小菜鸟的单向链表反转

关于单向链表的反转想必大家都很熟了,以前一直用递归的方法写的,还是挺好写的,但是后来又在网上瞄了一眼非递归方法的实现,当时以为那个代码是正确的,也没验证,后来就不了了之。

昨天下午开始写这个代码,最后老发现出问题,今天早上起来理了一遍,终于发现症结所在。

举个例子吧:

1->2->3->4->5->6       我反转后的结果应该是: 6->5->4->3->2->1

我的算法是这样的(语死早,大家不要笑,我就用过程图表达吧):

1->2->3->4->5->6

2->1->3->4->5->6

3->2->1->4->5->6

4->3->2->1->5->6

5->4->3->2->1->6

6->5->4->3->2->1

其实整个过程不复杂,但是吧,之前一直没把图画出来,理所当然的在空想,我把我的感触写下来吧:

1:注意1这个位置,这个位置起着连接后面未操作的数据的作用,相当重要,这是我之前代码一直出问题的原因

2:注意每次头结点的变化

3:到最后的时候尾节点变成了1位置的节点

好了,放代码了,新手写代码,大家请多多指教O(∩_∩)O哈!

struct Node   // 结点结构
{
  int m_data;
  Node* m_next;
};

struct List   // 单向链表结构
{
  Node* m_head;
  Node* m_tail;
  size_t m_length;

};

// 单向链表反转
  Node* first = m_head;                        // 两个待交换结点的第一个结点    
  Node* second = m_head->m_next;     // 两个待交换结点的第二个结点
  Node* next = second->m_next;          // 下一个要交换的节点
  Node* last = m_head;                         // 存放上面的“1”对应的节点

  //以下是第一次交换,是第一个结点和第二个结点的交换

  second->m_next = first;   // 后面的节点改变指向指向前面的节点
  first->m_next = next;      // 前面的节点改变指向,指向下一个要交换的节点
  first = second;                //  这一行和下一行做的操作就是把后面的节点和下一个要交换的节点放到first和second中用来操作
  second = next;
  next = next->m_next;   //下下个要交换的节点

  while(second != NULL)
  {
    second->m_next = first;  // 同上面的注释
    last->m_next = next;    //这一块就比较坑啦,大家要注意看我上面的图中1所在的位置,是1在不停地往后走,first对应的数据其实它的后结点是不会变了
    first = second;       // 上面已经有注释
    second = next;
    if (next != NULL)
    {
      next = next->m_next;
    }
  }
  m_head = first;
  m_tail = last;

  

  哎,我这表达能力啊,太捉急了,不过总算是写完了。。。谢谢大家捧场。

小菜鸟的单向链表反转

时间: 2024-12-21 03:20:00

小菜鸟的单向链表反转的相关文章

单向链表反转算法——递归版和迭代版

最近在做笔试题时,遇到一道编程题:单向链表反转算法.一时紧张,没写出来就提前交卷了,然而交完卷就想出来了... 最初想出来的是递归版,遗憾的是没能做到尾递归,后来又琢磨出了迭代版.后来用实际编译运行测试了一遍,能正常运行. 递归版的灵感来源于<Haskell 趣学指南>中非常简洁的快速排序算法的实现,其思想是将单向链表分割头部和尾部.其中头部指是链表的第一个节点,尾部是指除去第一个节点后的子链表.通过递归的方法,将子链表继续分割成头部和尾部,直至尾部指剩下一个节点,无法继续分割,然后将头部和尾

php 单向链表反转 reverse (没有空的头结点)

* 参照php标准库设计接口 http://php.net/manual/en/class.spldoublylinkedlist.php * 反转单向链表 reverse方法, 其他的方法为了方便测试 <?php /** * Created by PhpStorm. * User: Mch * Date: 8/11/18 * Time: 00:25 */ class Node { public $value; public $next; public function __construct(

单向链表反转,就地逆置与递归反转(无表头结点)

最近在看链表,今天刷到一道链表的反转题,链表反转可以说是基础操作,但是可提供的方案也有很多,简单通过了该题后又学习了一下递归反转,现在把三种方法都公开出来做一个总结. 1.就地逆置 2.单参数的递归逆置 3.双参数的递归逆置 一.就地逆置 方法:头插. 由于这里是不带表头结点的单向链表,所以头插会稍微复杂一点,不想往下看的小伙伴也可以直接选择定义一个临时表头结点从头结点开始遍历链表将每一个链表头插,最后将头结点指向表头结点的next指针域,最后free掉那个表头结点即可. 虽然不带表头结点头插会

Java实现单向链表反转

环境: Java: jdk1.8.0_91 public class LinkedListTest { public static void main(String[] args) { Node A = new Node("A"); Node B = new Node("B"); Node C = new Node("C"); Node D = new Node("D"); Node E = new Node("E&

数据结构和算法--3链表(单向链表、双向链表、环形单向链表和约瑟夫问题)

链表 链表是以节点的方式来存储 每个节点包含data域和next域,指向下一个节点 链表的各个节点不一定是连续存储 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定 单向列表 最大特点是可以将物理地址上不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查等功能. 单链表分为两种:有头链表和无头链表. 有头节点的增删改查 定义一个单链表的类: //定义一个SingleLinkedList,单链表,管理HeroNode class SingleLinkedList{ //初始

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t[转]

菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t Author:Echo Chen(陈斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:October 23h, 2014 1.ngx_list优势和特点 ngx_list _t是一个顺序容器,它实际上是动态数组和单向链表的结合体,扩容起来比动态数组简单的多,可以一次扩容一个数组,所以说它结合了 链表插入删除不需要移动的 和 数组下标快速索引 的优势

算法总结之 反转部分单向链表

给定单链表的表头节点head, 以及两个整数from 和 to, 在单向链表上把fro个节点到第to个节点这一部分进行反转 思路: 本题 有可能存在换头的问题,所以函数应该返回调整后的新的头节点 1 判断是否满足 1<=from<=to<=N 如果不满足,直接返回原来的头节点 2 找到第from-1个节点pre和第to+1个节点tPos,fPre即要反转部分的前一个节点,tPos是反转部分的后一个节点,把反转部分先反转,然后正确的链接fPre和tPos package TT; impor

[算法]反转单向链表和双向链表

题目: 分别实现反转单向链表和双向链表的函数. 要求: 如果链表长度为N,时间复杂度为O(N),额外空间复杂度要求为O(1). 程序: 反转单向链表: public class Node{ public Node(int data){ this.value=data; } public int value; public Node next; } public static Node reverseList(Node node){ Node pre=null; Node next=null; w

反转单向链表(JAVA)

在微博看到,有人说8个应届毕业生没有人写出o(1)空间复杂度,o(n)时间复杂度的反转单向链表. (不是我自己想的) public void reverseList(ListNode head) { ListNode newHead = null; while(head != null) { ListNode next = head.next; head.next = newHead; newHead = head; head = next; } return newHead; } 自己也想了很