美文网首页程序员Python
python算法-003单链表逆序插入法

python算法-003单链表逆序插入法

作者: DKider | 来源:发表于2019-03-01 21:17 被阅读65次

被压抑的情感并不会消失,累积到一定程度后,反而以更丑恶的方式爆发出来,有些精神病就是这样造成的。若是一味压抑,不能把愤懑的情绪加以升华,自我评价将日趋低落。——《高效能人士的七个习惯》

这段话告诉我们,心里有事一定要说出来,找人倾诉,或者写出来。或者是bug出多了,会被气炸,甚至砸了这破电脑……我们还是努力学习吧!


题目:给定一个带头节点的单链表:head->1->2->3->4->5->6->7->8;使其成为:head->8->7->6->5->4->3->2->1。


今天的题目还是将单链表逆序,前面已经写过两种方法了,一篇就地逆序法,一篇递归法。就地逆序法是将遍历到的节点逆序,需要将整个链表遍历一遍,时间复杂度为O(n),需要常数个额外变量来保存当前节点的前驱节点和后继节点,因此空间复杂度为O(1)。

递归法在性能上要比就地逆序法差一点。其优点是思路直观,很容易理解;但是其缺点就是实现起来要难一点,还有一点就是Python支持的递归深度为默认是 1000,在昨天的代码中,我将链表的长度加到998就是极限了,会报出下面图中的错误。

递归溢出
经过查找资料,这是python专门设置的一种机制用来防止无限递归造成Python溢出崩溃,默认深度是可以改的
import sys
sys.setrecursionlimit(1500) # 这是将递归深度改为1500

好的,今天的方法是插入法。
插入法的主要思路是,从链表的第二个节点开始遍历,将遍历到的当前节点插入到头节点的后面,直到遍历完所有节点。即原链表为head->1->2->3->4->5->6->7->8,从2开始遍历,将其插入1前面,也就是头节点后面:head->2->1->3->4->5->6->7->8,然后遍历到3,同理将其插入到头节点后面。当所有节点都插入头节点head后面,就可以实现链表的逆序。

我们要逆序链表当然得现有一个链表,链表的构造方法我在昨天文章写了,看不懂可以看看—— python算法-002单链表逆序递归法 ,下面代码实现:

#先构造节点对象
class LNode:
    """
    定义链表对象
    """
    def __init__(self, x):
        self.data = x
        self.next = None
#构造链表函数
def creatLink(x):
    i = 1
    head = LNode(None)
    tmp = None
    cur = head
    while i <= x:
        tmp = LNode(i)
        cur.next = tmp
        cur = tmp
        i += 1

链表有了,接下来就是实现算法:

def Reverse(head):
    '''
    带头节点
    输入: 链表
    输出: 逆序后的链表
    '''
    #先判断链表是否为空或这只有一个元素,是则返回
    if head is None or head.next is None:
        return head
    cur = None # 用来遍历链表
    next = None # 用来指向当前节点的后继节点
    cur = head.next.next # 从链表的第二个节点开始遍历
    head.next.next= None # 断开第一个节点与第二个节点。
    # 注意这里是重点!一定要断开,因为不断开的话,在下一步中
    # 第二个节点的next域为第一个节点,但是第一个节点的next域为第二个节
    # 点,这就成了一个最小的环,那么后面的程序就进入了死循环
    while cur is not None:
        next=cur.next # next用来保存cur的后继节点,不然会丢失后面的节点
        cur.next=head.next # 将当前遍历的节点插入到头节点之后
        head.next = cur #这里的两步实现的“插入”,细细体会
        cur = next # 遍历下一个节点
    return head

算法到这里就写完了,下面我们来试一试这个算法:

if __name__=='__main__':
    # 构造链表
    head=creatLink(8)
    #打印逆序前的链表
    print("BeforeReverse:")
    cur = head.next
    while cur != None:
        print(cur.data)
        cur = cur.next
    print("\nAfterReverse:")
    #调用逆序函数
    head=Reverse(head)
    #打印逆序后的链表
    cur = head.next
    while cur != None:
        print(cur.data)
        cur = cur.next

