使用Python实现常见的几种排序算法

使用Python实现各种常见的排序算法

文章共介绍六种排序算法

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 快速排序
  • 希尔排序
  • 归并排序
import sys
sys.setrecursionlimit(100000) #设置递归深度
class sort(object):
    """
    该类中包含一些常见的排序算法,默认为升序排序
    """
    def __init__(self,list):
        self.list = list

    def bubble_sort(self):
        """
        冒泡排序,原理是依次比较相邻的两个元素的值,如果前面的大于后面的,就进行交换。每一轮会有一个最大的元素被选出放在最后。
        n个元素经过n-1次排序即可完成排序。最优时间复杂度o(n),最坏时间复杂度o(n2),稳定排序算法。
        :return: 返回排序后的列表
        """
        for j in range(len(self.list)-1, 0, -1):
            # j从8到0,不包含0,每次减一,包使排序的次数为8次。
            for i in range(j):
                # 每一轮i从0到j进行变化,不包含j
                if self.list[i] > self.list[i+1]:
                    self.list[i], self.list[i+1] = self.list[i+1], self.list[i]
        print("经过冒泡排序后的列表顺序为:" + str(self.list))
        return self.list

    def select_sort(self,newlist):
        """
        选择排序,原理是每次从未排序序列中挑选出最小的元素放在序列开始,每轮会有一个元素被排好序。
        n个元素进行n-1轮排序,最好最坏时间复杂度都是o(n2),不稳定
        :return:返回排好序的列表
        """
        print("原始列表顺序为:"+str(list))
        n = len(newlist)
        # 需要n-1次排序
        for i in range(n-1):
            # 记录最小值的位置
            min_index = i
            # 选出最小的值,交换下标
            for j in range(i+1, n):
                if newlist[j] < newlist[min_index]:
                    min_index = j
            # 每一轮确定了最小的下标后,就更换值
            if min_index != i:
                newlist[i], newlist[min_index] = newlist[min_index], newlist[i]

        print("经过选择排序后的列表顺序为:"+str(newlist))
        return newlist

    def insert_sort(self,newlist):
        """
        插入排序,原理是构建一个已排列的序列,对于未排序的数据,在已排序序列中从后先前扫描,找到合适的位置插入。
        n个元素需要n-1轮的排序,最优时间复杂度o(n),最坏时间复杂度o(n2),稳定
        :param newlist:传入的未排序的列表
        :return:返回已经排列好的列表
        """
        print("原始列表顺序为:" + str(list))
        # n个元素需要n-1轮的排序
        for i in range(1,len(newlist)):
            for j in range(i, 0, -1):
                if newlist[j] < newlist[j-1]:
                    newlist[j], newlist[j-1] = newlist[j-1], newlist[j]

        print("经过插入排序后的列表顺序为:" + str(newlist))
        return newlist

    def quick_sort(self, newlist, start, end):
        """
        快速排序,原理是通过一趟排序要将排序的数据分割为独立的两部分,其中一部分的数据要比另一部分要小,
        然后再按照这种方法对这两部分数据分别进行快速排序,不断递归。具体:从序列中挑选出一个数作为基准,重新排列数列
        ,所有比基准元素小的摆在基准前面,所有元素比基准大的摆在基准后面.在对其余两个前后序列进行相同操作.
       最优时间复杂度o(nlogn),最差时间复杂度o(n2),空间复杂度o(logn),不稳定
        :param newlist:无序列表
        :return:返回已经排好序的列表
        """
        if start < end:
            i = start
            j = end
            pivot = newlist[start]
            while i < j :
                while newlist[j] >= pivot and i < j:
                    j -= 1
                newlist[i], newlist[j] = newlist[j], newlist[i]
                while newlist[i] <= pivot and i < j:
                    i += 1
                newlist[i], newlist[j] = newlist[j], newlist[i]
            self.quick_sort(newlist, start, i - 1)
            self.quick_sort(newlist, i+1, end)


        return newlist

    def shell_sort(self, newlist):
        """
        希尔排序,原理是将数据从大步长分割进行插入排序,慢慢减小步长进行排序,最终步长缩减为1.
        最坏时间复杂度o(n2),不稳定
        :param newlist:无序列表
        :return:返回有序列表
        """
        print("原始列表顺序为:" + str(list))
        n = len(newlist)
        # 初始步长
        gap = n//2
        while gap > 0 :
            for i in range(gap, n):
                j = i
                # 插入排序
                while j >= gap and newlist[j-gap] > newlist[j]:
                    newlist[j-gap] , newlist[j] = newlist[j], newlist[j-gap]
                    j -= gap
            gap = gap//2

        print("经过希尔排序后的列表顺序为:" + str(newlist))
        return newlist

    def merge_sort(self, newlist):
        """
        归并排序的思想就是分治,先递归分解数组,在合并数组.具体:将数组分解到最小之后,比较两个数组最前面的数,谁小就取谁,
        取了后相应的指针就往后移一位,然后再比较,直至有一个数组为空,再把不为空的数组直接复制过去。
        最优和最坏时间复杂度为o(nlogn),稳定
        :param newlist:无序列表
        :return:返回有序列表
        """
        if len(newlist) <= 1 :
            return newlist
        num = len(newlist)//2
        left = self.merge_sort(newlist[:num])
        right = self.merge_sort(newlist[num:])
        return self.merge(left,right)

    def merge(self, left, right):
        """
        用于合并merge_sort拆分后的两个列表
        :param left: 传入到merge_sort中的前num个数字组成的列表
        :param right: 传入到merge_sort中的n-num个数字组成的列表
        :return: 返回合并的结果
        """
        l,r = 0,0
        result = []
        while l < len(left) and r < len(right):
            if left[l] < right[r]:
                result.append(left[l])
                l += 1
            else:
                result.append(right[r])
                r += 1
        result += left[l:]
        result += right[r:]

        return result

if __name__ == "__main__":

    list = [23,15,65,49,98,52,0,12,-16]
    print("原始列表顺序为:"+str(list))
    sort = sort(list)
    sort.bubble_sort()
    list = [23, 15, 65, 49, 98, 52, 0, 12, -16]
    sort.select_sort(list)
    list = [23, 15, 65, 49, 98, 52, 0, 12, -16]
    sort.insert_sort(list)
    list = [23, 15, 65, 49, 98, 52, 0, 12, -16]
    print("原始列表顺序为:" + str(list))
    print("经过快速排序的列表顺序为:"+str(sort.quick_sort(list, 0, len(list)-1)))
    list = [23, 15, 65, 49, 98, 52, 0, 12, -16]
    sort.shell_sort(list)
    list = [23, 15, 65, 49, 98, 52, 0, 12, -16]
    print("原始列表顺序为:" + str(list))
    print("经过归并排序的列表顺序为:" + str(sort.merge_sort(list)))
posted @ 2021-04-14 11:08  lijiahaoAA  阅读(193)  评论(0编辑  收藏  举报