两种链表操作--链表反转、链表排序(pyhon实现)

链表反转和链表排序是两种链表的基本操作,在python里list类型的reverse()方法就是对list的反转,sort()方法可以对list的元素进行排序,本文将探讨这两种链表操作基于单链表的实现方式。

 

链表反转

对于单链表而言,链表反转可以有两种实现方式,一种是在节点之间搬动元素,即往复地将尾部元素搬到头部;另一种是修改节点的连接关系,通过改变节点的连接顺序来改表元素的顺序。但是单链表不支持从尾部向前查找元素,如果采用搬动元素的方法,则效率很低(O(n^{}2))。因此考虑第二种实现方式。注意到在链表头部插入节点或删除节点花费的时间都是O(1),如果不断从链表的头部取下节点,插入到另一个链表的头部,这样最后得到的就是反转后的链表,并且这是一个高效的操作,花费时间为O(n)。

    def rev(self):
        p=None
        while self._head is not None:
            q=self._head
            self._head=q.next    #取下原来的首节点
            q.next=p
            p=q                  #将刚取下的节点加入p引用的节点序列
        self._head=p             #反转后的节点序列已经做好,重置表头连接

在实际生活中也经常能见到类似的过程,如通过调度把一列火车车厢的顺序顛倒过来。另外,如果桌上有一摞书,一本本拿下来放到另一处,叠成另一摞,也是这个操作的实例。 

 

链表排序

排序算法有很多种,本结主要讨论基于插入排序的链表排序,插入排序的原理大家可以自行查找,这里不再赘述。主要实现有两种方式:1.基于移动元素的链表排序,2.基于调整链表的链表排序。

  • 基于移动元素的链表排序

如图a)所示,在第i个节点d之前的链表节点元素都是已排序的,现在要将d插入前面的有序序列中。采用移动元素的方法,从头结点开始扫描该有序序列直到找到第一个大于d的节点位置,记为j。然后将j及j之后的元素依次后移,最后将d插入到j的位置。如此循环取出链表的元素做此操作,即可完成链表的排序。

 

#基于移动元素的链表排序
    def sort1(self):
        if self._head is None:
            return
        crt=self._head.next #从头结点之后开始处理
        while crt is not None:
            x=crt.elem
            p=self._head
            while p is not crt and p.elem<=x:   #跳过小于它的元素
                p=p.next
            while p is not crt: #找到插入的位置,插入并且大于它的元素后移
                y=p.elem
                p.elem=x
                x=y
                p=p.next
            crt.elem=x
            crt=crt.next
  • 基于调整链表的链表排序

这种方法的操作过程比较好理解,就是一个个取下链表结点,将其插人一段元素递增的结点链中的正确位置。

#基于调整链表的链表排序
    def sort2(self):
        p=self._head
        if p is None or p.next is None: #链表为空或只有一个节点,不需要排序
            return
        rem=p.next
        p.next=None
        while rem is not None:
            p=self._head
            q=None
            while p is not None and p.elem<=rem.elem:
                q=p
                p=p.next        #寻找插入位置
            if q is None:
                self._head=rem  #rem是最小的,头部插入
            else:
                q.next=rem #q和p中间插入
            q=rem
            rem=rem.next
            q.next=p

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值