美文网首页
3.静态链表

3.静态链表

作者: mr_young_ | 来源:发表于2017-04-09 17:17 被阅读17次
//
//  main.c
//  03-静态链表
//
//  Copyright © 2017年 Mr.Young. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>

#define OK      1
#define ERROR   0
#define TRUE    1
#define FALSE   0
#define OVERFLOW    0

#define MAXSIZE     100 //链表的最大长度

typedef int Status;
typedef int BOOL;
typedef int ElemType;

typedef struct {
    ElemType data;
    int cur;
}component, SLinkList[100];

/**
 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,“0”表示空指针
 */
void InitSpace_SL(SLinkList *space) {
    for (int i = 0; i < MAXSIZE-1 ; i++)
        (*space)[i].cur = i+1;
    (*space)[MAXSIZE-1].cur = 0;
    (*space)[MAXSIZE-2].cur = 0; // 备用链表最后一个元素置为空
}

/**
 若备用空间链表非空,则返回分配的结点下标,否则返回0
 */
int Malloc_SL(SLinkList *space) {
    int i = (*space)[0].cur;
    if ((*space)[0].cur) // 静态链表不为空
        (*space)[0].cur = (*space)[i].cur;
    return i;
}

/**
 将下标为k的空闲结点回收到备用链表
 */
void Free_SL(SLinkList *space, int k) {
    (*space)[k].cur = (*space)[0].cur;
    (*space)[0].cur = k;
}

/**
 销毁静态链表L,L不再存在
 */
Status DestroySLinkList(SLinkList *L) {
    int i = (*L)[MAXSIZE-1].cur; // 获取链表中第一个结点的下标
    while ((*L)[i].cur) {
        i = (*L)[i].cur;
    } // 循环得到最后一个结点的下标
    (*L)[i].cur = (*L)[0].cur;
    (*L)[0].cur = (*L)[MAXSIZE-1].cur;
    (*L)[MAXSIZE-1].cur = 0; // 将静态链表的头结点设为空
    return OK;
}

/**
 将值为s的结点插入在第一个结点之前
 */
Status InsFirst(SLinkList *L, int s) {
    int i = (*L)[MAXSIZE-1].cur; // 获取链表中第一个结点的下标
    int m = Malloc_SL(L); // 分配一个下标为m的新结点
    (*L)[MAXSIZE-1].cur = m;
    (*L)[m].cur = i;
    (*L)[m].data = s;
    return OK;
}

/**
 已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回
 */
Status DelFirst(SLinkList *L, ElemType *e) {
    int i = (*L)[MAXSIZE-1].cur; // 获取第一个结点的下标
    *e = (*L)[i].data;
    (*L)[MAXSIZE-1].cur = (*L)[i].cur;
    Free_SL(L, i);
    return OK;
}

/**
 删除静态链表L中的尾结点并以e返回
 */
Status Remove(SLinkList *L, ElemType *e) {
    int i = (*L)[MAXSIZE-1].cur; // 获取第一个结点的下标
    if (!(*L)[i].cur) { // 如果静态链表中只有一个结点
        (*L)[MAXSIZE-1].cur=(*L)[i].cur;
        Free_SL(L, i);
    }
    int j = (*L)[i].cur;
    while ((*L)[j].cur) {
        i = (*L)[i].cur;
        j = (*L)[i].cur;
    }
    *e = (*L)[j].data;
    Free_SL(L, j);
    (*L)[i].cur = 0;
    return OK;
}

/**
 若线性链表L为空表,则返回TRUE,否则返回FALSE
 */
BOOL ListEmpty(SLinkList L) {
    return L[MAXSIZE-1].cur==0;
}

/**
 返回线性链表L中元素的个数
 */
int ListLength(SLinkList L) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int len = 0;
    while (i) {
        len++;
        i = L[i].cur;
    }
    return len;
}

/**
 返回静态链表中位序为i的数据元素的值
 */
ElemType GetCurElem(SLinkList L, int k) {
    if (k<1 || k>ListLength(L)) {
        printf("访问的位置不合法!\n");
        exit(OVERFLOW);
    }
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j = 1;
    while (j!=k && i) {
        i = L[i].cur;
        j++;
    }
    return L[i].data;
}

/**
 返回静态链表中第一个与e相等的结点位序
 */
int LocatePos(SLinkList L, ElemType e) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j = 0;
    while (i) {
        ++j;
        if (L[i].data==e)
            return j;
        i=L[i].cur;
    }
    return 0;
}

/**
 已知cur_e为静态链表L中的一个结点的数据,并用pri_e保存该结点的直接前驱的数据,若无前驱,则返回ERROR
 */
Status PriorElem(SLinkList L, ElemType cur_e, ElemType *pri_e) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    if (L[i].data==cur_e) {
        printf("该结点没有前驱结点!\n");
        return ERROR;
    }
    int j;
    while (i) {
        j = L[i].cur; // j指向i的下一个结点
        if (j && L[j].data == cur_e) {
            *pri_e = L[i].data;
            return OK;
        }
        i = j;
    }
    return ERROR;
}

