【算法与数据结构】--经典排序算法Python实现

2020.6.25 周四更新

冒泡排序、选择排序、插入排序、希尔交换式排序、希尔移位式排序

持续更新

------------------

下面是以上排序的Python代码:

  1 import numpy as np
  2 import time
  3 
  4 class Sort:
  5     def __init__(self, arr):
  6         self.arr = arr
  7 
  8     def bubblesort(self):
  9         # 冒泡排序
 10         count = 0
 11         flag = False  # 优化冒泡排序,当一次循环没有任何交换时就退出
 12         for i in range(len(self.arr)-1):
 13             for j in range(len(self.arr)-1-i):
 14                 if self.arr[j] > self.arr[j+1]:
 15                     flag = True
 16                     temp = self.arr[j]
 17                     self.arr[j] = self.arr[j+1]
 18                     self.arr[j+1] = temp
 19             #print('冒泡排序第%d次排序的结果为' % (i+1), self.arr)
 20             if flag == False:
 21                 return self.arr,count  # 如果flag为false,说明此次排序没有任何交换,即已经排好顺序
 22             else:
 23                 count +=1
 24                 flag = False  # 置为false,进行下一次排序
 25         return self.arr, count
 26 
 27 
 28     def selectSort(self):
 29         # 选择排序,找到最小值及其索引再进行交换
 30         k = 0  # 用于记录实际排序的次数
 31         for i in range(len(self.arr)-1):  # 总共需要排序的次数为len(self.arr)-1
 32             min = self.arr[i]  # 假定当前的值为最小值
 33             minindex = i  # 假定当前值的索引为最小值的索引
 34             for j in self.arr[i+1:]:  # 从当前值的下一个值开始遍历比较
 35                 if min > j:  # 如果当前值大于下一个值,则重置最小值和最小值索引
 36                     min = j
 37                     minindex = self.arr.index(j)
 38             if minindex != i:
 39                 self.arr[minindex] = self.arr[i]
 40                 self.arr[i] = min
 41                 k += 1
 42                 #print('选择排序第%d次排序的结果为' % k, self.arr)
 43         return self.arr,k
 44 
 45 
 46     def insertSort(self):
 47         # 插入排序,为每一个待插入的数找到合适的位置
 48         k = 0  # 用来记录优化后的排序次数
 49         for i in range(len(self.arr)-1):  # 需要排序的次数为len(self.arr)-1次
 50             insertvalue = self.arr[i+1]  # 待插入的数从第2个数开始
 51             insertindex = i  # 待插入的数要与它前面的数进行比较,这里用来记录前一个值的索引
 52             while insertindex >= 0 and insertvalue < self.arr[insertindex]:
 53                 # 满足两个条件,当前面值的索引大于等于0并且待插入的值小于前一个值时说明待插入的值还没有找到合适的位置
 54                 # 此时需要将前一个数向后移动
 55                 self.arr[insertindex + 1] = self.arr[insertindex]
 56                 insertindex -= 1  # 进行下一次判断
 57             if (insertindex + 1) != (i+1):  # 当本来就有序时则不需要插入
 58                 k += 1
 59                 self.arr[insertindex + 1] = insertvalue  # 将待插入的值放到合适的位置
 60                 #print('插入排序第%d次排序的结果为' % k, self.arr)
 61         return self.arr,k
 62 
 63 
 64     def shellSort(self):
 65         # 希尔交换式排序
 66         temp = 0  # 交换时的中间变量
 67         count = 0  # 记录排序次数
 68         gap = len(self.arr)//2  # gap初始值,第一次分组的数量
 69         while (gap > 0):  # gap分组为1时做最后一次插入排序
 70             count += 1
 71             for i in range(gap, len(self.arr)):  # 遍历gap后的每一个元素
 72                 for j in range(i-gap, -1, -gap):  # 遍历同一组的每一个元素
 73                     if self.arr[j] > self.arr[j+gap]:  # 当同一组元素的前一个值大于后一个值时交换两者位置
 74                         temp = self.arr[j]
 75                         self.arr[j] = self.arr[j+gap]
 76                         self.arr[j+gap] = temp
 77 
 78             #print('希尔交换式排序第%d次排序的结果为' % count, self.arr)
 79             gap //= 2  # 分组增量减少,进行下一次循环
 80         return self.arr,count
 81 
 82 
 83     def shellSort2(self):
 84         # 希尔移位式排序
 85         count = 0
 86         gap = len(self.arr)//2
 87         while gap > 0:
 88             count += 1
 89             for i in range(gap, len(self.arr)):
 90                 j = i  # 记录待插入值的索引
 91                 temp = self.arr[j]  # 记录当前值,待插入的值
 92                 if self.arr[j] < self.arr[j-gap]:  # 如果同一组中后一个值小于前一个值,则给当前值继续寻找合适的位置
 93                     while j-gap >= 0 and temp < self.arr[j-gap]:
 94                         # 满足两个条件,当前一个值的索引大于等于0且待插入的值小于前一个值则将前一个值向后移动
 95                         self.arr[j] = self.arr[j-gap]
 96                         j -= gap
 97                     self.arr[j] = temp  # 退出while循环时说明已经为temp找到了合适的位置
 98             # print('希尔移位式排序第%d次排序的结果为' % count, self.arr)
 99             gap //= 2
100         return self.arr,count
101 
102 
103 if __name__ == '__main__':
104     # arr = [3, -1, 9, 5, 14, -3]
105     np.random.seed(8000)  # 设置 8000 个种子
106     random1 = np.random.randint(0,8000000,8000)  # 随机生成8000个随机整数
107     random1 = random1.tolist()  # 将ndarray转换为list
108     print(type(random1))
109     #for index in range(len(random1)):
110        # print(random1[index])
111     sort1 = Sort(random1)  # 实例化对象类
112     print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))  # 格式化输出时间
113     start = time.time()
114     resarr,count = sort1.shellSort2()  # 调用对象的希尔移位式排序方法
115     end = time.time()
116     print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
117     print('排序运行时间为%.5f秒'%(end-start))  # 计算运行时间
118     print("一共排序%d次"%count)

 ---------------------

2020.7.17 周五 更新

归并排序、快速排序、基数排序

  • 归并排序 MergeSort.py
     1 def mergeSort(arr, left, right, temp):
     2     if left < right:
     3         mid = (left + right) // 2
     4         # 向左递归
     5         mergeSort(arr, left, mid, temp)
     6         # 向右递归
     7         mergeSort(arr, mid + 1, right, temp)
     8         # 合并排序
     9         merge(arr, left, mid, right, temp)
    10 
    11 
    12 def merge(arr, left, mid, right, temp):
    13     i = left
    14     j = mid + 1
    15     t = 0
    16     # 1.比较两边的数,将较小的数放入temp中
    17     while (i <= mid) and (j <= right):
    18         if arr[i] < arr[j]:
    19             temp[t] = arr[i]
    20             t += 1
    21             i += 1
    22         else:
    23             temp[t] = arr[j]
    24             t += 1
    25             j += 1
    26     # 2.若有剩余的数,将其依次放入到temp中
    27     while i <= mid:
    28         temp[t] = arr[i]
    29         t += 1
    30         i += 1
    31     while j <= right:
    32         temp[t] = arr[j]
    33         t += 1
    34         j += 1
    35     # 3.将temp中的元素拷贝到arr中
    36     t = 0
    37     tempLeft = left
    38     while tempLeft <= right:
    39         arr[tempLeft] = temp[t]
    40         t += 1
    41         tempLeft += 1
    42 
    43 
    44 if __name__ == '__main__':
    45     arr = [53, -3, -6, 542, 74, 214]
    46     temp = [0 for i in range(len(arr))]
    47     mergeSort(arr, 0, len(arr)-1, temp)
    48     print('排序后的结果为', arr)
  • 快速排序 QuickSort.py
     1 def quickSort(arr, left, right):
     2     l = left
     3     r = right
     4     pivot = arr[(left + right) // 2]
     5 
     6     while l < r:
     7         # 寻找pivot左边大于pivot的值
     8         while arr[l] < pivot:
     9             l += 1
    10         # 寻找pivot右边小于pivot的值
    11         while arr[r] > pivot:
    12             r -= 1
    13         # 退出循环的条件
    14         if l >= r:
    15             break
    16         # 将两边的值交换
    17         temp = arr[l]
    18         arr[l] = arr[r]
    19         arr[r] = temp
    20 
    21         if arr[l] == pivot:
    22             r -= 1
    23         if arr[r] == pivot:
    24             l += 1
    25     # while循环结束
    26     if l == r :
    27         r -= 1
    28         l += 1
    29     if left < r:
    30         quickSort(arr, left, r)
    31     if right > l:
    32         quickSort(arr, l, right)
    33 
    34 
    35 if __name__ == '__main__':
    36     arr = [53, -3, -6, 542, 74, 214]
    37     quickSort(arr, 0, len(arr)-1)
    38     print('排序后的数组为',arr)
  • 基数排序 RadixSort.py

     1 def radixSort(arr):
     2     # 寻找最大值与最小值
     3     max = arr[0]
     4     min = arr[1]
     5     for i in arr:
     6         if i > max:
     7             max = i
     8         if i < min:
     9             min = i
    10     # 对于最大值求其最高位
    11     maxLength = len(str(max))
    12     # 对于最小值,若其小于0,就将每一个元素减去这个最小值以保证每个元素都大于等于0
    13     if min < 0:
    14         for i in range(len(arr)):
    15             arr[i] -= min
    16     bucket = [[0 for i in range(len(arr))] for i in range(10)]  # 嵌套列表
    17     bucketElementCounts = [0 for i in range(10)]  # 记录每个桶里元素的个数
    18     n = 1
    19     # 遍历最大值的位数
    20     for i in range(maxLength):
    21         # 遍历待排序列表里的每一个值
    22         for j in range(len(arr)):
    23             ele = arr[j] // n % 10
    24             bucket[ele][bucketElementCounts[ele]] = arr[j]
    25             bucketElementCounts[ele] += 1
    26         # 将桶里的元素按顺序取出
    27         index = 0
    28         # 遍历每一个桶
    29         for k in range(len(bucket)):
    30             if bucketElementCounts[k] != 0:
    31                 for l in range(bucketElementCounts[k]):
    32                     arr[index] = bucket[k][l]
    33                     index += 1
    34             bucketElementCounts[k] = 0
    35         n *= 10
    36 
    37     if min < 0:
    38         for i in range(len(arr)):
    39             arr[i] += min
    40 
    41 
    42 if __name__ == '__main__':
    43     arr = [53, -3, -6, 542, 74, 214]
    44     radixSort(arr)
    45     print('排序后的数组为',arr)
原文地址:https://www.cnblogs.com/DJames23/p/13191370.html