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、完整代码:

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

Python实现排序(冒泡、快排、归并)
  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'
完整代码

 

你可能感兴趣的:(python)