静态链表

来源:互联网 发布:服装设计的网络课程 编辑:程序博客网 时间:2024/04/30 01:21

静态数组实际有2个链表,一个链表上链接的是线性表的结点,另一个链表把所有空闲结点链接形成一个备用链表,数组下标为0的单元为备用链表的头结点。cur值为0的结点为线性表的尾结点。

 

代码:

[cpp] view plaincopy
  1. #include <string.h>     
  2. #include <ctype.h>     
  3. #include <malloc.h>  // malloc()等     
  4. #include <limits.h>  // INT_MAX等     
  5. #include <stdio.h>   // EOF(=^Z或F6),NULL     
  6. #include <stdlib.h>  // atoi()     
  7. #include <io.h>      // eof()     
  8. #include <math.h>    // floor(),ceil(),abs()     
  9. #include <process.h> // exit()     
  10.   
  11. // 函数结果状态代码     
  12. #define TRUE  1     
  13. #define FALSE 0     
  14. #define OK    1     
  15. #define ERROR 0     
  16. #define INFEASIBLE -1     
  17. // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行     
  18. typedef int Status;  // Status是函数的类型,其值是函数结果状态代码,如OK等     
  19. typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE   
  20.   
  21. typedef int ElemType;  
  22.   
  23. // 线性表的静态单链表存储结构  
  24. #define MAX_SIZE 100 // 链表的最大长度  
  25. typedef struct  
  26. {  
  27.     ElemType data;  
  28.     int cur;  
  29. }component, SLinkList[MAX_SIZE];  
  30.   
  31. int Malloc(SLinkList space)   
  32. // 若备用链表非空,则返回分配的结点下标(备用链表的第一个结点),否则返回0  
  33.     int i = space[0].cur;  
  34.     if (i)  
  35.         space[0].cur = space[i].cur;  
  36.     return i;  
  37. }  
  38.   
  39. void Free(SLinkList space, int k)   
  40. // 将下标为空的空闲结点回收到备用链表(成为备用链表的第一个结点)  
  41.     space[k].cur = space[0].cur;  
  42.     space[0].cur = k;  
  43. }  
  44.   
  45. // 一个数组只生成一个静态链表的基本操作(11个))  
  46. #define DestroyList ClearList // DestroyList()和ClearList()的操作是一样的  
  47. void InitList(SLinkList L)  
  48. // 构造一个空的链表L,表头为L的最后一个单元L[MAX_SIZE-1],其余单元链成  
  49.     // 一个备用链表,表头为L的第一个单元L[0],“0”表示空指针  
  50.     int i;  
  51.     L[MAX_SIZE - 1].cur = 0;  
  52.     for (i = 0; i < MAX_SIZE - 2; i++)  
  53.         L[i].cur = i + 1;  
  54.     L[MAX_SIZE - 2].cur = 0;      
  55. }  
  56.   
  57. void ClearList(SLinkList L)  
  58. // 初始条件:线性表L已存在。操作结果:将L重置为空表  
  59.     int i, j, k;  
  60.     i = L[MAX_SIZE - 1].cur;  
  61.     L[MAX_SIZE - 1].cur = 0;  
  62.     k = L[0].cur;  
  63.     L[0].cur = i;  
  64.     while (i)  
  65.     {  
  66.         j = i;  
  67.         i = L[i].cur;  
  68.     }  
  69.     L[j].cur = k;  
  70. }  
  71.   
  72. Status ListEmpty(SLinkList L)  
  73. // 若L是空表,返回TRUE;否则返回FALSE  
  74.     if (!L[MAX_SIZE - 1].cur)  
  75.         return TRUE;  
  76.     else  
  77.         return FALSE;  
  78. }  
  79.   
  80. int ListLength(SLinkList L)  
  81. // 返回L中数据元素个数  
  82.     int i, length;  
  83.     i = L[MAX_SIZE - 1].cur;  
  84.     length = 0;  
  85.     while (i)  
  86.     {  
  87.         i = L[i].cur;  
  88.         length++;  
  89.     }  
  90.     return length;  
  91. }  
  92.   
  93. Status GetElem(SLinkList L, int i, ElemType &e)  
  94. // 用e返回L中第i个元素的值  
  95.     int j, k = MAX_SIZE - 1;  
  96.     if (i < 1 || i > ListLength(L))  
  97.         return ERROR;  
  98.     for (j = 1; j <= i; j++)  
  99.         k = L[k].cur;  
  100.     e = L[k].data;  
  101.     return OK;  
  102. }  
  103.   
  104. int LocateElem(SLinkList L, ElemType e)   
  105. // 在静态单链线性表L中查找第1个值为e的元素。若找到,则返回它在L中的  
  106.     // 位序,否则返回0。(与其它LocateElem()的定义不同)  
  107.     int i = L[MAX_SIZE - 1].cur;  
  108.     while (i && L[i].data != e)  
  109.         i = L[i].cur;  
  110.     return i;  
  111. }  
  112.   
  113. Status PriorElem(SLinkList L, ElemType cur_e, ElemType &pre_e)  
  114. // 初始条件:线性表L已存在  
  115.     // 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,  
  116.     //           否则操作失败,pre_e无定义  
  117.     int i, j;  
  118.     i = L[MAX_SIZE - 1].cur;      
  119.     do   
  120.     {  
  121.         j = i;  
  122.         i = L[i].cur;  
  123.     } while (i && L[i].data != cur_e);  
  124.     if (i)  
  125.     {  
  126.         pre_e = L[j].data;  
  127.         return OK;  
  128.     }  
  129.     return ERROR;  
  130. }  
  131.   
  132. Status NextElem(SLinkList L, ElemType cur_e, ElemType &next_e)  
  133. // 初始条件:线性表L已存在  
  134.     // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,  
  135.     //           否则操作失败,next_e无定义  
  136.     int i, j;  
  137.     i = LocateElem(L, cur_e);  
  138.     if (i)  
  139.     {  
  140.         j = L[i].cur;  
  141.         if (j)  
  142.         {  
  143.             next_e = L[j].data;  
  144.             return OK;  
  145.         }  
  146.     }  
  147.     return ERROR;  
  148. }  
  149.   
  150. Status ListInsert(SLinkList L, int i, ElemType e)  
  151. // 在L中第i个元素之前插入新的数据元素e  
  152.     int j, k, l;  
  153.     k = MAX_SIZE - 1;  
  154.     if (i < 1 || i > ListLength(L) + 1)  
  155.         return ERROR;  
  156.     j = Malloc(L);  
  157.     if (j)  
  158.     {  
  159.         L[j].data = e;  
  160.         for(l = 1; l <= i - 1; l++)  
  161.             k = L[k].cur;  
  162.         L[j].cur = L[k].cur;  
  163.         L[k].cur = j;  
  164.         return OK;  
  165.     }  
  166.     return ERROR;  
  167. }  
  168.   
  169. Status ListDelete(SLinkList L, int i, ElemType &e)  
  170. // 删除在L中第i个数据元素e,并返回其值  
  171.     int j, k;  
  172.     if (i < 1 || i > ListLength(L))  
  173.         return ERROR;  
  174.     k = MAX_SIZE - 1;  
  175.     for (j = 1; j <= i - 1; j++)  
  176.         k = L[k].cur;  
  177.     j = L[k].cur;  
  178.     L[k].cur = L[j].cur;  
  179.     e = L[j].data;  
  180.     Free(L, j);  
  181.     return OK;  
  182. }  
  183.   
  184. void ListTraverse(SLinkList L, void(*vi)(ElemType))  
  185. // 初始条件:线性表L已存在。操作结果:依次对L的每个数据元素调用函数vi()  
  186.     int i = L[MAX_SIZE - 1].cur;  
  187.     while (i)  
  188.     {  
  189.         vi(L[i].data);  
  190.         i = L[i].cur;  
  191.     }  
  192. }  
  193.   
  194. void print(ElemType c)  
  195. {  
  196.     printf("%d ",c);  
  197. }  
  198.   
  199. void main()  
  200. {  
  201.     int j, k;  
  202.     Status i;  
  203.     ElemType e, e0;  
  204.     SLinkList L;  
  205.     InitList(L);  
  206.     for(j = 1; j <= 5; j++)  
  207.         i = ListInsert(L, 1, j);  
  208.     printf("在L的表头依次插入1~5后:L=");  
  209.     ListTraverse(L, print);  
  210.     i = ListEmpty(L);  
  211.     printf("/nL是否空:i=%d(1:是 0:否)表L的长度=%d/n",i, ListLength(L));  
  212.     ClearList(L);  
  213.     printf("清空L后:L=/n");  
  214.     ListTraverse(L, print);  
  215.     i = ListEmpty(L);  
  216.     printf("L是否空:i=%d(1:是 0:否)表L的长度=%d/n",i, ListLength(L));  
  217.     for(j = 1; j <= 10; j++)  
  218.         ListInsert(L, j, j);  
  219.     printf("在L的表尾依次插入1~10后:L=");  
  220.     ListTraverse(L, print);  
  221.     GetElem(L, 5, e);  
  222.     printf("/n第5个元素的值为:%d/n", e);  
  223.     for(j = 0; j <= 1; j++)  
  224.     {  
  225.         k = LocateElem(L, j);  
  226.         if(k)  
  227.             printf("值为%d的元素在静态链表中的位序为%d/n", j, k);  
  228.         else  
  229.             printf("没有值为%d的元素/n", j);  
  230.     }  
  231.     for(j = 1; j <= 2; j++) // 测试头两个数据  
  232.     {  
  233.         GetElem(L, j, e0); // 把第j个数据赋给e0  
  234.         i=PriorElem(L, e0, e); // 求e0的前驱  
  235.         if(!i)  
  236.             printf("元素%d无前驱/n", e0);  
  237.         else  
  238.             printf("元素%d的前驱为:%d/n", e0, e);  
  239.     }  
  240.     for(j = ListLength(L) - 1; j <= ListLength(L); j++) // 最后两个数据  
  241.     {  
  242.         GetElem(L, j, e0); // 把第j个数据赋给e0  
  243.         i=NextElem(L, e0, e); // 求e0的后继  
  244.         if(!i)  
  245.             printf("元素%d无后继/n", e0);  
  246.         else  
  247.             printf("元素%d的后继为:%d/n", e0, e);  
  248.     }  
  249.     k = ListLength(L); // k为表长  
  250.     for(j = k + 1; j >= k; j--)  
  251.     {  
  252.         i=ListDelete(L, j, e); // 删除第j个数据  
  253.         if(i)  
  254.             printf("第%d个元素为%d,已删除。/n", j, e);  
  255.         else  
  256.             printf("删除第%d个元素失败(不存在此元素)。/n", j);  
  257.     }  
  258.     printf("依次输出L的元素:");  
  259.     ListTraverse(L, print); // 依次对元素调用print(),输出元素的值  
  260. }  

原创粉丝点击