数据结构之静态链表

静态链表:静态链表就是长度大小固定的,链式存储的线性表。

 

静态链表的定义

 1 //结点结构体的定义
 2 typedef struct _tag_StaticListNode
 3 {
 4     unsigned int data;  //结点数据
 5     int next;               
 6 }TStaticListNode;
 7 
 8 
 9 //静态链表结构体的定义
10 typedef struct _tag_StaticList
11 {
12     int capacity;    //容量
13     TStaticListNode header;  //指向表头
14     TStaticListNode node[];  //柔性数组
15 }TStaticList;

 

静态链表的操作

StaticList.c

  1 /**************************************************************************************************************  
  2 文件名:StaticList.c 
  3 头文件:StaticList.h 
  4 功能:实现静态链表的操作
  5 **************************************************************************************************************/  
  6 #include <stdio.h>  
  7 #include <malloc.h>  
  8 #include <string.h>  
  9 #include "StaticList.h"  
 10   
 11 #define AVAILABLE -1  
 12   
 13 typedef struct _tag_StaticListNode  //这个是静态链表的结构   用来保存链表元素的   
 14 {  
 15     unsigned int data;   //这个是为了复用保存数据地址的   
 16     int next;            //这个是用来保存下一个节点位置的   
 17 }StaticListNode;           
 18   
 19 typedef struct _tag_StaticList  //因为静态链表是基于顺序表改写的  这个就是顺序表中描述顺序表的那个结构   
 20 {  
 21     int capacity;           //静态链表的大小是固定的  这是链表的容量   
 22     StaticListNode head;    //链表  头节点    
 23     StaticListNode node[];  //利用柔性数组 创建静态链表   
 24 }StaticList;  
 25   
 26 /**************************************************************************************************************  
 27 函数名 : Creat_StaticList 
 28 函数功能:创建一个静态链表使用的空间 
 29 具体数据: StaticList这个结构是描述静态链表的结构    StaticListNode这个结构才是真正的静态链表的元素 
 30            每一个静态链表的元素都是由两个部分组成的 一个是数据data(即保存的地址)  另一个是下一个链表 
 31            元素的位置next     
 32            对于StaticList这个结构中的数据是capacity是静态链表的容量 head是链表的头节点 
 33            node[0]也是头节点 node[]是柔性数据  这里面保存的才是真的链表内容  
 34 参数: int capacity  链表容量  正确范围 0到无穷大  当为0的时候链表中仅仅有一个node[0]头节点  
 35 返回值:StaticList* ret 返回描述静态链表的结构 StaticList的地址   (SList*这个是为了封装) 
 36 **************************************************************************************************************/   
 37 SList* Creat_StaticList(int capacity)  
 38 {  
 39     int i=0;   
 40     StaticList* ret = NULL;   
 41     if( capacity >= 0) //参数合法性检测  一定要大于等于0   如果capacity为0 是给node[0]开辟空间  node[0]是链表头节点   
 42     {  
 43         ret = (StaticList*)malloc( sizeof(StaticList)*1 + sizeof(StaticListNode)*(capacity+1) );  
 44     }  
 45     if(NULL != ret)  //判断malloc是否成功 内存是否分配成功   
 46     {  
 47         ret -> capacity = capacity; //静态链表的容量   
 48         ret -> head.data = 0;   //头节点中保存的 链表长度   初始化为0   
 49         ret -> head.next = 0;   //头节点中保存的  链表下一个节点的位置  初始化为NULL  
 50         for(i=1; i<=capacity; i++)  //把链表中从node[1]开始 到node[capacity]中的next都标志为可用   
 51         {  
 52             ret -> node[i].next =  AVAILABLE; //这个在插入函数的时候有用   
 53         }   
 54           
 55     }  
 56     return (SList*)ret;  
 57        
 58 }   
 59   
 60 /**************************************************************************************************************  
 61 函数名:Destroy_StaticList 
 62 函数功能:释放StaticList结构开辟的内存  
 63 参数:StaticList* Static_List  (SList* Static_List这个是为了 封装) 
 64 返回值:void  
 65 **************************************************************************************************************/   
 66 void Destroy_StaticList(SList* Static_List)  
 67 {  
 68     free(Static_List); //释放静态链表创建的内存空间   
 69 }  
 70   
 71 /************************************************************************************************************** 
 72 函数名: Get_Lenth 
 73 函数功能:返回静态链表长度 
 74 参数:StaticList* Static_List    (SList* List为了封装) 
 75 返回值:成功 int Static_List -> head.data 静态链表使用的长度   失败返回 0  
 76 **************************************************************************************************************/  
 77 int Get_Lenth(SList* List)   
 78 {  
 79     StaticList* Static_List = (StaticList*)List;  
 80     int ret = 0;  
 81     if(NULL != Static_List)  
 82     {  
 83         ret = Static_List -> head.data; //静态链表的长度   
 84     }  
 85     return ret;  
 86 }  
 87   
 88 /************************************************************************************************************** 
 89 函数名:Get_Capacity 
 90 函数功能:返回静态链表的容量 
 91 参数:StaticList* Static_List  (SList* List为了封装) 
 92 返回值:成功返回 int Static_List -> capacity 静态链表的容量  失败返回 0  
 93 **************************************************************************************************************/  
 94 int Get_Capacity(SList* List)   
 95 {  
 96     StaticList* Static_List = (StaticList*)List;  
 97     int ret = 0;  
 98     if(NULL != Static_List)  
 99     {  
100         ret = Static_List -> capacity; //静态链表的容量   
101     }  
102     return ret;  
103 }  
104   
105 /************************************************************************************************************** 
106 函数名: Clear_StaticList 
107 函数功能:重置静态链表 
108 参数:StaticList* Static_List  (SList* List为了封装) 
109 返回值:成功返回1  失败返回0  
110 **************************************************************************************************************/  
111 int Clear_StaticList(SList* List)  
112 {  
113     StaticList* Static_List = (StaticList*)List;  
114     int i = 0;  
115     int ret = 0;  
116     if(NULL != Static_List)  
117     {  
118         Static_List -> head.data = 0;  
119         Static_List -> head.next = 0;  
120         for(i=1; i<=Static_List -> capacity; i++)    
121         {  
122             Static_List -> node[i].next =  AVAILABLE;    
123         }   
124         ret = 1;  
125     }   
126     return ret;  
127 }  
128   
129 /************************************************************************************************************** 
130 函数名: Add_StaticList 
131 函数功能: 在链表中的pos位置处插入一个链表元素   pos的规则跟上节单链表的规则一样 0和1为头插法  无穷大为尾插法 
132            node[0]是链表头节点  其实是head的一个中间变量  使用node[0]真的很方便 此处记得更新头节点 
133 参数:SList* List 要插入的链表地址    SListNode* Node要插入的数据地址   int pos插入的位置  
134 返回值:返回1说明插入成功  返回0说明插入失败  
135 **************************************************************************************************************/  
136 int Add_StaticList(SList* List, SListNode* Node, int pos)  
137 {  
138     StaticList* Static_List = (StaticList*)List;  139     StaticListNode*  node =  (StaticListNode*)Node;  
140     int ret = 0;  
141     int num = 0;  
142     int index = 0;  
143     int i = 0;  
144     ret = (NULL != Static_List)&&(NULL != node);  
145     ret = ret&&(Static_List->head.data+1 <= Static_List->capacity)&&(pos >= 0);   
146       
147     if(ret)  //参数合法性检测成功   
148     {  
149         for(i=1; i<=Static_List->capacity; i++) //轮询获得可用的位置index   
150         {  
151             if(-1 == Static_List->node[i].next)  
152             {  
153                 index = i;  
154                 break;  
155             }  
156         }  
157         Static_List->node[index].data = (unsigned int)node; //保存链表中的数据   
158         Static_List->node[0] = Static_List->head;  //此时node[0]变成了链表头节点   
159   
160         for(i=1; (i < pos)&&(0 != Static_List->node[num].next); i++)  
161         {  
162             num =  Static_List->node[num].next;  
163         }  
164         Static_List->node[index].next = Static_List->node[num].next;  
165         Static_List->node[num].next = index;  
166           
167         Static_List->node[0].data++;  
168         Static_List->head = Static_List->node[0];//更新链表头节点   
169     }  
170     return ret;   
171 }   
172   
173   
174 /************************************************************************************************************** 
175 函数名: Get_StaticListNode 
176 函数功能:获得pos位置处的数据  pos的规则跟单向链表一样 
177           范围是 0  到   head->data  0是头节点 
178 参数:  SList* List 要插入的链表地址     int pos插入的位置  
179 返回值: 成功返回pos位置处的数据  失败返回NULL  
180 **************************************************************************************************************/  
181 SListNode* Get_StaticListNode(SList* List, int pos)  
182 {  
183     SListNode* ret = NULL;  
184     int i = 0;  
185     int num = 0;  
186     StaticList* Static_List = (StaticList*)List;   
187     if( (NULL != Static_List) && (pos <= Static_List->head.data) && (pos >= 0) )  
188     {  
189         Static_List->node[0] = Static_List->head;   
190         for(i=0; i<pos; i++)  
191         {  
192             num = Static_List->node[num].next;  
193         }  
194         ret = (SListNode*)Static_List->node[num].data;   
195     }  
196     return ret;  
197 }   
198   
199   
200 /************************************************************************************************************** 
201 函数名: Del_StaticListNode 
202 函数功能:删除pos位置处的数据  pos的规则跟单向链表一样 
203           范围是 1  到   head->data  0是头节点 不能删除 
204 参数: SList* List 要插入的链表地址     int pos删除的位置 
205 返回值:成功返回 pos位置的数据 (目的在于:因为此数据一般是数据的地址  便于释放内存)    失败返回NULL  
206 **************************************************************************************************************/  
207 SListNode* Del_StaticListNode(SList* List, int pos)  
208 {  
209     SListNode* ret = NULL;  
210     int i = 0;  
211     int num = 0;  
212     int temp = 0;   
213     StaticList* Static_List = (StaticList*)List;   
214     if( (NULL != Static_List) && (pos <= Static_List->head.data) && (pos > 0) )  
215     {  
216         Static_List->node[0] = Static_List->head;   
217         for(i=1; i<pos; i++)//得找到要删除的那个节点的上一个   
218         {  
219             num = Static_List->node[num].next;  
220         }  
221         temp = Static_List->node[num].next;  
222         Static_List->node[num].next = Static_List->node[temp].next;  
223           
224         Static_List->node[0].data--;  
225         Static_List->head = Static_List->node[0]; //更新链表头节点   
226           
227         Static_List->node[temp].next = AVAILABLE; //把删除的节点标志为可用节点   
228           
229         ret = (SListNode*)Static_List->node[temp].data;    
230     }  
231     return ret;  
232       
233 }

 

