chunlanse2014

导航

2.3线性表的链式存储和运算—静态链表

下面先请看图2.22 ,在图2.22中,规模较大的结构数组sd[MAXSIZE] 中有两个链表:

其中链表SL是一个带头结点的单链表,表示了线性表(a1, a2, a3, a4, a5),而另一个单链表AV是将当前sd 中的空结点组成的链表。

数组sd的定义如下:

1 #define MAXSIZE … /*足够大的数*/
2 typedef struct
3 {
4     datatype data;
5     int next;
6 }SNode; /*结点类型*/
7 SNode sd[MAXSIZE];
8 int SL,AV; /*两个头指针变量*/

这种链表的结点中也有数据域data和指针域next,与前面所讲的链表中的指针不同的是,这里的指针是结点的相对地址(数组的下标),称之为静态指针,这种链表称之为静态链表,空指针用-1表示,因为上面定义的数组中没有下标为-1的单元。

在图2.22中,SL是用户的线性表,AV模拟的是系统存储池中空闲结点组成的链表,当用户需要结点时,例如向线性表中插入一个元素,需自己向AV申请,而不能用系统函数malloc来申请,相关的语句为:

1 if(AV!=-1)
2 { 
3     t=AV;
4     AV=sd[AV].next;
5 }

所得到的结点地址(下标)存入了t中;不难看出当AV表非空时,摘下了第一个结点给用户。当用户不再需要某个结点时,需通过该结点的相对地址t将它还给AV,相关语句为: 

1 sd[t].next=AV;
2 AV=t;

 

而不能调用系统的free 函数。交给AV表的结点链在了AV的头部。

下面通过线性表插入这个例子看静态链表操作。

例2.4 在带头结点的静态链表SL的第i个结点之前插入一个值为x的新结点。设静态链表的存储区域sd为全局变量。

 1 int Insert_SList( int SL, datatype x, int i)
 2 { 
 3     int p,s;
 4     p=SL; 
 5     j=0;
 6     while(sd[p].next!=-1 && j<i-1)     /*找第i-1个结点*/
 7     {
 8         p=sd[p].next;        
 9         j++;
10     } 
11     if(j==i-1)
12     { 
13         if(AV!=-1)       /*若AV表还有结点可用*/
14         {
15             t=AV;
16             AV=sd[AV].next; /*申请、填装新结点*/
17             sd[t].data=x;
18             sd[t].next=sd[p].next; /*插入*/
19             sd[p].next=t;
20             return 1;   /*正常插入成功返回*/
21         }
22         else             /*未申请到结点,插入失败*/
23         {
24             printf("存储池无结点");
25             return 0;
26         }
27     }    
28     else                 /*插入位置不正确,插入失败*/
29     {
30         printf("插入的位置错误");
31         return -1;
32     }  
33 }

算法2.14

读者可将该算法和算法2.12相比较,除了一些描述方法有些区别外,算法思路是相同的。有关基于静态链表上的其它线性表的操作基本与动态链表相同,这里不再赘述。

posted on 2015-04-19 12:03  chunlanse2014  阅读(379)  评论(0编辑  收藏  举报