当前位置:   article > 正文

线性表的创建和基本操作_创建一个线性表

创建一个线性表

&&逻辑与 ||逻辑或

线性表是最基本、最简单、也是最常用的一种数据结构。

线性表结构中,数据元素之间通过一对一首位相接的方式连接起来。

具体实现时,线性表可

以采用不同的存储策略。

该方案将线性表存储在一片连续的空间里,通过data,len , 和max三个属性元素。

组织成为了一个结构:

  • data: 给出线性存储空间的起始地址;
  • max : 指明线性表存储空间最
  • len : 当前线性表里的数据元素个数。

为了讨论简化,我们假设每个数据元素是一个整数:

  1. 该线性表的结构定义如下:
  2. struct SeqList{
  3. T* data; //数据元素存储空间的开始地址
  4. int len; //线性表的当前长度
  5. int max; //线性表的最大长度
  6. };

以上示意图中的slist是指向给结构的一个指针,只要给定slist指针,就可对线性表就行操作。

对数据元素进行操作处理是一个数据结构的重要组成部分。线性表涉及的主要操作如下:

 SeqList*SL_Create(int max)

  • 释放线性表存储空间: 释放slist->data 指向的用于存储线性表数据元素的存储空间。该操作函数具体定义如下:

void SL_Free(SeqList*slist)

  • 置空线性表:将当前线性表变为一个空表,实现方法是将slist->len 设置为0。该操作函数具体定义如下:

void SL_MakeEmpty(SeqList*slist)

  • 获取线性表当前长度:获取并返回线性表的当前长度slist->len。该操作函数具体定义如下:

int SL_Length(SeqList*slist)

  • 判断线性表是否为空:若当前线性表是空表,则返回false,否则返回true.该操作函数具体定义如下:

BOOL SL_IsEmpty(SeqList*slist)

  • 判断线性表是否已满:若线性表达到最大长度,则返回true,否则返回false。该操作函数具体定义如下:

BOOL SL_IsFull(SeqList*slist)

  • 返回线性表第 i 个数据元素: 返回线性表的第 i 个数据元素 slist ->data[i] 。 该操作函数具体定义如下:

T SL_GetAt(SeqList* slist , int i)

  • 修改线性表第 i 个数据元素: 将线性表的第 i 个数据元素的值修改为 x 。 该操作函数具体定义如下:

void SL_SetAt(SeqList*slist, int i , T x)

  • 在线性表位置 i 插入数据元素 x : 将x 插入slist->data[i] 之前。若插入失败(i>slist-len 或 i <0时, 无法插入),返回false , 否则返回true。 该操作函数具体定义如下:

BOOL SL_InsAt(SeqList*slist , int i , T x)

  • 删除线性表位置 i 处 的数据元素: 删除线性表的 i 号数据元素。输入参数 i 范围应在 [0,slist -> len -1] 内,否则会产生不能预料的异常或错误。返回被删除的数据元素的值。该操作函数具体定义如下:

T SL_DelAt(SeqList* slist , int i)

  • 查找线性表中第一个值为x的数据元素的位置: 找到线性表中第一个值为x的数据元素的编号。返回值-1表示没有找到,返回值>=0表示该元素位置。该操作函数具体定义如下:

int SL_FindValue(SeqList* slist , T x)

  • 删除线性表中第一个值为x的数据元素: 删除第一个值为x的数据元素,返回该数据元素的编号。如果不存在值为x的数据元素,则返回-1. 该操作函数具体定义如下:

int SL_DelValue(SeqList*slist , T x)

  • 打印线性表: 打印整个线性表。该操作函数具体定义如下:

void SL_Print(SeqList*slist)

  1. //顺序表操作实现
  2. SeqList* SL_Create(int maxlen)
  3. //创建一个顺序表。
  4. //与SqLst_Free()配对。
  5. {
  6. SeqList*slist=(SeqList*)malloc(sizeof(SeqList));
  7. slist->data = (T*)malloc (sizeof(T)*maxlen);
  8. slist -> max =maxlen;
  9. slist -> len=0;
  10. return slist;
  11. }
  12. void SL_Free(SeqList* slist)
  13. //释放/删除 顺序表
  14. //与SqLst_Create()配对
  15. {
  16. free(slist -> data);
  17. free(slist);
  18. }
  19. void SL_MakeEmpty(SeqList* slist)
  20. //置为空表
  21. {
  22. slist -> len=0
  23. }
  24. int SL_Length(SeqList* slist)
  25. //获取长度。
  26. {
  27. return slist ->len;
  28. }
  29. bool SL_IsEmpty(SeqList* slist)
  30. //判断顺序表是否为空
  31. {
  32. return 0==slist ->len;
  33. }
  34. T SL_GetAt(SeqList* slist, int i)
  35. //获取顺序表slist的第i号节点数据。
  36. //返回第i号节点的值。
  37. {
  38. if(i<0||i>=slist->len){
  39. printf("SL_GetAt():location error when reading elements of the slist!\n");
  40. SL_Free(slist);
  41. exit(0);
  42. }
  43. else
  44. return slist->data[i];
  45. }
  46. void SL_SetAt(SeqList* slist , int i ,T x)
  47. //设置第i 号节点的值(对第i号结点的数据进行写)。
  48. {
  49. if (i<0||i>=slist->len){
  50. printf("SL_SetAt():location error when setting elements of the slist!\n");
  51. SL_Free(slist);
  52. exit(0);
  53. }
  54. else
  55. slist->data[i]=x;
  56. }

