当前位置:   article > 正文

数据结构 ——单链表【c语言版】_输出链表第i至第j个结点间的所有结点

输出链表第i至第j个结点间的所有结点

线性表:具有相同特性的数据元素(既同类型数据)的一个有限序列.

注:同一线性表中的元素必定具有相同特性

线性表的特性:1.有穷性 2.一致性  3.序列性

线性表的最本质特征:有唯一的前驱和后继

线性表的链式存储结构称为链表

链式存储:逻辑上相邻的数据元素,物理上不一定相邻
 

在单链表中,假设每个节点的类型用SLinkList表示,它包括存储元素的数据域(data),其类型用通用类型标识符ElemType表示,还包括存储后继节点位置的指针域(next)。SLinkList类型声明如下

  1. typedef int ElemType;
  2. typedef struct Node
  3. {
  4. ElemType data;//存储线性表的元素值(1个)
  5. struct Node *next;//存储后继元素节点的地址
  6. }SLinkList;

在链表中建立了一个头节点,方便统一空表与非空表的处理过程

为了方便操作,特别地加了一个头节点进来,类型和普通节点一样
data:不用 
next:存储第1个元素节点的地址

1)初始化线性表 

          构造一个空的单链表,并建立一个头节点

  1. SLinkList *InitList()
  2. {
  3. SLinkList *h;
  4. h=(SLinkList *)malloc(sizeof(SLinkList));
  5. h->next=NULL;
  6. return h;
  7. }

单链表为空条件:h ->next ==NULL

初始化链表的时间复杂度为O(1)

2)销毁单链表

        链表中,销毁元素后需要释放内存

        销毁链表时,需要判断链表是否非空,以确保操作合法性

        这里我们调用删除(ListDelete(SLinkList *h,int i,ElemType *e))来逐一删除链表中的元素

  1. void DestroyList(SLinkList *h)
  2. {
  3. int ListDelete(SLinkList *h,int i,ElemType *e);
  4. ElemType v;
  5. while(h->next!=NULL)//不空
  6. {
  7. //删除第1个元素节点
  8. ListDelete(h,1,&v);
  9. }
  10. free(h);
  11. }

销毁链表的时间复杂度为O(n)

3)判断链表是否为空

        链表为空的条件 :h->next == NULL

  1. ListEmpty(SLinkList *h)
  2. {
  3. if(h->next==NULL)
  4. {
  5. return 1;
  6. }
  7. else
  8. {
  9. return 0;
  10. }
  11. }

或者也可以直接return返回,若为空返回真,否则返回假

  1. ListEmpty(SLinkList *h)
  2. {
  3. return (h->next == NULL) //为空返回True,非空返回False
  4. }

判断链表是否为空的时间复杂度为O(1)

4)求链表长度

        创建一个p,刚开始p指向头节点,此时链表长度len==0,只要 p->next不等于NULL,则让p指向下一个节点,len也加1,当循环结束时,len值就是链表长度

  1. int ListLength(SLinkList *h)
  2. {
  3. SLinkList *p;
  4. int len;
  5. p=h;
  6. len=0;
  7. while(p->next!=NULL)
  8. {
  9. p=p->next;
  10. len=len+1;
  11. }
  12. return len;
  13. }

求链表长度的时间复杂度为O(n)

5)输出链表

  1. void DispList(SLinkList *h)
  2. {
  3. SLinkList *p;
  4. p=h;
  5. printf("线性表的元素为:");
  6. while(p->next!=NULL)
  7. {
  8. p=p->next;
  9. printf("%d ",p->data);
  10. }
  11. printf("\n");
  12. }

输出链表的时间复杂度也为O(n)

6)获取链表中的某一元素值

        取值时,要判断取得值是否为链表的范围内,这里可以调用ListLength(SLinkList *h)来判断参数合法性

  1. /*
  2. 参数合法:i>=1 && i<=ListLength(h)
  3. 若参数合法,进行相关操作,返回1;
  4. 否则,提示,返回0
  5. */
  6. int GetElem(SLinkList *h,int i,ElemType *e)
  7. {
  8. SLinkList *p;
  9. int j;
  10. if(i>=1 && i<=ListLength(h))
  11. {
  12. p=h;
  13. for(j=1;j<=i;j++)
  14. {
  15. p=p->next;
  16. }
  17. *e=p->data;
  18. return 1;
  19. }
  20. else
  21. {
  22. printf("参数错误!\n");
  23. return 0;
  24. }
  25. }

链表中取某一值的时间复杂度也为O(n)

