python 单向链表实现快速排序

快速排序的基本思想:
从序列当中选择一个基准数
在这里我们选择序列当中第一个数作为基准数
将序列当中的所有数依次遍历,比基准数大的位于其右侧,比基准数小的位于其左侧
重复步骤1.2,直到所有子集当中只有一个元素为止。
 

以【4,2,5,3,7,9,0,1】为例,我们来模拟一趟快排的过程。

1、初始化时,i指向链表首元素4;j = i +1,指向2。基准数字为当前i 指向的数字:4。

j
42537901
i

 

2、随后开始循环,j 当前指向2,因为2小于4,所以要把2移动到前面去。按照我们的算法步骤操作:

  • i ++,首先 i 向后移动一位,指向2
  • swap(i, j) ,随后交换 i、j 位置的值,这里面是2和2自己交换
  • j ++,然后 j 向后移动一位,指向5

执行一次交换后的结果如下:

j
42537901
i

 

3、接下来,由于 j 指向的值5 大于4,直接跳过,执行j++,此时 j 指向3

j
42537901
i

 

4、 j 指向的值为3,小于4,仿照步骤2,我们再次执行一次交换移动过程。

  • i ++,首先 i 向后移动一位,指向5
  • swap(i, j) ,随后交换 i、j 位置的值,这里面是5和3交换
  • j ++,然后 j 向后移动一位,指向7

交换后的结果如下:

j
42357901
i

 

5、 j指向的值为7,大于4,所以直接跳过,执行 j++,j 指向9

j
42357901
i

 

6、同理,j 指向的值为9,也大于4,跳过,执行 j++,j 指向0

j
42357901
i

 

7、 j 指向的值为0,小于4,执行一次交换过程

  • i ++,首先 i 向后移动一位,指向5
  • swap(i, j) ,随后交换 i、j 位置的值,这里面是5和0交换
  • j ++,然后 j 向后移动一位,指向1

交换后的结果如下:

j
42307951
i

 

8、 j 指向的值为1,小于4,我们再执行一次交换过程

  • i ++,首先 i 向后移动一位,指向7
  • swap(i, j) ,随后交换 i、j 位置的值,这里面是7和1交换
  • j ++,然后 j 向后移动一位,已经超过了链表的长度,不再向后移动。

交换后的结果如下:

j
42301957
i

 

9、最后,交换当前 i指向的值1,和4。得到【1、2、3、0、4、9、5、7】,一趟排序结束。

j
12304957
i

我们发现,4的左边都是小于4的数字,右边都是大于4的数字。
接下来,对左边和右边分别排序,不断递归下去,直到元素全部有序。
 

// 链表结点类
class Node():  
    def __init__(self, item=None):
        self.item = item  // 数据域
        self.next = None  // 指针域


// 链表类,生成链表以及定义相关方法
class LinkList():
    def __init__(self):
        self.head = None
        
    // 生成链表,这里使用list来生成
    def create(self, item):
        self.head = Node(item[0])
        p = self.head
        for i in item[1:]:
            p.next = Node(i)
            p = p.next

    // 遍历显示
    def print(self):
        p = self.head
        while p != None:
            print(p.item, end=' ')
            p = p.next
        print()

    // 根据索引取值
    def getItem(self, index):
        p = self.head
        count = 0
        while count != index:
            p = p.next
            count += 1
        return p.item

    // 根据索引设值
    def setItem(self, index, item):
        p = self.head
        count = -1
        while count < index-1:
            p = p.next
            count += 1
        p.item = item

    // 互换
    def swapItem(self, i, j):
        t = self.getItem(j)
        self.setItem(j, self.getItem(i))
        self.setItem(i, t)

    def quicksortofloop(self, left, right):
        if left < right:
    		// 初始化
            i = left
            j = i+1
            start = self.getItem(i)

        	// 大循环条件,j不能超过链表长度
            while (j <= right):
        		// 如果 j 指向的值大于等于基准数字,直接跳过
                while (j <= right and self.getItem(j) >= start):
                    j += 1
        	    // 否则,j 指向的值小于基准,则交换
                if (j <= right):
                    i += 1
                    self.swapItem(i, j)
                    self.print()
                    j += 1
            self.swapItem(left, i)
            self.quicksortofloop(left, i-1)
            self.quicksortofloop(i+1, right)


if __name__ == "__main__":
    L = LinkList()
    L.create([4, 2, 5, 3, 7, 9, 0, 1])
    L.quicksortofloop(0, 7)
    L.print()

4 2 5 3 7 9 0 1
4 2 3 5 7 9 0 1
4 2 3 0 7 9 5 1
4 2 3 0 1 9 5 7
1 0 3 2 4 9 5 7
0 1 3 2 4 9 5 7
0 1 2 3 4 9 5 7
0 1 2 3 4 9 5 7
0 1 2 3 4 7 5 9
0 1 2 3 4 5 7 9

参考:https://www.cnblogs.com/wuxinyan/p/8615127.html
参考:https://blog.csdn.net/u010429424/article/details/77776731

  • 18
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值