/** 静态链表相关操作 借助一维数组来描述线性链表 **/ /** 1、为操作方便,特为申请到的空间段设一“头结点”; 2、模拟系统动态申请空间过程; 3、 i=S[i].cur同p=p->next,表示指针后移 ; **/ #ifndef STATIC_LINKED_LIST #define STATIC_LINKED_LIST #define MAXSIZE 16 typedef int LElemType_S; /* 线性表的静态单链表存储结构 */ typedef struct { LElemType_S data; int cur; } component,SLinkList[MAXSIZE]; /* SLinkList类型为数组,成员类型为结构体 */ /* 3) 为数组定义简洁的类型名称 它的定义方法很简单,与为基本数据类型定义新的别名方法一样,示例代码如下所示: 纯文本复制 typedef int INT_ARRAY_100[100]; INT_ARRAY_100 arr; */ /* 静态链表空间 */ /* 可用空间,书中称为备用空间、备用链表, 静态链表从可用空间获取空间,存放删除的结点 */ /* 类似于通常而言的“内存空间” */ SLinkList space; /* 全局变量 */ void InitSpace_SL() { /* 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针 "0"表示空指针 */ int i; for(i=0; i<MAXSIZE-1; i++) { space[i].cur=i+1; printf("%d,space\n",i); } space[MAXSIZE-1].cur=0; } /* 用户实现malloc和free2个函数 为了辨明数组中哪些分量未被使用,解决办法是将所有未被使用过以及被删除的分量用游标链成一个备用链表 每当进行插入时便可从备用链表上取得第一个结点作为待插入的新结点 反之,在删除时将从链表中删除下来的结点链接到备用链表上 */ int Malloc_SL() { /* 若备用空间链表非空,则返回分配的结点的下标,否则返回0 */ int i=space[0].cur; /* 备用空间链表也是一个静态链表,i表示头指针指向的位置 */ if(space[0].cur) space[0].cur=space[i].cur; /* 头指针下移 */ printf("%d,Malloc_SL\n",i); return i; } /* 假设S为SLinkList型变量,S[0].cur指示第一个结点在数组中的位置, 若设i=S[0].cur,则S[i].data存储线性表的第一个数据元素, 且S[i].cur指示第二个结点在数组中的位置。 */ // 将下标为k的空闲结点回收到备用链表 void Free_SL(int k) { space[k].cur=space[0].cur; space[0].cur=k; } /* 对数组arr的arr[0].data不赋值 */ Status ListInsert_SL(SLinkList s,int i,LElemType_S e) { /* 在静态链表S的第i(i>=0)个位置,插入结点,结点data为e; 当i为0时,认为结点e.data不存在;当i=MAXSIZE时,认为结点指向e.cur为0; */ int p; if(i>0) { p=Malloc_SL(); s[i].cur=s[i-1].cur; s[i-1].cur=p; s[i].data=e; } return ERROR; } Status ListTraverse_SL(SLinkList s,void(Visit)(component)) { int p; int i=0; for(i=0; i<=MAXSIZE-1; i++) { Visit(s[i]); } printf("\n--->\n"); Visit(s[0]); p=s[0].cur; while(p) { Visit(s[p]); p=s[p].cur; } printf("\n彩蛋-C语言变量作用域\n"); Visit(s[p]); return OK; } /* 测试函数,打印整型 */ void StaticLinkedList_PrintElem(component e) { printf("e.data=%d,e.cur=%d,&e=%d\n",e.data,e.cur,&e); } void StaticLinkedList() { SLinkList s; /* 注意s为数组,按引用传入函数 */ LElemType_S e; int i; InitSpace_SL(); for(i=0; i<MAXSIZE; i++) { e=100+i; ListInsert_SL(s,i,e); } ListTraverse_SL(s,StaticLinkedList_PrintElem); } #endif