Python实现排序(冒泡、快排、归并)

  Thomas H.Cormen 的《算法导论》上介绍的几个经典排序算法的Python实现。

1、冒泡排序:

  简单的两重循环遍历,使最小(最大)的值不断地往上升(下沉)而实现的排序,算法时间为O(n2)。

  代码如下:

  

 1 def up_sort(a):
 2         # 冒泡排序
 3
 4         a_length = len(a)
 5         while True:
 6                 i = 0
 7                 j = 1
 8
 9                 while True:
10                         if a[i] > a[j]:
11                                 a[i], a[j] = a[j], a[i]
12                                 i += 1
13                                 j = i+1
14                         else:
15                             i += 1
16                             j = i+1
17                         if j >= a_length:
18                                 break
19                 a_length -= 1
20                 if a_length == 1:
21                         break

2、快速排序

  快排是一种使用较多的一种排序算法,对于包含n个数输入数组,最坏情况运行时间为Θ(n2),期望运行时间为Θ(nlgn),而且常数因子较小,不容易出现最坏情况,所以快排常是进行排序的最佳选择。

  其主要包括三个步骤(对子数组A[p...r]):

  分解:数组A[p...r]被划分成两个子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的元素都小于等于A[q],而A[q+1..r]中的都大于A[q]

  解决:通过递归调用快排,对数组A[p..q-1]和A[q+1..r]进行排序

  合并:因为两个子数组是就地排序的,将他们的合并不需要操作:整个数组A[p..r]已排序

代码如下:

  为排序一个完整的数组A,需调用quicksort(A,0,len[A]-1),partition()函数就是对子数组进行就地重排.

def partition(a, p, r):
    x = a[r]
    i = p-1
    for j in range(p, r-1):
        if a[j] <= x:

           i += 1
           a[i], a[j] = a[j], a[i]
    a[i+1], a[r] = a[r], a[i+1]
    return i+1

def quicksort(a, p, r):
    ‘快排‘
    if p < r:
        q = partition(a, p, r)
        quicksort(a, p, q-1)
        quicksort(a, q+1, r)
        # print a

3、归并排序

  归并排序是利用的分治的思想,讲一个要解决的问题划分为多个子问题,分别对每个子问题进行求解,算法直观的操作如下:

  分解:将n个元素分解成各含n/2个元素的子序列;

  解决:用合并排序法对两个子序列递归的排序

  合并:合并两个已排序的子序列得到排序结果

代码如下:

归并排序的时间复杂度为Θ(nlgn)

 1 def merge_sort(a, p, r):
 2     ‘归并排序‘
 3     if p < r:
 4         q = (p+r)//2
 5         merge_sort(a, p, q)
 6         merge_sort(a, q+1, r)
 7
 8         merge(a, p, q, r)
 9
10
11 def merge(a, p, q, r):
12     n1 = q - p + 1
13     n2 = r - q
14     left = []
15     right = []
16     for i1 in range(0, n1):
17         left.append(a[p+i1])
18     for j1 in range(0, n2):
19         right.append(a[q+j1+1])
20
21     left.append(float(‘inf‘))
22     right.append(float(‘inf‘))
23     i = 0
24     j = 0
25     for k in range(p, r+1):
26         if left[i] <= right[j]:
27             a[k] = left[i]
28             i += 1
29         else:
30             a[k] = right[j]
31             j += 1

