静态链表-C语言实现


1.静态链表是在没有指针的编程语言里对链表的一种实现
2.主要是用数组模拟指针
3.在这里,使用结构体使数组的每一个空间可以存储一个数据元素(date)和一个游标(cur),游标的作用相当于链表的指针域,用于记录下一元素的下标是多少
4.在没有结构体(typedef)的语言中,也可以使用两个并行数组实现此功能

此种结构在编程中不一定能用得到,但是这种思想非常巧妙,非常值得我们学习,不多说,直接上代码,亲测可行,有详细注释

#include<stdio.h>

#define MAXSIZE 1000                //静态链表最大空间容量 typedef int ElemType;                //数据类型
typedef int Status;                    //返回值类型
#define OK 1                        //操作成功返回值
#define ERROR 0                        //操作失败返回值 typedef struct                        //静态链表的结构体
{ ElemType date; //结点数据
    int cur;                        //结点游标(相当于链表中的地址)
}StaticLinkList[MAXSIZE];            //表名

/* 静态链表的初始化 第一个位置space[0]的cur指向第一个没有数据的位置空间 最后一个位置space[MAXSIZE-1]的cur指向第一个有数据的位置空间,即头结点 */ Status InitList(StaticLinkList space) { for(int i = 0; i < MAXSIZE-1; i++)            //为数组中的每个位置的游标赋值
        space[i].cur = i + 1; space[MAXSIZE-1].cur = 0;                    //使最后一个位置的游标为0
    return OK; } /* 模拟链表中的malloc函数,在数组中寻找空闲位置空间作为新结点 */
int malloc_SLL(StaticLinkList space) { int i = space[0].cur;                        //将备用链表的第一个结点位置赋值给i
    if(space[0].cur)                            //如果space[0].cur不是0,即备用链表非空
        space[0].cur = space[i].cur;                //将备用链表的下一个空闲位置赋值给space[0]
    return i; } /*获得链表的长度*/
int ListLength(StaticLinkList L) { int i, l; l = 0;                    //记录链表长度
    i = MAXSIZE - 1;        //获得头结点下标
    i = L[i].cur;            //获得头结点位置
    while(i)                //如果此下标 != 0
 { l++;                //长度加1
        i = L[i].cur;        //下标后移
 } return l;                //返回长度l
} /* 静态链表的插入操作 */ Status InsertLinkList(StaticLinkList L, int i, ElemType e) { int j ,k, l; k = MAXSIZE-1;                            //获取头结点的下标
    if(i < 1 || i > ListLength(L)+1)        //判断要插入的位置是否合理
        return ERROR; j = malloc_SLL(L);                        //获得备用链表中的第一个位置下标
    if(j)                                    //如果此下标不是0,说明还有空间可用
 { L[j].date = e;                        //将此下标对应位置的数据域赋值为e
        for(l = 1; l < i; l++)                //遍历链表,寻找i位置之前的结点
            k = L[k].cur;                    //获得此结点的游标
        L[j].cur = L[k].cur;                //新结点的游标等于i-1位置的游标
        L[k].cur = j;                        //i-1位置的游标等于新结点的游标
        return OK;                            //操作成功
 } return ERROR;                            //操作失败
} /*模拟free()函数,将删除的结点空间加入备用空间*/
void free_SSL(StaticLinkList space, int i) { space[i].cur = space[0].cur;                    //删除位置的游标等于0位置的游标
    space[0].cur = i;                                //0位置的游标等于当前结点
} /*静态链表的删除操作*/ Status DelLinkList(StaticLinkList L, int i) { int j, k; if(i < 1 || i > ListLength(L)+1)                //判断删除的位置是否合理
        return ERROR; k = MAXSIZE - 1;                                //获得头结点的游标
    for(j = 1; j < i; j++)                            //寻找i位置
        k = L[k].cur;                                //游标后移
    j = L[k].cur;                                    //将要删除的位置下标赋值给j
    L[k].cur = L[j].cur;                            //使删除结点的前一结点的游标指向删除结点的游标
    free_SSL(L, j);                                    //释放删除的结点
    return OK; } /*静态链表的遍历操作*/
void PrintLinkList(StaticLinkList L) { int i; int j = MAXSIZE - 1;                        //获得数组最后一个位置的下标
    j = L[j].cur;                                //获得此下标的游标值,即头结点的下标 // printf("长度为%d\n",ListLength(L));
    for(i = 1; i <= ListLength(L); i++)            //遍历此表
 { printf("第%d个结点的数据是:%d\n", i, L[j].date);                //输出每个结点的数据
        j = L[j].cur;                            //获得下一结点的游标
 } } void main() { StaticLinkList L; //创建链表L
    int i, e;            //i为元素位置,e为元素内容

    while(true) { printf("请选择对静态链表的操作:\n"); printf("1.初始化\n"); printf("2.插入\n"); printf("3.删除\n"); printf("4.输出\n"); printf("5.退出\n"); int a; scanf("%d", &a); switch(a) { case 1: if(InitList(L)) printf("初始化成功\n"); else printf("初始化失败\n"); break; case 2: printf("请输入需要插入的位置:"); scanf("%d", &i); printf("请输入需要插入的元素:"); scanf("%d", &e); if(InsertLinkList(L, i, e)) printf("插入成功\n"); else printf("插入失败\n"); break; case 3: printf("请输入需要删除的位置:"); scanf("%d", &i); if(DelLinkList(L, i)) printf("删除成功\n"); else printf("删除失败\n"); break; case 4: PrintLinkList(L); break; case 5: return; default: printf("选择错误\n"); break; } } }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM