数据结构之静态链表
静态链表:静态链表就是长度大小固定的,链式存储的线性表。
静态链表的定义
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 }