[关闭]
@1405010304geshuaishuai 2017-07-21T06:25:59.000000Z 字数 4167 阅读 813

线性表的顺序表示和实现

数据结构 线性表顺序表示


线性表的顺序表示指的是用一组地址连续的存储单元一次存储线性表的数据元素。

以元素在计算机内“物理位置相邻”来表示线性表中元素之间的逻辑关系。

通常用数组来描述数据结构中的顺序存储结构。
由于线性表的长度可变,且所需最大存储空间随问题不同而不同,则在C语言中可用动态分配的一维数组。

  1. //-----线性表的动态分配顺序存储结构---
  2. #define LIST_INIT_SIZE 100 //线性表存储空间的出事分配量
  3. #define LISTINCREMENT 10 //线性表存储空间的分配增量
  4. typedef struct {
  5. ElemType *elem; //存储空间基址
  6. int length; //当前长度
  7. int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
  8. }SqList;

数组指针elem指示线性表的基地址,length指示线性表的当前长度。
顺序表的初始化操作就是为顺序表分配一个预定义大小的数组空间,并将线性表的当前长度设为“0”。listsize指示顺序表当前分配的存储空间大小,一旦因插入元素而空间不足时,可进行再分配,即为顺序表增加一个大小为存储LISTINCREMENT个数据元素的空间。

  1. Status InitList_Sq(SqList &L) {
  2. //构造一个空的线性表L
  3. L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
  4. if(!L.elem) exit(OVERFLOW); //存储分配失败
  5. L.length = 0; //空表长度为0
  6. L.listsize = LIST_INIT_SIZE; //初始存储容量
  7. return OK;
  8. } //InitList_Sq

顺序线性表的插入元素算法:
一般情况下,在第i(1<=i<=n)个元素之前插入一个元素时,需将第n至第i(共n-i+1)个元素向后移动一个位置,算法如下:

  1. Status ListInsert_Sq(SqList &L, int i, ElemType e) {
  2. //在顺序线性表L中第i个位置之前插入新的元素e,i的合法值为1<=i<=ListLength_Sq(L)+1
  3. if(i<1||i>L.length+1) return ERROR; //i值不合法
  4. if(L.length>=L.listsize) { //当前存储空间已满,增加分配
  5. newbase = (ElemType *)realloc(L.elem, (L.listsize+LISTINCREMENT)*sizeof(ElemType));
  6. if(!newbase)exit(OVERFLOW); //存储分配失败
  7. L.elem = newbase; //新基址
  8. L.listsize += LISTINCREMENT; //增加存储容量
  9. }
  10. q = &(L.elem[i-1]); //q为插入位置
  11. for(p=&(L.elem[L.length-1]); p>=q;--p) *(p+1) = *p; //插入位置及之后的元素右移
  12. *q = e; //插入e
  13. ++L.length; //表长增1
  14. return OK;
  15. } //ListInsert_Sq

反之,线性表的删除操作是使长度为n的线性表变为长度为n-1的线性表。为了删除第4个元素,必须将从第5个至第8个元素都依次向前移动一个位置。

  1. Status ListDelete_Sq(SqList &L, int i, ElemType &e) {
  2. //在顺序线性表L中删除第i个元素,并用e返回其值i的合法值为1<=i<=ListLength_Sq(L)
  3. if((i<1)||(i>L.length)) return ERROR; //i值不合法
  4. p = &(L.elem[i-1]); //p为被删除元素的位置
  5. e = *p; //被删除元素的值赋给e
  6. q = L.elem+L.length-1; //表尾元素的位置
  7. for(++p;p<=q;++p) *(p-1) = *p; //被删除元素之后的元素左移
  8. --L.length;
  9. return OK;
  10. } //ListDelete_Sq