4、完整代码:

  包括实验的测试代码如下:

  1 # -*- coding: utf-8 -*-
  2
  3 # !/usr/bin/env python
  4
  5
  6 __author__ = ‘you‘
  7
  8 import random
  9 import time
 10
 11
 12 def up_sort(a):
 13         # 冒泡排序
 14
 15         a_length = len(a)
 16         while True:
 17                 i = 0
 18                 j = 1
 19
 20                 while True:
 21                         if a[i] > a[j]:
 22                                 a[i], a[j] = a[j], a[i]
 23                                 i += 1
 24                                 j = i+1
 25                         else:
 26                             i += 1
 27                             j = i+1
 28                         if j >= a_length:
 29                                 break
 30                 a_length -= 1
 31                 if a_length == 1:
 32                         # print a
 33                         break
 34
 35
 36 def partition(a, p, r):
 37     x = a[r]
 38     i = p-1
 39     for j in range(p, r-1):
 40         if a[j] <= x:
 41
 42            i += 1
 43            a[i], a[j] = a[j], a[i]
 44     a[i+1], a[r] = a[r], a[i+1]
 45     return i+1
 46
 47
 48 def quicksort(a, p, r):
 49     ‘快排‘
 50     if p < r:
 51         q = partition(a, p, r)
 52         quicksort(a, p, q-1)
 53         quicksort(a, q+1, r)
 54         # print a
 55
 56
 57 def merge(a, p, q, r):
 58     n1 = q - p + 1
 59     n2 = r - q
 60     left = []
 61     right = []
 62     for i1 in range(0, n1):
 63         left.append(a[p+i1])
 64     for j1 in range(0, n2):
 65         right.append(a[q+j1+1])
 66
 67     left.append(float(‘inf‘))
 68     right.append(float(‘inf‘))
 69     i = 0
 70     j = 0
 71     for k in range(p, r+1):
 72         if left[i] <= right[j]:
 73             a[k] = left[i]
 74             i += 1
 75         else:
 76             a[k] = right[j]
 77             j += 1
 78
 79
 80 def merge_sort(a, p, r):
 81     ‘归并排序‘
 82     if p < r:
 83         q = (p+r)//2
 84         merge_sort(a, p, q)
 85         merge_sort(a, q+1, r)
 86
 87         merge(a, p, q, r)
 88         # print a
 89
 90
 91 if __name__ == ‘__main__‘:
 92         in_len = int(raw_input(‘输入排序个数:‘))
 93         begin_num = int(raw_input(‘输入随机产生序列的范围:‘))
 94         end_num = int(raw_input())
 95
 96         A = []
 97         for i in range(0, in_len):
 98             A.append(random.randrange(begin_num, end_num))
 99             # print(A)
100         while True:
101             print ‘-‘*10+‘算法性能比较‘+‘-‘*10
102             print ‘‘‘
103             1、冒泡排序
104             2、快排
105             3、归并排序
106             0、退出
107             ‘‘‘
108             print ‘-‘*30
109             select=int(raw_input(‘输入选择‘))
110             if select == 1:
111                 begin_time=time.time()
112
113
114                 up_sort(A)
115                 # print A
116                 end_time=time.time()
117             elif select == 0:
118                 break
119             elif select == 2:
120                 begin_time=time.time()
121                 quicksort(A, 0, len(A)-1)
122                 end_time=time.time()
123             else:
124                 begin_time=time.time()
125                 merge_sort(A, 0, len(A)-1)
126                 end_time=time.time()
127             print ‘该算法的耗时为:‘+str((end_time-begin_time)*1000)+‘ms‘

完整代码

时间: 2024-10-10 05:03:41

Python实现排序(冒泡、快排、归并)的相关文章

算法总结——三大排序(快排,计数排序,归并)

快排: 适用条件:方便...只要数字不是很多 复杂度:O(nlogn)  每一层n复杂度,共logn层 原理:利用一个随机数与最后面一个数交换,那么这个随机数就到了最后一位,然后循环,如果前面的数大于最后一个数,那么把这个数放到前面去,经过一次排序之后,前面的数都是大于最后一个的,然后对1到k和k+1到n进行排序,一层一层地下去 模板: #include<cstdio> #include<algorithm> #include<time.h> using namespa

排序 之 快排and归并&lt;时间复杂度&gt;----掌握思想和过程

俗话说:天下武功无坚不破,唯快不破.对于算法当然也是要使用时间最短.占用空间最小的算法来实现了. 注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或者把代码改一下输出每次排序后的结果. 总之,师傅领进门,修行在个人.奋斗把!骚年! ※冒泡排序.选择排序:(不稳定,时间复杂度 O(n^2)) 1 #include "cstdio" 2 #include "iostream" 3 using namespace std