7)查找

        查找链表中是否存在某个元素e

  1. int LocateElem(SLinkList *h,ElemType e)
  2. {
  3. SLinkList *p;
  4. int len;
  5. p=h;
  6. len=0;
  7. while(p->next!=NULL)
  8. {
  9. p=p->next;
  10. len=len+1;
  11. if(p->data==e)
  12. {
  13. return len;
  14. }
  15. }
  16. return 0;
  17. }

查找某一元素的时间复杂度也为O(n),它需要从头开始找

8)插入

        插入也就是添加元素,可以在链表头结点与首结点之间插入元素(头插法),也可以在尾结点之后插入元素(尾插法),甚至可以在链表中任意位置插入元素

此处我们会涉及到头插法与尾插法,但是我会主要讲解任意位置插入的方法

头插法的主要步骤如下:

  1. s->next = h->next;
  2. h->next = s;

尾插法的主要步骤如下:

  1. r->next = s; //r为尾指针
  2. r =s;

单链表插入结点时,需要先找他第i-1个结点,让p指向它,再将新结点q插入,代码如下:

  1. /*
  2. 参数合法:i>=1 && i<=ListLength(h)+1
  3. 若参数合法,进行相关操作,返回1;
  4. 否则,提示,返回0
  5. */
  6. int ListInsert(SLinkList *h,int i,ElemType e)
  7. {
  8. SLinkList *p,*q;
  9. int j;
  10. if(i>=1 && i<=ListLength(h)+1)
  11. {
  12. //1.构造一个节点q,存储元素e
  13. q=(SLinkList *)malloc(sizeof(SLinkList));
  14. q->data=e;
  15. //2.让p指向第i-1个元素节点
  16. p=h;
  17. for(j=1;j<=i-1;j++)
  18. {
  19. p=p->next;
  20. }
  21. //3.添加
  22. q->next=p->next;
  23. p->next=q;
  24. return 1;
  25. }
  26. else
  27. {
  28. printf("参数错误!\n");
  29. return 0;
  30. }
  31. }

在链表中插入元素的时间复杂度为O(n)

9)删除

        删除元素也需要先找到第i-1个,让p指向第i-1个,让q指向第i个,把要删除的元素值存储到*e中 ,再释放内存,代码如下:

  1. /*
  2. 参数合法:i>=1 && i<=ListLength(h)
  3. 若参数合法,进行相关操作,返回1;
  4. 否则,提示,返回0
  5. */
  6. int ListDelete(SLinkList *h,int i,ElemType *e)
  7. {
  8. SLinkList *p,*q;
  9. int j;
  10. if(i>=1 && i<=ListLength(h))
  11. {
  12. //1.让p指向第i-1个
  13. p=h;
  14. for(j=1;j<=i-1;j++)
  15. {
  16. p=p->next;
  17. }
  18. //2.让q指向第i个
  19. q=p->next;
  20. //3.把要删除的元素值存储到*e中
  21. *e=q->data;
  22. //4.删除
  23. p->next=q->next;
  24. //5.释放存储空间
  25. free(q);
  26. return 1;
  27. }
  28. else
  29. {
  30. printf("参数错误!\n");
  31. return 0;
  32. }
  33. }

链表中删除某一元素的时间复杂度为O(n)

因为顺序表必须占用一块事先分配好的存储空间,这样会降低存储空间的利用率。

链表的设计思路就是牺牲空间效率换取时间效率