实现一个链接存储的线性表

  1. #include<stdlib.h>
  2. #include "LinkList.h"
  3. // 1)
  4. LinkList* LL_Create()
  5. //创建一个链接存储的线性表,初始为空表,返回llist指针
  6. {
  7. LinkList* llist=(LinkList*)malloc(sizeof(LinkList));
  8. llist->front=NULL;
  9. llist->rear=NULL;
  10. llist->pre=NULL;
  11. llist->curr=NULL;
  12. llist->position=0;
  13. llist->len=0;
  14. return llist;
  15. }
  16. // 2)
  17. void LL_Free(LinkList* llsit)
  18. //释放链表的结点,然后释放llist所指向的结构
  19. {
  20. LinkNode* node=llist->front;
  21. LinkNode* nextnode;
  22. while (node){
  23. nextnode=node->next;
  24. free(node);
  25. node=nextnode;
  26. }
  27. free(llsit);
  28. }
  29. //3)
  30. void LL_MakeEmpty(LinkList* llist)
  31. //将当前线性表变为一个空表,因此需要释放所有结点
  32. {
  33. LinkNode* node=llist->front;
  34. LinkNode* nextnode;
  35. while(node){
  36. nextnode=node->next;
  37. free(node);
  38. node=nextnode;
  39. }
  40. llist->front=NULL;
  41. llsit->rear=NULL;
  42. llist->pre=NULL;
  43. llist->curr=NULL;
  44. llist->position=0;
  45. llsit->len=0
  46. }
  47. int LL_Length(LinkList* llist)
  48. //返回线性表的当前长度
  49. {
  50. return llsit->len;
  51. }
  52. //5)
  53. bool LL_IsEmpty(LinkList* llist)
  54. //若当前线性表是空表,则返回true,否则返回False
  55. {
  56. return llsit->==0;
  57. }
  58. //6)
  59. bool LL_SetPosition(LinkList* llist, int i)
  60. //设置线性表的当前位置为i号位置。
  61. //设置成功,则返回ture,否则返回false(线性表为空,或i不在有效的返回)
  62. //假设线性表当前长度len,那么i的有效范围为[0,len].
  63. {
  64. int k;
  65. /*链表为空、或越界*/
  66. if(llist->len==0 || i<0 || i>llist->len ){
  67. printf("LL_SetPosition():position error");
  68. return false;
  69. }
  70. /*寻找对应结点*/
  71. llist ->curr=llist->front;
  72. llist->pre=NULL;
  73. llist->position=0;
  74. for (k=0;k<i;k++){
  75. llist->posiontion++;
  76. llist->pre=llist->curr;
  77. llist->curr=(llist->curr)->next;
  78. }
  79. /*返回当前结点位置*/
  80. return true;
  81. }
  82. }
  83. //8)
  84. bool LL_NextPosition(LinkList* llist)
  85. //设置线性表的当前位置的下一个位置为当前位置。
  86. //设置成功,则返回true,否则返回false(线性表为空,或当前位置为表尾)
  87. {
  88. if(llist->position>=0 && lllsit->position<llist->len)
  89. /*若当前结点存在,则将其后设置为当前结点*/
  90. {
  91. llist->position++;
  92. llist->pre =llist->curr;
  93. llist->curr=llist->curr->next;
  94. return true;
  95. }
  96. else
  97. return false;
  98. }
  99. T LL_GetAt(LinkList* llist)
  100. //返回线性表的当前位置的数据元素的值
  101. {
  102. if(llist->curr==NULL)
  103. {
  104. printf("LL_GetAt():Empty list,or End of the List.\n");
  105. LL_Free(llist);
  106. exit(1);
  107. }
  108. return llist->curr->data;
  109. }
  110. void LL_SetAt(LinkList* llist, T x)
  111. //将线性表的当前位置的数据元素的值修改为x
  112. {
  113. if(llist->curr==NULL)
  114. {
  115. printf("LL_SetAt():Empty list,or End of the List.\n";)
  116. LL_Free(llist);
  117. exit(1);
  118. }
  119. llist->curr->data=x;
  120. }
  121. //11)
  122. bool LL_InsAt(LinkList* llsit,T x)
  123. //在线性表的当前位置之前插入数据元素x.当前位置指针指向新数据元素结点。
  124. {
  125. LinkNode *newNode=(LinkNode*)malloc(sizeof(LinkNode));
  126. if (newNode==NULL) return false;
  127. newNode->data=x;
  128. if (llist->len==0){
  129. //在空表中插入
  130. newNode->next=NULL;
  131. llist->front = llist->rear=newNode;
  132. }
  133. //当前位置为表头;
  134. else if (llist ->pre==NULL)
  135. {
  136. /*在表头结点处插入*/
  137. newNode->next=llist->front;
  138. llist->front=newNode;
  139. }
  140. else{
  141. /*在链表的中间位置或表尾后的位置插入*/
  142. newNode->next=llist->curr;
  143. llist->pre->next=newNode;
  144. }
  145. //插入在表尾后。
  146. if(llist->pre==llist->rear)
  147. llist->rear=newNode;
  148. /*增加链表的大小*/
  149. llsit->len++;
  150. /*新插入的结点为当前结点*/
  151. llist->curr=newNode;
  152. return true;
  153. }
  154. //12)
  155. bool LL_InsAfter(LinkList* llist , T x)
  156. //在线性表的当前位置之后插入数据元素x。空表允许插入。当前位置指针将指向新结点。
  157. //若插入失败,返回false,否则返回true.
  158. {
  159. }
  160. //13)
  161. bool LL_DelAt(LinkList* llist)
  162. //删除线性表的当前位置的数据元素结点
  163. //若删除失败(为空表,或当前位置为尾结点之后),则放回false,否则返回true
  164. {
  165. LinkNode *oldNode;
  166. /*若表为空或已到表尾之后,则给出错误提示并返回*/
  167. if(llist->curr==NULL)
  168. {
  169. printf("LL_DelAt():delete a node that does not exist.\n");
  170. return false;
  171. }
  172. oldNode =llist->curr;
  173. /*删除的是表头结点*/
  174. if(llist->pre==NULL)
  175. {
  176. llist->front=oldNode->next;
  177. }
  178. /*删除的是表中或表尾结点*/
  179. else if (llsit->curr!NUll){
  180. llist->pre->next=oldNode->next;
  181. }
  182. if(oldNode==llist->rear){
  183. /*删除的是表尾结点,则修改表尾指针和当前结点位置值*/
  184. llist->rear=llist->pre;
  185. }
  186. /*后继节点作为新的当前结点*/
  187. llsit->curr=odlNode->next;
  188. /*释放原当前结点*/
  189. free*(oldNode);
  190. /*链表大小减*/
  191. llist->len --;
  192. return true;
  193. }
  194. //14)
  195. bool LL_DelAfter(LinkList* llist)
  196. //删除线性表的当前位置的那个数据元素
  197. //若删除失败(为空表、或当前位置是表尾),则返回false,否则返回true
  198. {
  199. LinkNode *oldNode;
  200. /*若表为空或已到表尾,则给出错误提示并返回*/
  201. if(llist->curr==NULL||llist->curr==llist->rear)
  202. {
  203. printf("LL_DelAfter():delete a node that does not exist.\n");
  204. return false;
  205. }
  206. /*保存被删除结点的指针并从链表中删除该节点*/
  207. oldNode = llist->curr->next;
  208. llist->curr->next=oldNode->next;
  209. if(oldNode==llsit->rear)
  210. /*删除的表尾结点*/
  211. llist->rear=llist->curr;
  212. /*释放别删除结点*/
  213. free(oldNode);
  214. llist->len--;
  215. return true;
  216. }
  217. //15)
  218. int LL_FindValue(LinkList* llist,T x)
  219. //找到线性表中第一个值为x的数据元素的编号。
  220. //返回值-1表示没有找到,返回值>=0表示标号。
  221. {
  222. LinkNode* p=llist->front;
  223. int idx=0;
  224. while(p!=NULL && p->data!=x){
  225. idx++;
  226. p=p->next;
  227. }
  228. if(idx>=llist->len)return -1;
  229. else return idx;
  230. }
  231. //16)
  232. int LL_DelValue(LinkList* llist, T x)
  233. //删除第一个值为x的数据元素,返回该数据元素的编号。如果不存在值为x的数据元素,则返回-1
  234. {
  235. int idx=LL_FindValue(llist,x);
  236. if(idx>0)return -1;
  237. LL_SetPosition(llsit,idx);
  238. LL_DelAt(llist);
  239. return idx;
  240. }
  241. //17))
  242. void LL_Print(LinkList* llist)
  243. //打印整个线性表
  244. {
  245. LinkNode* node=llist-front;
  246. while(node){
  247. printf("%d",node->data);
  248. node=node->next;
  249. }
  250. printf("\n");
  251. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/529454
推荐阅读
  

闽ICP备14008679号