递归实现快速排序,冒泡排序(Bubble Sort)和快速排序(Quick Sort)

我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序。

  排序算法大体可分为两种:

    一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。

    另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序基数排序桶排序等。

这里主要写比较排序的两种,也是用Python实现的,当然,其他语言也可实现。

一、冒泡排序

冒泡排序可以说是最为稳定的一种排序,不止排序稳定,他的时间复杂度也更是稳定.....

冒泡排序是一种极其简单的排序算法,也是我所学的第一个排序算法。它重复地走访过要排序的元素,依次比较相邻两个元素,如果他们的顺序错误就把他们调换过来,直到没有元素再需要交换,排序完成。这个算法的名字由来是因为越小(或越大)的元素会经由交换慢慢“浮”到数列的顶端。

  冒泡排序算法的运作如下:

  1. 比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

比如有五个数: 12, 5, 9, 8, 6, 从小到大排序, 对相邻的两位进行比较

  • 第一趟:
  • 第一次比较: 5, 12, 9, 8, 6
  • 第二次比较: 5, 9, 12, 8, 6
  • 第三次比较: 5, 9, 8, 12, 6
  • 第四次比较: 5, 9, 8, 6, 12

经过第一趟比较后, 五个数中最大的数已经在最后面了, 接下来只比较前四个数, 依次类推

  • 第二趟
    5,  8,  9,  6, 12
  • 第三趟
    5,  8,  6,  9, 12
  • 第四趟
    5,  6,  8,  9,12
    比较完成

 代码如下:

#!/usr/bin/env python
# coding:utf-8

def bubbleSort(nums):
    for i in range(len(nums)-1):    # 这个循环负责设置冒泡排序进行的次数
        for j in range(len(nums)-i-1):  # j为列表下标
            if nums[j] > nums[j+1]:
                nums[j], nums[j+1] = nums[j+1], nums[j]
    return nums

nums = [12,5,9,8,6]

print bubbleSort(nums)

冒泡排序缺点也很明显,效率太低,而快速排序则进一步优化了这种排序方法。

二、快速排序(quick sort)

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序n个元素要O(nlogn)次比较。在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他O(nlogn)算法更快,因为它的内部循环可以在大部分的架构上很有效率地被实现出来。

  快速排序使用分治策略(Divide and Conquer)来把一个序列分为两个子序列。步骤为:

  1. 从序列中挑出一个元素,作为"基准"(pivot).
  2. 把所有比基准值小的元素放在基准前面,所有比基准值大的元素放在基准的后面(相同的数可以到任一边),这个称为分区(partition)操作。
  3. 对每个分区递归地进行步骤1~2,递归的结束条件是序列的大小是0或1,这时整体已经被排好序了。

  快速排序的代码如下:

# quick sort
def qsort(arr):
    if not len(arr):
        return []
    else:
    # 在这里以第一个元素为基准线
        pivot = arr[0]
        left = qsort([x for x in arr[1:] if x < pivot])
        right = qsort([x for x in arr[1:] if x >= pivot])
    return left+[pivot]+right
arr=[4,2,7,2,45,2,87,2,0,3,7,9,45]
print(b_sort(arr))

快速排序相对时间复杂度要低,但是他是不稳地的,例如L[4,4,3]结果两个4会调换位置,这也是在选择排序方法时需要考虑的。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值