StaticList.h

 1 #ifndef __STATICLIST_H__  
 2 #define __STATICLIST_H__   
 3   
 4 typedef void SList;  
 5 typedef void SListNode;  
 6   
 7 SList* Creat_StaticList(int capacity);  
 8 void Destroy_StaticList(SList* Static_List);  
 9 int Get_Lenth(SList* List);  
10 int Get_Capacity(SList* List);  
11 int Clear_StaticList(SList* List);  
12 int Add_StaticList(SList* List, SListNode* Node, int pos);  
13 SListNode* Get_StaticListNode(SList* List, int pos);  
14 SListNode* Del_StaticListNode(SList* List, int pos);  
15   
16 #endif 

 

main.c

 1 #include <stdio.h>  
 2 #include <malloc.h>  
 3 #include <string.h>  
 4 #include "StaticList.h"  
 5   
 6 int main()  
 7 {  
 8     SList* list = Creat_StaticList(10);  
 9     int *f = 0;  
10     int i = 0;  
11     int a = 1;  
12     int b = 2;  
13     int c = 3;  
14     int d = 4;  
15     int e = 5;  
16       
17     Add_StaticList(list, &a, 0);  
18     Add_StaticList(list, &b, 0);  
19     Add_StaticList(list, &c, 0);  
20     Add_StaticList(list, &d, 0);  
21       
22     for(i=1; i<=Get_Lenth(list); i++)  
23     {  
24         f=(int* )Get_StaticListNode(list, i);  
25         printf("%d\n",*f);  
26     }  
27        
28     Add_StaticList(list, &e, 2);  
29     printf("\n");  
30     for(i=1; i<=Get_Lenth(list); i++)  
31     {  
32         f=(int* )Get_StaticListNode(list, i);  
33         printf("%d\n",*f);  
34     }   
35       
36     printf("\n");  
37     f=(int* )Del_StaticListNode(list, 4);  
38     printf("del %d\n",*f);  
39     printf("\n");  
40     for(i=1; i<=Get_Lenth(list); i++)  
41     {  
42         f=(int* )Get_StaticListNode(list, i);  
43         printf("%d\n",*f);  
44     }   
45     Destroy_StaticList(list);  
46     return 0;  
47 }  

 

posted @ 2019-06-11 20:15  千小塔  阅读(574)  评论(0编辑  收藏  举报