单链表的排序(快排和冒泡实现)以及查找中间结点

//快排,冒泡链表排序 #include<iostream> #include<assert.h> using namespace std; template<class T> struct LinkNode { T _data; LinkNode* _next; LinkNode(const T& x) :_data(x) , _next(NULL) {} }; template<class T> class ListNode { //为了安全性

排序 折半,冒泡 快排

折半插入排序: /*********************************************** 折半插入排序 ***********************************************/ #include<stdio.h> #include<string.h> #include<math.h> #include<ctype.h> #include<stdbool.h> #include<stdlib.h

三种排序:快排,归并,堆排

转自:http://www.cnblogs.com/LUO77/p/5798149.html (一)快排 快排考的是最多次的.之前看大神写的算法很简单,思想也很好.就一直用他的思想去思考快排了.挖坑法. 拿走第一个元素作为标兵元素,即挖坑,然后从后面找一个比它小的填坑,然后又形成一个坑,再从前面找一个比标兵大的填坑,又形成一个坑.……最后一个坑填入标兵就好. 然后就是递归了.再在标兵左边排序,右边排序. 1 void QSort(int* num, int start, int end) { 2

排序--QuickSort 快排

Quick の implementation 快排,就像它的名字一定,风一样的快.基本上算是最快的排序算法了.快排的基本思想是选择一个切分的元素.把这个元素排序了.所有这个元素左边的元素都小于这个元素,所有这个元素右边的元素都大于这个元素.接着再把左右2个数组分别排序. 假设你有如下数组 (所有 i  左边的对象都小于 切分对象. 所有 j  右边的对象都大于切分对象 这句话稍后有用 先知道一下) 首先,我们把index = 0 的元素当作切分元素. 从index = 1 的位置开始,找到第一个

NYOJ 8 一种排序【快排】

三级快排,注意题意要求就可以了. 一种排序 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数:现在要求按照一下方式排序(默认排序规则都是从小到大): 1.按照编号从小到大排序 2.对于编号相等的长方形,按照长方形的长排序: 3.如果编号和长都相同,按照长方形的宽排序: 4.如果编号.长.宽都相同,就只保留一个长方形用于排序,删除多余的长方形:最后排好序按照指定

普林斯顿大学算法课 Algorithm Part I Week 3 重复元素排序 - 三路快排 Duplicate Keys

很多时候排序是为了对数据进行归类,这种排序重复值特别多 通过年龄统计人口 删除邮件列表里的重复邮件 通过大学对求职者进行排序 若使用普通的快排对重复数据进行排序,会造成N^2复杂度,但是归并排序和三路快排就没有这样的问题. 归并排序对重复数据排序的比较在1/2NlgN和NlgN之间 三路快排 目标:将数据分成三个区间(3-way partitioning) lt和gt区间内的元素都和比较元素v相等 lt左边的元素都比v小 gt右边的元素都比v大 性能 三路快排的复杂度比普通快排小,主要取决于数据

排序算法——快排思想

快速排序 1.思想 快速排序将一个数组分成两个数组,再对两个数组独立排序,是个递归算法. 首先随机选出一个切分元素temp(一般为这个数组的第一个元素),将小于temp的数放在temp的左边,将大于temp的数放在temp的右边. 快排和堆排序很像,他们都是将一个数组分成两个子数组,都属于递归算法.但是不同之处在于:快排空间复杂度为o(1),而堆排为o(n), 快排是原地排序,只需要一个很小的辅助栈,时间复杂度为NlogN. 2.代码实现(java) public class Quick {  

排序之快排(JS)

快速排序(Quicksort)是对冒泡排序的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 详细描述:首先在要排序的序列 a 中选取一个中轴值,而后将序列分成两个部分,其中左边的部分 b 中的元素均小于或者等于 中轴值,右边的部分 c 的元素 均大于或者等于中轴值,而后通过递归调用快速排序的过程分别对两个部分进行排序