几种排序算法的对比

已知数据结构中有多种算法,现在参考比较多方来源,总结出python版的排序算法的实现,一方面是为了总结,另外一方面也是温故知新。

具体参考:1.《漫画算法--小灰的算法之旅》

                  2. CSDN博客:《八大排序算法》

下面首先来看下本文中所列出的几种算法的时间空间复杂度和稳定性

排序算法的比较
排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序O(n^{2})O(n^{2})O(1)稳定
鸡尾酒排序O(n^{2})O(n^{2})O(1)稳定
快速排序O(nlogn)O(n^{2})O(logn)不稳定
堆排序O(nlogn)O(nlogn)O(1)​​​​​​​不稳定
桶排序O(n)​​​​​​​O(nlogn)O(n)稳定

 

 

 

 

 

 

 

 

下面分别来看

class Sort(object):
    def __init__(self,li=[]):
        self.li = li

        # 首先要判断列表非为空
        if len(self.li) == 0:
            raise Exception("Please add some elements in the array.")

    def bubble_sort(self):
        '''
        冒泡排序法,思想是逐个比较,算法复杂度为O(n^2),空间复杂度O(1),稳定
        '''
        blist = self.li
        for i in range(len(blist)):
            for j in range(len(blist)-i-1):
                if blist[j] > blist[j+1] :
                    # 比较大小,最大的冒泡到最上面
                    blist[j+1],blist[j] = blist[j],blist[j+1]
        return blist


    def insert_sort(self):
        '''
        插入排序法,将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序;
        首先将第一个作为已经排好序的,然后每次从后的取出插入到前面并排序;
        时间复杂度为O(n^2),空间复杂度为O(1),稳定
        '''
        ilist = self.li
        for i in range(len(ilist)):
            for j in range(i):
                if ilist[i] < ilist[j]:
                    ilist.insert(j, ilist.pop(i))
                    break
        return ilist

    def cock_sort(self):
        '''
        鸡尾酒排序法,思路类似于冒泡排序,区别在于比较和交换是双向的
        时间复杂度为O(n^2),空间复杂度为O(),稳定
        '''
        clist = self.li
        for i in range(len(clist) // 2):
            isSorted = True
            # 奇数轮,从左向右比较和交换
            for j in range(len(clist)-i-1):
                if clist[j] > clist[j+1]:
                    clist[j+1],clist[j] = clist[j],clist[j+1]
                    isSorted = False
            if isSorted:
                break

            # 偶数轮,从右向左比较和交换
            isSorted = True
            for j in reversed(len(clist)-i-1):
                if clist[j] < clist[j - 1]:
                    clist[j - 1], clist[j] = clist[j], clist[j - 1]
                    isSorted = False
            if isSorted:
                break

        return clist


    def quick_sort(self,qlist=[]):
        '''
        快速排序法,思路为通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小
        整个思路是通过递归实现
        时间复杂度为O(nlog(n)),空间复杂度为O(nlog(n)),不稳定
        '''
#        qlist = self.li
        if qlist == []:
            return []
        else:
            qfirst = qlist[0]
            qless = self.quick_sort([l for l in qlist[1:] if l < qfirst])
            qmore = self.quick_sort([m for m in qlist[1:] if m >= qfirst])
            return qless + [qfirst] + qmore



    def heap_sort(self):
        '''
        堆排序,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。
        堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。
        在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶
        堆排序的时间复杂度为O(nlog(n)),空间复杂度为O(1),不稳定
        '''
        import copy

        def heap_adjust(parent):
            child = 2 * parent + 1  # left child
            while child < len(heap):
                if child + 1 < len(heap): # 判断右节点是否存在
                    if heap[child + 1] > heap[child]: #右孩子是否大于左孩子?
                        child += 1  # right child
                if heap[parent] >= heap[child]:
                    break
                # 如果父节点的指比左右孩子中最大的要小, 父节点和最大子节点交换
                # 然后将下沉的父节点与再下一层的左右子节点比较
                heap[parent], heap[child] = heap[child], heap[parent]
                parent, child = child, 2 * child + 1


        heap, hlist = copy.copy(self.li), []

        # 构建最大二叉堆
        for i in range(len(heap) // 2, -1, -1):
            heap_adjust(i)

        while len(heap) != 0:
            heap[0], heap[-1] = heap[-1], heap[0]
#            hlist.append(heap.pop())  # 从堆中取最大值,赋给数组的最后一位--result:从大到小排序
            hlist.insert(0,heap.pop())# 从堆取最大值,赋给数组的第一位--result:从小到大排序

            heap_adjust(0)

        return hlist


    DEFAULT_BUCKET_SIZE = 5 # 桶的个数,这个可以自己定义,也可以根据数组的情况来确定

    def bucket_sort(self,bucket_size=DEFAULT_BUCKET_SIZE):
        '''
        桶排序,思路为将n个元素分到m个空桶里,分别进行排序然后拼接
        时间复杂度为O(n),空间复杂度为O(n),稳定
        '''
        blist = self.li
        # 统计各项定义
        max_item,min_item = max(blist),min(blist)

        #初始化
        # 具体要建立多少桶,确定桶的区间范围,有多种方式
        # 区间跨度 =(最大值-最小值)/桶的数量+1
        count_size = (max_item-min_item)//bucket_size+1
        print('count_size:',count_size)
        bucket_list = [[ ] for _ in range(count_size)]

        # 把各个元素放入桶中
        for i in range(len(blist)):
            i_num = (blist[i]-min_item)//bucket_size
            bucket_list[i_num].append(blist[i])

        # 对桶中的元素进行排序
        for i in range(len(bucket_list)):
            bucket_list[i].sort()

        # 输出全部元素
        sort_list = [i for i in bucket_list]
        print(sort_list)
        sorted_list = [item for index in bucket_list for item in index]

        return sorted_list








if __name__ == "__main__":
    list1 = [1,2,5,4,16,3,12,10]
#    list1 = [4,5,6,7,3,2,6,9,8]
#    list1 = [3,5,7,24,67,45,32,56,17,20]
    print('list1 = ',list1)
    new_s = Sort(list1)

    s = new_s.bubble_sort()
    print('冒泡排序法: ',s)

    cock_s = new_s.cock_sort()
    print('鸡尾酒排序法: ',cock_s)

    insert_s = new_s.insert_sort()
    print('插入排序法: ',insert_s)


    quick_s = new_s.quick_sort(list1)
    print('快速排序法:',quick_s)
    
    heap_s = new_s.heap_sort()
    print('堆排序法:',heap_s)

    bucket_s = new_s.bucket_sort()
    print('桶排序法:',bucket_s)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值