快速排序(python)

一、前言

1.1、基本思想

快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

1.2、算法步骤

  1. 选择基准:在待排序列中,按照某种方式挑出一个元素,作为 “基准”(pivot);
  2. 分割操作:以该基准在序列中的实际位置,把序列分成两个子序列。此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大;
  3. 递归操作:递归地对两个序列进行快速排序,直到序列为空或者只有一个元素。

1.3、选择基准的方式

对于分治算法,当每次划分时,算法若都能分成两个等长的子序列时,那么分治算法效率会达到最大。也就是说,基准的选择是很重要的。选择基准的方式决定了两个分割后两个子序列的长度,进而对整个算法的效率产生决定性影响。
最理想的方法是,选择的基准恰好能把待排序序列分成两个等长的子序列,

下面介绍三种实现方式:

  1. 分割交换排序:取序列的第一个或最后一个元素作为基准;
  2. 随机排序:取待排序列中任意一个元素作为基准;
  3. 中位数排序:对待排序序列中low、mid、high三个位置上数据进行排序,取他们中间的那个数据作为枢轴,并用0下标元素存储枢轴。

二、算法实现

2.1.分割交换排序

代码

# 分割交换排序:取序列的第一个或最后一个元素作为基准;
import random
import datetime

def random_int_list(start, stop, length):
  start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
  length = int(abs(length)) if length else 0
  random_list = []
  for i in range(length):
      random_list.append(random.randint(start, stop))
  return random_list

def partition(li, left, right):
    """
    归位函数
    """
    tmp = li[left]  # 先把最左侧的数拿出来,然后开始查找其该在的位置
    while left < right:
        while left < right and li[right] >= tmp:  # 如果降序排列修改li[right] <= tmp
            right -= 1  # 从右边找比基准小的数,填充到基准的位置
        li[left] = li[right]
        while left < right and li[left] <= tmp:  # 如果降序排列修改li[right] >= tmp
            left += 1  # 从左边找比基准大的数字放在右边的空位
        li[right] = li[left]
    li[left] = tmp  # 当跳出循环条件的时候说明找到了,并且把拿出来的基准在放进去
    return left


def quick_sort(li, left, right):
    # 快速排序的两个关键点:归位,递归
    if left < right:  # 至少有两个元素,才能进行递归
        mid = partition(li, left, right)  # 找到归位的位置
        quick_sort(li, left, mid - 1)  # 递归,右边的-1
        quick_sort(li, mid + 1, right)  # 递归,左边的+1


def sort(li):
    return quick_sort(li, 0, len(li) - 1)

if __name__ == '__main__':

    li=random_int_list(1,100000,100)
    print("initial array:\n",li)
    oldtime=datetime.datetime.now()
    sort(li)
    newtime=datetime.datetime.now()
    print("result array:\n",li)
    print(u'运算时间为:%s微秒'%(newtime-oldtime).microseconds)

测试数据

测试数据量时间
100116微秒
500731微秒
10001623微秒
20003760微秒
30005928微秒
40008203微秒
500010299微秒
100000345600微秒
200000704385微秒

2.2.随机排序

代码

import random
import datetime

def random_int_list(start, stop, length):
  start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
  length = int(abs(length)) if length else 0
  random_list = []
  for i in range(length):
      random_list.append(random.randint(start, stop))
  return random_list

def quicksort(arr,firstIndex, lastIndex):
    if firstIndex<lastIndex:
        divIndex=random_partition(arr,firstIndex, lastIndex)
        quicksort(arr,firstIndex,divIndex)
        quicksort(arr,divIndex+1, lastIndex)
    else:
        return

def partition(arr, firstIndex, lastIndex):
    i =firstIndex-1
    for j in range(firstIndex, lastIndex):
        if arr[j]<=arr[lastIndex]:
            i=i+1
            arr[i],arr[j]=arr[j],arr[i]
    arr[i+1],arr[lastIndex]=arr[lastIndex],arr[i+1]
    return i

def random_partition(arr,firstIndex, lastIndex):
    i=random.randint(firstIndex,lastIndex)
    arr[i],arr[lastIndex]=arr[lastIndex],arr[i]
    return partition(arr,firstIndex,lastIndex)

if __name__ == '__main__':
    arr=random_int_list(1,100000,100)
    print("initial array:\n",arr)
    oldtime=datetime.datetime.now()
    quicksort(arr,0,len(arr)-1)
    newtime=datetime.datetime.now()
    print("result array:\n",arr)
    print(u'运算时间为:%s微秒'%(newtime-oldtime).microseconds)

测试数据

测试数据量时间
100433微秒
5002284微秒
10004649微秒
20009987微秒
300015336微秒
400020443微秒
500031395微秒
100000611790微秒
200000484507微秒

3.3.中位数排序

代码

# 中位数排序:对待排序序列中low、mid、high三个位置上数据进行排序,取他们中间的那个数据作为枢轴,并用0下标元素存储枢轴。
import random
import datetime

def random_int_list(start, stop, length):
  start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
  length = int(abs(length)) if length else 0
  random_list = []
  for i in range(length):
      random_list.append(random.randint(start, stop))
  return random_list

def quicksort(arr):
	if not arr:
		return []
	else:
		lst=[arr[0],arr[-1],arr[len(arr)//2]]
        # 返回重新排序的列表。
		div=sorted(lst)[1]
		index=arr.index(div)
		left=quicksort([l for l in (arr[:index]+arr[index+1:]) if l<=div])
		right=quicksort([r for r in (arr[:index]+arr[index+1:]) if r>div])
		return left+[div]+right

if __name__ == '__main__':
    arr=random_int_list(1,100000,100000)
    print("initial array:\n",arr)
    oldtime=datetime.datetime.now()
    print("result array:\n",quicksort(arr))
    newtime=datetime.datetime.now()
    print(u'运算时间为:%s微秒'%(newtime-oldtime).microseconds)

测试数据

测试数据量时间
100257微秒
5001262微秒
10002693微秒
20005659微秒
30008849微秒
400013815微秒
500014782微秒
100000409379微秒
200000136135微秒
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
快速排序是一种基于分治思想的排序算法,它通过选择一个基准元素,将数组分为两部分,并使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。然后递归地对左右两部分进行排序,最终得到一个有序数组。 以下是Python实现快速排序的代码: ```python def quick_sort(array, start, end): if start >= end: return mid_data, left, right = array[start], start, end while left < right: while array[right >= mid_data and left < right: right -= 1 array[left = array[right] while array[left < mid_data and left < right: left += 1 array[right = array[left] array[left = mid_data quick_sort(array, start, left-1) quick_sort(array, left+1, end) if __name__ == '__main__': array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] quick_sort(array, 0, len(array)-1) print(array) ``` 快速排序的实现步骤如下: 1. 在数列中选择一个元素作为基准(pivot)。 2. 将数列中所有元素与基准进行比较,把比基准小的元素放在基准的左边,比基准大的元素放在基准的右边。 3. 以基准值左右两边的子列作为新数列,不断重复步骤1和步骤2,直到所有子集只剩下一个元素为止。 快速排序的优点是在处理大数据集时效果比较好,因为它采用了分治思想,可以充分利用计算资源。然而,快速排序在小数据集上的性能较差,因为交换元素的开销较大。另外,当选择的基准元素不合适或者数据已经有序时,快速排序的性能可能会变差。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值