/**
 已知cur_e为静态链表L中的一个结点的数据,并用next_e保存该结点的直接后继的数据,若无前驱,则返回ERROR
 */
Status NextElem(SLinkList L, ElemType cur_e, ElemType *next_e) {
    int i = L[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j;
    while (i) {
        j = L[i].cur;
        if (j && L[i].data==cur_e) {
            *next_e = L[j].data;
            return OK;
        }
        i = j;
    }
    printf("该结点没有后继结点!\n");
    return ERROR;
}

/**
 在静态链表L中的第k个位置之前插入数据为e的结点
 */
Status ListInsert(SLinkList *L, int k, ElemType e) {
    if (k<1 || k>ListLength(*L)+1) {
        printf("插入的位置不合法!\n");
        return ERROR;
    }
    if (k==1) {
        InsFirst(L, e);
        return OK;
    }
    int i = (*L)[MAXSIZE-1].cur;
    int j = 1;
    while (i && j<k-1) {
        ++j;
        i = (*L)[i].cur;
    }
    int m = (*L)[i].cur; // m指向第k个结点
    int new = Malloc_SL(L); // 从静态表中找出一个空闲结点下标
    (*L)[new].cur = m;
    (*L)[new].data = e;
    (*L)[i].cur = new;
    return OK;
}

/**
 在静态链表L中,删除第k个结点,并用e保存第k个位置的值
 */
Status ListDelete(SLinkList *L, int k, ElemType *e) {
    if (k<1 || k>ListLength(*L)) {
        printf("删除的位置不合法!\n");
        return ERROR;
    }
    int i = (*L)[MAXSIZE-1].cur; // 获取第一个结点的下标
    int j = 1;
    while (i && j <k-1) { // 找到第k-1个结点位置
        j++;
        i = (*L)[i].cur;
    }
    int m = (*L)[i].cur; // 第k个结点的下标
    (*L)[i].cur = (*L)[m].cur;
    *e = (*L)[m].data;
    Free_SL(L, m);
    return OK;
}

/**
 遍历静态链表L
 */
void ListTraverse(SLinkList L) {
    int i = L[MAXSIZE-1].cur; // 获取静态链表第一个结点的下标
    int j = 0;
    while (i) {
        j++;
        printf("第%d个结点的值为:%d\n", j, L[i].data);
        i = L[i].cur;
    }
}

int main(int argc, const char * argv[]) {
    
    SLinkList *L = (SLinkList *)malloc(sizeof(SLinkList));
//    SLinkList *L = (SLinkList *)malloc(sizeof(component)*MAXSIZE);
    InitSpace_SL(L);
//    for (int i = 0; i < MAXSIZE; i++) {
//        printf("%d\n", (*L)[i].cur);
//    }
    printf("length = %d\n", ListLength(*L));
    InsFirst(L, 1);
    InsFirst(L, 2);
    InsFirst(L, 3);
    ListInsert(L, 1, 10);
    ListInsert(L, 5, 5);
    ListTraverse(*L);
    ElemType remove;
    Remove(L, &remove);
    printf("remove last is %d\n", remove);
    printf("length = %d\n", ListLength(*L));
    
    DestroySLinkList(L);
    free(L);
    return 0;
}

相关文章

  • 3.静态链表

  • 静态链表及C#实现

    静态链表 静态链表是用数组模拟动态链表。 静态链表结构描述 首先,静态链表使用数组来模拟动态链表。数组存放一个节点...

  • 线性表的静态链表

    静态链表定义 静态链表的增删

  • 链表处理

    1.创建链表 2.查找元素 3.插入元素 4.删除元素 5.静态链表 1074 Reversing Linked ...

  • 25_静态单链表的实现

    关键词: 单链表的一个缺点、静态单链表设计思路、静态单链表的继承层次结构、静态单链表的实现思路、静态单链表的实现 ...

  • C语言实现静态链表

    静态链表(单链表的一种形式) 有时,也可以借用一维数组来描述线性链表,我们称这种链表为静态链表。 静态链表需要实现...

  • 动态链表与静态链表

    动态链表与静态链表 1. 静态链表 静态链表概述 从他的意义上讲,静态链表像是对没有指针的语言缺陷而产生这么一个补...

  • 数据结构(静态链表的基础操作)

    静态链表的基础操作的前提是已经成功创建静态链表的基础上 静态链表中添加元素 加入将元素4添加到上静态链表中第3个位...

  • [数据结构]第二章线性表(6)——静态链表

    静态链表 什么是静态链表? 定义一个静态链表 方法1: 方法2: 验证方法2的定义方法 基本操作 总结反思 源码 ...

  • 静态链表——数据结构预习

    其实一般有单链表的话,应该用不着静态链表。然而并不是什么编程语言都有指针,这时静态链表可以起到单链表的作用。静态链...

网友评论

      本文标题:3.静态链表

      本文链接:https://www.haomeiwen.com/subject/wigdattx.html