顺序表的合并

  1. void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) {
  2. //已知顺序线性表La和Lb的元素按值非递减排列归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
  3. pa = La.elem; pb = Lb.elem;
  4. Lc.listsize = Lc.length = La.length+Lb.length;
  5. pc = Lc.elem = (ElemType *)malloc(Lc.listsize*sizeof(ElemType));
  6. if(!Lc.elem) exit(OVERFLOW); //存储分配失败
  7. pa_last = La.elem + La.length -1;
  8. pb_last = Lb.elem + Lb.length -1;
  9. while(pa <= pa_last && pb<=pb_last) { //归并
  10. if(*pa<=*pb) *pc++=*pa++;
  11. else
  12. *pc++ = *pb++;
  13. }
  14. while(pa<=pa_last) *pc++ = *pa++;//插入La的剩余元素
  15. while(pb<=pb_last) *pc++ = *pb++; //插入Lb的剩余元素
  16. } //MergeList_Sq

下面例子转自http://blog.csdn.net/lincyang/article/details/8606682
注意,该博文中的程序有错误,请看该博文评论,出现两处错误,一处为i>index修改为i>=index另一处为在插入数据的时候应该先把该数据之后的数据右移再插入数据,博主刚好把顺序颠倒。
下面为已改正的程序:

  1. //201707
  2. //Charley
  3. //linear list
  4. //Sequence Storage Structure
  5. //
  6. #include <stdio.h>
  7. #define OK 1
  8. #define ERROR -1
  9. #define TRUE 1
  10. #define FALSE 0
  11. #define MAXLENGTH 20
  12. struct sequencelist
  13. {
  14. int data[MAXLENGTH];
  15. int length;
  16. };
  17. //get list elements
  18. //make sure element is NOT NULL when calling.
  19. int getElement(struct sequencelist list,int index, int *element)
  20. {
  21. printf("\ngetElement\n");
  22. int length = list.length;
  23. printf("length is %d\n",length);
  24. if(length==0||index<0||index>=length)
  25. return ERROR;
  26. *element = list.data[index];
  27. return OK;
  28. }
  29. //insert operation
  30. //
  31. int insert(struct sequencelist *list, int index, int element)
  32. {
  33. printf("\ninsert\n");
  34. int i=0, length = list->length;
  35. printf("length is %d\n",length);
  36. if(length==0||index<0||index>length||length>=MAXLENGTH)
  37. return ERROR;
  38. for(i=length-1;i>=index;i--)
  39. {
  40. list->data[i+1]=list->data[i];
  41. }
  42. list->data[index]=element;
  43. list->length++;
  44. return OK;
  45. }
  46. //Delete opration
  47. //
  48. int delete(struct sequencelist *list, int index)
  49. {
  50. printf("\ndelete\n");
  51. int i=0, length = list->length;
  52. printf("length is %d\n",length);
  53. if(length==0||index<0||index>length-1)
  54. return ERROR;
  55. for(i=index;i<length-1;i++)
  56. {
  57. list->data[i]=list->data[i+1];
  58. }
  59. list->data[length-1]='\0';
  60. list->length--;
  61. return OK;
  62. }
  63. int main()
  64. {
  65. struct sequencelist list =
  66. {
  67. {3,1,5,7,12,78,34},
  68. 7
  69. };
  70. printf("list length : %d\n",list.length);
  71. //Test get
  72. int *element = 0, test = 8;
  73. element = &test;
  74. if(OK == getElement(list,2,element))
  75. {
  76. printf("list get 2:%d\n", *element);
  77. }
  78. //Test insert
  79. if(OK==insert(&list,7,520))
  80. {
  81. printf("list insert 7 ok!\n");
  82. }
  83. if(OK==getElement(list,7,element))
  84. {
  85. printf("list get 7 :%d\n", *element);
  86. }
  87. if(OK==insert(&list,3,520))
  88. {
  89. printf("list insert 3 ok!\n");
  90. }
  91. if(OK==getElement(list,3,element))
  92. {
  93. printf("list get 3 :%d\n",*element);
  94. }
  95. //Test delete
  96. if(OK == delete(&list,3))
  97. {
  98. printf("list delete 3 ok\n");
  99. }
  100. if(OK == getElement(list,3,element))
  101. {
  102. printf("list get 3 :%d\n",*element);
  103. }
  104. if(OK == delete(&list,6))
  105. {
  106. printf("list delete 6 ok\n");
  107. }
  108. if(OK == getElement(list,6,element))
  109. {
  110. printf("list get 6:%d\n", *element);
  111. }
  112. else
  113. {
  114. printf("list get ERROR!\n");
  115. }
  116. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注