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

小海 2020-06-25

2020.6.25 周四更新

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

持续更新

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

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

import numpy as np
import time

class Sort:
    def __init__(self, arr):
        self.arr = arr

    def bubblesort(self):
        # 冒泡排序
        count = 0
        flag = False  # 优化冒泡排序,当一次循环没有任何交换时就退出
        for i in range(len(self.arr)-1):
            for j in range(len(self.arr)-1-i):
                if self.arr[j] > self.arr[j+1]:
                    flag = True
                    temp = self.arr[j]
                    self.arr[j] = self.arr[j+1]
                    self.arr[j+1] = temp
            #print(‘冒泡排序第%d次排序的结果为‘ % (i+1), self.arr)
            if flag == False:
                return self.arr,count  # 如果flag为false,说明此次排序没有任何交换,即已经排好顺序
            else:
                count +=1
                flag = False  # 置为false,进行下一次排序
        return self.arr, count


    def selectSort(self):
        # 选择排序,找到最小值及其索引再进行交换
        k = 0  # 用于记录实际排序的次数
        for i in range(len(self.arr)-1):  # 总共需要排序的次数为len(self.arr)-1
            min = self.arr[i]  # 假定当前的值为最小值
            minindex = i  # 假定当前值的索引为最小值的索引
            for j in self.arr[i+1:]:  # 从当前值的下一个值开始遍历比较
                if min > j:  # 如果当前值大于下一个值,则重置最小值和最小值索引
                    min = j
                    minindex = self.arr.index(j)
            if minindex != i:
                self.arr[minindex] = self.arr[i]
                self.arr[i] = min
                k += 1
                #print(‘选择排序第%d次排序的结果为‘ % k, self.arr)
        return self.arr,k


    def insertSort(self):
        # 插入排序,为每一个待插入的数找到合适的位置
        k = 0  # 用来记录优化后的排序次数
        for i in range(len(self.arr)-1):  # 需要排序的次数为len(self.arr)-1次
            insertvalue = self.arr[i+1]  # 待插入的数从第2个数开始
            insertindex = i  # 待插入的数要与它前面的数进行比较,这里用来记录前一个值的索引
            while insertindex >= 0 and insertvalue < self.arr[insertindex]:
                # 满足两个条件,当前面值的索引大于等于0并且待插入的值小于前一个值时说明待插入的值还没有找到合适的位置
                # 此时需要将前一个数向后移动
                self.arr[insertindex + 1] = self.arr[insertindex]
                insertindex -= 1  # 进行下一次判断
            if (insertindex + 1) != (i+1):  # 当本来就有序时则不需要插入
                k += 1
                self.arr[insertindex + 1] = insertvalue  # 将待插入的值放到合适的位置
                #print(‘插入排序第%d次排序的结果为‘ % k, self.arr)
        return self.arr,k


    def shellSort(self):
        # 希尔交换式排序
        temp = 0  # 交换时的中间变量
        count = 0  # 记录排序次数
        gap = len(self.arr)//2  # gap初始值,第一次分组的数量
        while (gap > 0):  # gap分组为1时做最后一次插入排序
            count += 1
            for i in range(gap, len(self.arr)):  # 遍历gap后的每一个元素
                for j in range(i-gap, -1, -gap):  # 遍历同一组的每一个元素
                    if self.arr[j] > self.arr[j+gap]:  # 当同一组元素的前一个值大于后一个值时交换两者位置
                        temp = self.arr[j]
                        self.arr[j] = self.arr[j+gap]
                        self.arr[j+gap] = temp

            #print(‘希尔交换式排序第%d次排序的结果为‘ % count, self.arr)
            gap //= 2  # 分组增量减少,进行下一次循环
        return self.arr,count


    def shellSort2(self):
        # 希尔移位式排序
        count = 0
        gap = len(self.arr)//2
        while gap > 0:
            count += 1
            for i in range(gap, len(self.arr)):
                j = i  # 记录待插入值的索引
                temp = self.arr[j]  # 记录当前值,待插入的值
                if self.arr[j] < self.arr[j-gap]:  # 如果同一组中后一个值小于前一个值,则给当前值继续寻找合适的位置
                    while j-gap >= 0 and temp < self.arr[j-gap]:
                        # 满足两个条件,当前一个值的索引大于等于0且待插入的值小于前一个值则将前一个值向后移动
                        self.arr[j] = self.arr[j-gap]
                        j -= gap
                    self.arr[j] = temp  # 退出while循环时说明已经为temp找到了合适的位置
            # print(‘希尔移位式排序第%d次排序的结果为‘ % count, self.arr)
            gap //= 2
        return self.arr,count


if __name__ == ‘__main__‘:
    # arr = [3, -1, 9, 5, 14, -3]
    np.random.seed(8000)  # 设置 8000 个种子
    random1 = np.random.randint(0,8000000,8000)  # 随机生成8000个随机整数
    random1 = random1.tolist()  # 将ndarray转换为list
    print(type(random1))
    #for index in range(len(random1)):
       # print(random1[index])
    sort1 = Sort(random1)  # 实例化对象类
    print(time.strftime(‘%Y-%m-%d %H:%M:%S‘,time.localtime(time.time())))  # 格式化输出时间
    start = time.time()
    resarr,count = sort1.shellSort2()  # 调用对象的希尔移位式排序方法
    end = time.time()
    print(time.strftime(‘%Y-%m-%d %H:%M:%S‘,time.localtime(time.time())))
    print(‘排序运行时间为%.5f秒‘%(end-start))  # 计算运行时间
    print("一共排序%d次"%count)

相关推荐