数据结构 静态链表

数据结构 严蔚敏版本 P31 的静态链表 用一位数组来实现链表

通过数组来实现链表的时候,需要自己定义Malloc和Free函数;

静态链表的结构

1 #define MAXSIZE 10
2 typedef struct {
3     int val;
4     int cur;
5 }SLinkList[MAXSIZE];

对一个链表进行一下的初始化

1 void InitSpace_SL(SLinkList &space){
2     for(int i=0; i<MAXSIZE-1; ++i) space[i].cur=i+1;
3     space[MAXSIZE-1].cur=0;
4 }

 

为了辨明数组中哪些空间没有被使用,解决的办法是把所有的没有被使用过的空间组成一个备用链表,这个链表的头部是space[0], 储存数据的链表的头部是space[1];

也就是说一个数组被分为两部分,一部分表示没有使用的空间,一部分表示已经使用的空间

0 1 2 3 4 5 6 7 8 9
5 3 9 4 7 6 2 8 0 0

 

 

 

像上面表格中所示,5->6->2->9这个链表中的空间未被使用; 3->4->7->8这个链表的空间已经被使用

每次要插入新数的时候,就申请一个空间,space[0]指向的始终是为使用的空间,申请空间的时候,函数返回未被使用的空间的地址,当返回-1的时候,表示空间已经用完了,不能再添加

1 int Malloc_SL(SLinkList &space){
2     int i=space[0].cur;
3     if(i!=0) space[0].cur = space[i].cur;
4     else i=-1;
5     return i;
6 }

 

当释放空间的时候, 把需要释放空间的地址加入到未使用地址的链表中即可

1 void Free_SL(SLinkList& space, int k){
2     space[k].cur = space[0].cur;
3     space[0].cur = k;
4 }

当删除一个结点的时候,应该:

space[p].cur = space[k].cur; //p是要删除结点的前驱,和链表对比一下就能理解这个操作
 Free_SL(space, k);

 

完整的程序,实现集合A-B的差集

 1 #include<iostream>
 2 using namespace std;
 3 
 4 #define MAXSIZE 10
 5 typedef struct {
 6     int val;
 7     int cur;
 8 }SLinkList[MAXSIZE];
 9 
10 void InitSpace_SL(SLinkList &space){
11     for(int i=0; i<MAXSIZE-1; ++i) space[i].cur=i+1;
12     space[MAXSIZE-1].cur=0;
13 }
14 
15 int Malloc_SL(SLinkList &space){
16     int i=space[0].cur;
17     if(i!=0) space[0].cur = space[i].cur;
18     else i=-1;
19     return i;
20 }
21 
22 void Free_SL(SLinkList& space, int k){
23     space[k].cur = space[0].cur;
24     space[0].cur = k;
25 }
26 
27 void difference(SLinkList &space, int &S){
28     InitSpace_SL(space);
29     S = Malloc_SL(space);
30     int r = S; //r用来记录数据链表中的最后一个数据所在位置
31     int m, n;
32     cout<<"please input m, n:";
33     cin>>m>>n;
34     for(int j=1; j<=m; ++j){
35        int i = Malloc_SL(space);
36         cout<<"please input val: ";
37         cin>>space[i].val;
38         space[r].cur = i; //把新的数据添加到链表中
39         //printf("i=%d space[%d].val=%d space[%d].cur=%d", i, i, space[i].val, r, i);
40         r = i; //更新最后一个数据的位置
41     //cout<<"r="<<r<<endl;
42     }
43     space[r].cur=0; //表示r为数据链表中最后一个数据
44     for(int j1=1; j1<=n; ++j1){
45         int b;
46         cout<<"please input b: ";
47         cin>>b;
48         int p = S, k = space[S].cur;
49         space[S].val=-1;//判断b是否在数据链表中
50         while(k!=space[r].cur && space[k].val!=b){
51             p = k;
52             k = space[k].cur;
53         }
54     //printf("p=%d k=%d\n", k, space[k].cur);
55         if(k==space[r].cur){//若不在数据链表中,就添加到数据链表中
56             int i = Malloc_SL(space);
57             if(i==-1){
58                 cout<<"There is no enough space!"<<endl;
59             }else{
60             space[i].val = b;
61             space[r].cur = i;
62             r=i;}
63             //space[i].cur = space[r].cur;
64             //printf("i=%d space[%d].val=%d, space[%d].cur=%d space[%d].cur=%d\n", i, i, b, i, space[r].cur, r, i);
65         }else{//若在链表中,就删除该数据, 其实数据依然保存在数组中,只是通过cur不能访问该位置的数据,即把该位置从数据链表中删除
66             space[p].cur = space[k].cur;
67             Free_SL(space, k);
68             if(r==k) r==p;//删除数据链表的尾部的时候,需要更新尾部
69             if(space[S].cur==0) space[S].cur = space[0].cur;//当数据链表中的值全部被删除后,需要改变数据链表的头部,否知会出错,自己可以试试,分析一下
70             //printf("space[0].cur =%d space[space[0].cur].cur=%d\n", space[0].cur, space[space[0].cur].cur);
71         }
72     }
73     space[r].cur=0;
74 }
75 int main(){
76     SLinkList space;
77     int s;
78     difference(space, s);
79     while(space[s].cur){
80         s=space[s].cur;
81         cout<<space[s].val<<" ";
82     }
83     cout<<endl;
84 return 0;}

 

posted @ 2018-05-14 23:11  赖兴宇  阅读(398)  评论(0编辑  收藏  举报