直接插入全部代码:(reverseLinklist函数是逆置操作)

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4.  
  5. typedef int LDataType;
  6. typedef struct Linklist{
  7. LDataType data;
  8. struct Linklist *next;
  9. }Linklist,*pLinklist;
  10.  
  11. pLinklist BuyNewNode(LDataType data); //动态生成新结点
  12. void InitLinklist(pLinklist *pL); //初始化单链表
  13. void PushBackLinklist(pLinklist *pL,LDataType data); //尾插
  14. void PushFrontLinklist(pLinklist *pL,LDataType data); //头插
  15. void PopBackLinklist(pLinklist* pL); //尾删
  16. void PopFrontLinklist(pLinklist *pL); //头删
  17. void PrintLinklist(Linklist *pL); //打印单链表
  18. pLinklist FindLinklist(pLinklist *pL,LDataType data); //查找指定元素,返回元素位置
  19. void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data); //指定位置插入
  20. void RemoveLinklist(pLinklist* pL,LDataType data); //删除第一个指定元素
  21. void RemoveAllLinklist(pLinklist *pL,LDataType data); //删除所有指定元素
  22. int IsEmptyLinklist(pLinklist pL); //判断链表是否为空
  23. void DestoryLinklist(pLinklist *pL); //销毁单链表
  24. pLinklist reverseLinklist(pLinklist *pL);
  25.  
  26. int main(void){
  27. Linklist *first = NULL;
  28. InitLinklist(&first);
  29. PushBackLinklist(&first,5);
  30. PushBackLinklist(&first,4);
  31. PushBackLinklist(&first,3);
  32. PushBackLinklist(&first,2);
  33. PushBackLinklist(&first,1);
  34. PushBackLinklist(&first,0);
  35. PushFrontLinklist(&first,6);
  36. first = reverseLinklist(&first);
  37. PushFrontLinklist(&first,-1);
  38. PrintLinklist(first);
  39. }
  40.  
  41. pLinklist BuyNewNode(LDataType data){
  42. pLinklist NewNode = (pLinklist)malloc(sizeof(Linklist));
  43. if (NewNode == NULL){
  44. printf("动态开辟内存空间失败\n");
  45. return NULL;
  46. }
  47. NewNode->data = data;
  48. NewNode->next = NULL;
  49. return NewNode;
  50. }
  51. void InitLinklist(pLinklist *pL){
  52. assert(pL != NULL); //初始化操作
  53. (*pL) = NULL;
  54. }
  55. void PushBackLinklist(pLinklist *pL,LDataType data){
  56. assert(pL != NULL); //尾插一个数据域为data的结点
  57. pLinklist NewNode = BuyNewNode(data);
  58. if(*pL == NULL){
  59. *pL = NewNode;
  60. return ;
  61. }
  62. pLinklist cur = *pL;
  63. while(cur->next){
  64. cur = cur->next;
  65. }
  66. cur->next = NewNode;
  67. }
  68. void PushFrontLinklist(pLinklist *pL,LDataType data){
  69. assert(pL != NULL); //头插一个数据域为data的结点
  70. pLinklist NewNode = BuyNewNode(data);
  71. if(*pL == NULL){
  72. *pL = NewNode;
  73. return ;
  74. }
  75. NewNode->next = *pL;
  76. *pL = NewNode;
  77. }
  78. int IsEmptyLinklist(pLinklist pL){
  79. return (pL == NULL); //判断无头单链表是否为空
  80. }
  81. void PopBackLinklist(pLinklist *pL){
  82. assert(pL != NULL); //尾删
  83. if(IsEmptyLinklist(*pL)){
  84. puts("链表为空,删除失败");
  85. return ;
  86. }
  87. pLinklist cur = *pL;
  88. pLinklist pre;
  89. if(cur->next == NULL){
  90. //只有一个结点
  91. *pL = NULL;
  92. free(cur);
  93. cur = NULL;
  94. return ;
  95. }
  96. while(cur->next){
  97. pre = cur;
  98. cur = cur->next;
  99. }
  100. pre->next = NULL;
  101. free(cur);
  102. cur = NULL;
  103. }
  104. void PopFrontLinklist(pLinklist *pL){
  105. assert(pL != NULL); //头删,既是删除第一个结点
  106. if(*pL == NULL){
  107. printf(" 链表为空,删除失败");
  108. return ;
  109. }
  110. pLinklist cur = *pL;
  111. *pL = cur->next;
  112. free(cur);
  113. cur = NULL;
  114. }
  115. pLinklist FindLinklist(pLinklist *pL,LDataType data){
  116. assert( pL != NULL); //找到第一个数据为data的结点
  117. pLinklist cur = *pL;
  118. while(cur){
  119. if (cur->data == data){
  120. return cur;
  121. }
  122. cur = cur->next;
  123. }
  124. return NULL;
  125. }
  126. void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data){
  127. assert(pL != NULL); //xiangp结点之前插入一个数据为data的元素
  128. pLinklist NewNode = BuyNewNode(data);
  129. pLinklist cur = *pL;
  130. while(cur->next != p){
  131. cur = cur->next;
  132. }
  133. NewNode->next = p;
  134. cur->next = NewNode;
  135. }
  136. void RemoveLinklist(pLinklist *pL,LDataType data){
  137. assert(pL != NULL); //删除第一个数据域为data的结点
  138. pLinklist cur = NULL;
  139. pLinklist p = *pL;
  140. pLinklist pre = NULL;
  141. cur = FindLinklist(pL,data);
  142. if (cur == NULL){
  143. printf("未找到要删除的元素");
  144. return ;
  145. }
  146. if (*pL == cur){
  147. //位于第一个结点
  148. *pL = cur->next;
  149. free(cur);
  150. cur = NULL;
  151. return ;
  152. }
  153. while(p != cur){
  154. pre = p;
  155. p = p->next;
  156. }
  157. pre->next = cur->next;
  158. free(cur);
  159. cur = NULL;
  160. }
  161. void RemoveAllLinklist(pLinklist *pL,LDataType data){
  162. assert(pL != NULL); //删除每一个数据域都是data的结点
  163. pLinklist cur = NULL;
  164. pLinklist p = *pL;
  165. pLinklist pre = *pL;
  166. while(p){
  167. if (p->data == data && (*pL) == p){
  168. //第一个结点是
  169. pre = p;
  170. p = p->next;
  171. *pL = p;
  172. free(pre);
  173. pre = NULL;
  174. }
  175. else if(p->data == data){
  176. //后续结点是
  177. cur = p;
  178. p = p->next;
  179. pre->next = p;
  180. free(cur);
  181. cur = NULL;
  182. }
  183. else{
  184. //此结点不是
  185. pre = p;
  186. p = p->next;
  187. }
  188. }
  189. }
  190. void PrintLinklist(Linklist *pL){
  191. pLinklist cur = pL; //打印链表
  192. while(cur){
  193. printf("%d--->",cur->data);
  194. cur = cur->next;
  195. }
  196. printf("NULL\n");
  197. }
  198. void DestoryLinklist(pLinklist *pL){
  199. assert(pL != NULL); //摧毁链表
  200. pLinklist cur = *pL;
  201. pLinklist pre = NULL;
  202. if (*pL == NULL){
  203. printf("链表为空");
  204. return ;
  205. }
  206. if (cur->next = NULL){
  207. *pL = NULL;
  208. free(cur);
  209. cur = NULL;
  210. return ;
  211. }
  212. while(cur){
  213. pre = cur;
  214. cur = cur->next;
  215. free(pre);
  216. pre = NULL;
  217. }
  218. }
  219. pLinklist reverseLinklist(pLinklist *pL){
  220. if((*pL) == NULL || pL == NULL){
  221. return NULL;
  222. }
  223. if((*pL)->next == NULL){
  224. return *pL;
  225. }
  226. Linklist *p = *pL;
  227. Linklist *q = (*pL)->next;
  228. Linklist *r = *pL;
  229. while(q->next != NULL){
  230. r = q->next;
  231. q->next = p
  232. p = q;
  233. q = r;
  234. r = r->next;
  235. }
  236. q->next = p;
  237. (*pL)->next = NULL;
  238. *pL = q;
  239. return *pL;
  240. }

第一步就是判断这个单链表是否为空,因为我用了二级指针,因此要看链表为空的同时还要看pL是否指向有问题。

然后看几个元素,如果只有一个元素的话,直接返回就行了,剩下的难点是如何解决超过一个元素的链表;

注意到我用了p,q,r;三个指向结点的指针,p是存前一个元素,q是实现逆置的指针,通过它来指向前面那一个结点,r是后面的指针,其存在的意义是为了让q有后续,因为q指向其他地方后,无法通过p = p->next进行传递。下面是图示。

我感觉应该听得懂。(图中最后一步没有在图中把原来头指针指向结点的next域改为NULL,看图请注意!!!

逆置单链表(基于c语言)的更多相关文章

  1. 单链表(C语言实现)

    链表结构: SList.h //-------------------------------------------------------------------------- /* **功能:应 ...

  2. 无头结点的单链表(C语言)

    1.单链表: 在顺序表中,用一组地址连续的存储单元来一次存放线性表的结点,因此结点的逻辑顺序与物理顺序是一致的.但链表却不同,链表是用一组任意的存储单元来存放 线性表的结点,这组存储单元可以是连续的, ...

  3. 单链表(c语言实现)贼详细

    直接上代码吧 #include<stdio.h> #include<malloc.h> /* 单链表特点: 它是一种动态的储存结构,链表中每个节点占用的储存空间不是预先分配的, ...

  4. C语言版本:单链表的实现(优化版本)

    未优化版本:http://www.cnblogs.com/duwenxing/p/7569376.html slist.h #ifndef __SLIST_H__ #define __SLIST_H_ ...

  5. C语言版本:单链表的实现

    slist.h #ifndef __SLIST_H__ #define __SLIST_H__ #include<cstdio> #include<malloc.h> #inc ...

  6. 如何使用C++实现单链表

    线性表--链表 为什么假期也在发文章 //TODO NullGirlfrindException 请忽略以上两行无聊的事实...... 如何弥补顺序表的不足之处? 第一次学习线性表一定会马上接触到一种 ...

  7. Java带头节点单链表的增删合并以及是否有环

    带头节点单链表 1.优势: 1)当链表为空时,指针指向头结点,不会发生null指针异常 2)方便特殊操作(删除第一个有效节点或者插入一个节点在表头) 3)单链表加上头结点之后,无论单链表是否为空,头指 ...

  8. 数据结构C语言实现系列——线性表(线性表链接存储(单链表))

    #include <stdio.h>#include <stdlib.h>#define NN 12#define MM 20typedef int elemType ;/** ...

  9. C语言单链表实现19个功能完全详解

    谢谢Lee.Kevin分享了这篇文章 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将 ...

随机推荐

  1. tabbar选中按钮的标题颜色和字体

    @implementation XMGTabBarController /* 问题: 1.选中按钮的图片被渲染 -> iOS7之后默认tabBar上按钮图片都会被渲染 1.修改图片 2.通过代码 ...

  2. 源码推荐 VVebo剥离的TableView绘制

    源码推荐 VVebo剥离的TableView绘制 https://github.com/johnil/VVeboTableViewDemo 此项目由VVebo剥离,希望你能通过这个demo看到我是如何 ...

  3. Ansible 自动化运维——剧本(playbook)

    Ansible 自动化运维--剧本(playbook) 1.playbook介绍: playbook是ansible用于配置,部署,和管理被控节点的剧本.通过playbook的详细描述,执行其中的ta ...

  4. Ubuntu - root, sudo, su, passwd

    1.rootubuntu中默认是不使用root账户的,当然也是可以开启并设置为默认登录账户的,但ubuntu不建议使用而已,毕竟root账户拥有所有权限,可能会出现一些误操作之类.在普通账户中,如果遇 ...

  5. Vue2.0源码学习(2) - 数据和模板的渲染(下)

    vm._render是怎么实现的 上述updateComponent方法调用是运行了一个函数: // src\core\instance\lifecycle.js updateComponent = ...

  6. 理解OAuth2.0协议和授权机制

    无论是自然资源还是互联网上的资源,需要控制使用权与被使用权,以保护资源的安全.合理的使用和有效的管控. 项目中,我们需要控制的是用户资源,既要保证有效用户的合理使用,又要防范非法用户的攻击.如此,如何 ...

  7. pytest--mark基本使用(主要通过pytest.ini文件注册标签名,对用例进行标记分组)

    1.pytest中的mark介绍 mark主要用于在测试用例/测试类中给用例打标记(只能使用已注册的标记 名),实现测试分组功能,并能和其它插件配合设置测试方法执行顺序等.如下 图,现在需要只执行红色 ...

  8. C# 中的Stream流

    流就是一个类的对象,很多文件的输入输出操作都以类的成员函数的方式来提供: 流其实是一种信息的转换,是有序的,有输入和输出流(IO); 1.FileStream 文件流,读取和保存文件操作使用: //写 ...

  9. 对于计算正确率时 logits.argmax(dim=1),torch.eq(pre_label,label)

    额  好像是一句非常简单的代码 ,但是作为新手 ,我是完全看不懂哎 前十眼. 首先 这里的logits是一个 (a,b)维的张量.其中a是你的全连接输出维度,b是一个batch中的样本数量. 我们经过 ...

  10. excel仪表盘制作,商业智能仪表盘的作用

    ​商业仪表盘被称为管理驾驶舱的重要组成部分,无论是管理决策者,还是企业业务流程中的普通员工,都可以利用它来展示分析的结果,让决策更加快速准确,更快地推动业务流程的进展,提高工作效率. 一个明确地了解自 ...