倒置链表

题目描述:给出单向链表的头节点l,如何只遍历一次就将链表中的所有元素倒转。

算法描述:

首先给出单向链表的结构

    struct LinkList {
        int data;
        LinkList *next;
    };

遍历一次链表,对于每一个节点p,记录p的前驱pre,将p节点的后继(即next域)指向pre,即可完成倒转。

算法步骤:

1、设p节点指向头指针l的下一个节点(即指向第一个元素),pre设为NULL
2、若p的下一个节点为空,跳到4,否则跳到3
3、将q指向p的下一个节点,将p的next域指向pre节点,将pre指向p节点,将p指向q节点,跳到2
4、将p的next域指向pre节点
5、结束

实现:

    p = l->next;
    pre = NULL;
    while (p->next != NULL) {
        q = p->next;
        p->next = pre;
        pre = p;
        p = q;
    }
    p->next = pre;
    return p;

算法说明:

显然,这道题目如果通过记录data域来实现调转,算法复杂度在O(n^2)级,因为在不使用辅助数组的情况下,每次颠倒需要从头节点以O(n)的时间复杂度找到需要颠倒的节点。所以我们不妨换一个想法,从链表的next域下手。很容易想到,如果我们将每个节点的next域都指向它的前驱而不是后继,就可实现调转。我们不妨具体举例说明。

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

假设前两个节点已经完成倒转,那么链表就可以表示成:

  1<-2 
  3->4->5

可以看出,链表变为了两部分。这时我们需要一个指针记录3的当前后继(也就是4),以完成后续遍历,之后将3的next域指向2,并记录3的位置(以便4指向3),即可完成前3个节点的倒转。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 11,395评论 0 13
  • 一.线性表 定义:零个或者多个元素的有限序列。也就是说它得满足以下几个条件:  ①该序列的数据元素是有限的。  ②...
    Geeks_Liu阅读 7,568评论 1 12
  • 搞懂单链表常见面试题 Hello 继上次的 搞懂基本排序算法,这个一星期,我总结了,我所学习和思考的单链表基础知识...
    醒着的码者阅读 10,065评论 1 45
  • 新的课程 如果不留下点痕迹 怎么证明来过
    车百阅读 2,880评论 0 0
  • 作者:迈克尔·伊斯特伍德 出版社:发现号角 翻译:善迦叶子 购买此书英文原版请点击:Crystal Over...
    玄月之佑阅读 9,621评论 0 6