这是运行成果:

程序运行结果
给一下全部的代码:
#先构造节点对象
class LNode:
    """
    定义链表对象
    """
    def __init__(self, x):
        self.data = x
        self.next = None

#构造链表函数
def creatLink(x):
    i = 1
    head = LNode(None)
    tmp = None
    cur = head
    while i <= x:
        tmp = LNode(i)
        cur.next = tmp
        cur = tmp
        i += 1

def Reverse(head):
    '''
    带头节点
    输入: 链表
    输出: 逆序后的链表
    '''
    #先判断链表是否为空或这只有一个元素,是则返回
    if head is None or head.next is None:
        return head
    cur = None # 用来遍历链表
    next = None # 用来指向当前节点的后继节点
    cur = head.next.next # 从链表的第二个节点开始遍历
    head.next.next= None # 断开第一个节点与第二个节点。
    # 注意这里是重点!一定要断开,因为不断开的话,在下一步中
    # 第二个节点的next域为第一个节点,但是第一个节点的next域为第二个节
    # 点,这就成了一个最小的环,那么后面的程序就进入了死循环
    while cur is not None:
        next=cur.next # next用来保存cur的后继节点,不然会丢失后面的节点
        cur.next=head.next # 将当前遍历的节点插入到头节点之后
        head.next = cur #这里的两步实现的“插入”,细细体会
        cur = next # 遍历下一个节点
    return head

if __name__=='__main__':
    # 构造链表
    head=creatLink(8)
    #打印逆序前的链表
    print("BeforeReverse:")
    cur = head.next
    while cur != None:
        print(cur.data)
        cur = cur.next
    print("\nAfterReverse:")
    #调用逆序函数
    head=Reverse(head)
    #打印逆序后的链表
    cur = head.next
    while cur != None:
        print(cur.data)
        cur = cur.next

好了,今天的算法是对有头节点的链表写的,不带头节点的你会吗?欢迎来讨论,在我的github上也有代码,你可以对照一下,亦可以将你的代码发我给我、私信我,也可以关注我自己的公众号:DKider 来联系我。
我们一起加油吧!

力学如力耕,勤惰尔自知。但使书种多,会有岁稔时。——宋 刘过《书院》

相关文章

  • python算法-003单链表逆序插入法

    被压抑的情感并不会消失,累积到一定程度后,反而以更丑恶的方式爆发出来,有些精神病就是这样造成的。若是一味压抑,不能...

  • LeetCode 2. Add Two Numbers

    单链表逆序相加

  • python算法-002单链表逆序递归法

    上一篇文章也讲的单链表的逆序,但我没有详细的将过程写出来。这让读者不能够更加快速的理解我写的代码的原理,是我的疏忽...

  • Leetcode-Medium-2 Add Two Number

    题目 思路 给定两哥数字非负的单链表,每条单链表逆序存储着一个数字。将两条单链表存储的数字相加,并逆序放入单链表中...

  • 逆序单链表

    1、对一个单链表进行逆序操作。逆序之前为 head-->A-->B-->C-->None逆序之后为 head-->...

  • 单链表逆序

    1.创建链表结构 2.新建节点 3.打印函数 4.main函数实现 5.打印结果

  • 2.单链表

    该部分包含以下内容-单链表的增删改查-计算链表长度-逆序链表-寻找(删除)链表倒数第K个元素-逆序打印链表(使用栈)

  • 算法学习-单链表反转

    单链表的反转是一道很基本的算法题,一般可以想到以下三种方法: 方法1:将单链表储存为数组,然后按照数组的索引逆序进...

  • leetcode 单链表的各种算法

    1 递归实现:合并两个有序的单链表 2 递归实现:单链表逆序存入vector 3 循环实现:快慢指针找到单链表中间...

  • swift 实现单链表创建、插入、删除

    初始化单链表创建结点: 调用方法执行 头插入法结果输出:0,20,12,5,3 尾插入法结果输出:0,3,5,12...

网友评论

    本文标题:python算法-003单链表逆序插入法

    本文链接:https://www.haomeiwen.com/subject/jxujuqtx.html