最后再附上完整代码

  1. #include <stdio.h>
  2. typedef int ElemType;
  3. typedef struct Node
  4. {
  5. ElemType data;//存储线性表的元素值(1个)
  6. struct Node *next;//存储后继元素节点的地址
  7. }SLinkList;
  8. /*
  9. 为了方便操作,特别地加了一个头节点进来,类型和普通节点一样
  10. data:不用
  11. next:存储第1个元素节点的地址
  12. 执行语句p=p->next;一次,p的指向往后移动一个位置
  13. 空:h->next==NULL
  14. 最后一个节点:若p->next==NULL,说明p指向最后一个节点
  15. */
  16. /*
  17. 1.初始化
  18. 构造一个空的线性表
  19. */
  20. SLinkList *InitList()
  21. {
  22. SLinkList *h;
  23. h=(SLinkList *)malloc(sizeof(SLinkList));
  24. h->next=NULL;
  25. return h;
  26. }
  27. /*
  28. 2.销毁
  29. */
  30. void DestroyList(SLinkList *h)
  31. {
  32. int ListDelete(SLinkList *h,int i,ElemType *e);
  33. ElemType v;
  34. while(h->next!=NULL)//不空
  35. {
  36. //删除第1个元素节点
  37. ListDelete(h,1,&v);
  38. }
  39. free(h);
  40. }
  41. /*
  42. 3.判断线性表是否为空
  43. 若为空,返回1;
  44. 否则,返回0
  45. */
  46. ListEmpty(SLinkList *h)
  47. {
  48. if(h->next==NULL)
  49. {
  50. return 1;
  51. }
  52. else
  53. {
  54. return 0;
  55. }
  56. }
  57. /*
  58. 4.求长度
  59. */
  60. int ListLength(SLinkList *h)
  61. {
  62. SLinkList *p;
  63. int len;
  64. p=h;
  65. len=0;
  66. while(p->next!=NULL)
  67. {
  68. p=p->next;
  69. len=len+1;
  70. }
  71. return len;
  72. }
  73. /*
  74. 5.输出
  75. */
  76. void DispList(SLinkList *h)
  77. {
  78. SLinkList *p;
  79. p=h;
  80. printf("线性表的元素为:");
  81. while(p->next!=NULL)
  82. {
  83. p=p->next;
  84. printf("%d ",p->data);
  85. }
  86. printf("\n");
  87. }
  88. /*
  89. 6.取值
  90. 参数合法:i>=1 && i<=ListLength(h)
  91. 若参数合法,进行相关操作,返回1;
  92. 否则,提示,返回0
  93. */
  94. int GetElem(SLinkList *h,int i,ElemType *e)
  95. {
  96. SLinkList *p;
  97. int j;
  98. if(i>=1 && i<=ListLength(h))
  99. {
  100. p=h;
  101. for(j=1;j<=i;j++)
  102. {
  103. p=p->next;
  104. }
  105. *e=p->data;
  106. return 1;
  107. }
  108. else
  109. {
  110. printf("参数错误!\n");
  111. return 0;
  112. }
  113. }
  114. /*
  115. 7.查找
  116. 在线性表中查找是否存在值为e的元素,
  117. 若存在,返回该元素的位序
  118. 否则,返回0
  119. */
  120. int LocateElem(SLinkList *h,ElemType e)
  121. {
  122. SLinkList *p;
  123. int len;
  124. p=h;
  125. len=0;
  126. while(p->next!=NULL)
  127. {
  128. p=p->next;
  129. len=len+1;
  130. if(p->data==e)
  131. {
  132. return len;
  133. }
  134. }
  135. return 0;
  136. }
  137. /*
  138. 8.添加
  139. 参数合法:i>=1 && i<=ListLength(h)+1
  140. 若参数合法,进行相关操作,返回1;
  141. 否则,提示,返回0
  142. */
  143. int ListInsert(SLinkList *h,int i,ElemType e)
  144. {
  145. SLinkList *p,*q;
  146. int j;
  147. if(i>=1 && i<=ListLength(h)+1)
  148. {
  149. //1.构造一个节点q,存储元素e
  150. q=(SLinkList *)malloc(sizeof(SLinkList));
  151. q->data=e;
  152. //2.让p指向第i-1个元素节点
  153. p=h;
  154. for(j=1;j<=i-1;j++)
  155. {
  156. p=p->next;
  157. }
  158. //3.添加
  159. q->next=p->next;
  160. p->next=q;
  161. return 1;
  162. }
  163. else
  164. {
  165. printf("参数错误!\n");
  166. return 0;
  167. }
  168. }
  169. /*
  170. 9.删除
  171. 参数合法:i>=1 && i<=ListLength(h)
  172. 若参数合法,进行相关操作,返回1;
  173. 否则,提示,返回0
  174. */
  175. int ListDelete(SLinkList *h,int i,ElemType *e)
  176. {
  177. SLinkList *p,*q;
  178. int j;
  179. if(i>=1 && i<=ListLength(h))
  180. {
  181. //1.让p指向第i-1个
  182. p=h;
  183. for(j=1;j<=i-1;j++)
  184. {
  185. p=p->next;
  186. }
  187. //2.让q指向第i个
  188. q=p->next;
  189. //3.把要删除的元素值存储到*e中
  190. *e=q->data;
  191. //4.删除
  192. p->next=q->next;
  193. //5.释放存储空间
  194. free(q);
  195. return 1;
  196. }
  197. else
  198. {
  199. printf("参数错误!\n");
  200. return 0;
  201. }
  202. }
  203. /*
  204. 变量先定义,再赋初值,才能使用
  205. */
  206. int main()
  207. {
  208. }

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

闽ICP备14008679号