排序方法-堆排序,基数排序,快速排序 python实现

2 篇文章 0 订阅
1 篇文章 0 订阅

1 堆排序,大顶堆示例 

def getLeft(i):
    return i*2 +1
def getRight(i):
    return i * 2 + 2
def adjust_max_heap(nums,length,i):
    # 定义一个int值保存当前序列最大值的下标
    largest = i
    while True:
        # 找到当前调整节点的左右孩子
        left,right = getLeft(i), getRight(i)
        # 找出左右孩子和自己中最大的数在序列中的下标
        if left < length and nums[left] > nums[i]:
            largest = left
            print("左叶子节点")
        else:
            largest = i
        
        if right < length and nums[right] > nums[largest]:
            largest = right
            print("右叶子节点")
        # 如果当前位置不是最大的,叫交换位置,并将i的位置换成更换位置的下标,
        # 重新判断这个位置的左右孩子是否满足大顶堆
        if largest != i:
            nums[i],nums[largest]= nums[largest],nums[i]
            i = largest
            print(largest)
            continue
        else:
            break
            
def build_max_heap(nums):
    n = len(nums)
    # 从第一个非叶子节点开始调整堆,定位到,
    for x in range(int((n-2)/2),-1,-1):
        adjust_max_heap(nums,n,x)

"""
    大顶堆的排序算法,首先构建大顶堆,然后排序的过程,
    每次将堆顶元素和序列最后一个元素互换位置,
    此时:1序列末尾的元素为已排序的最大值;
    2 由于交换了元素,当前位于根节点的堆并不一定满足大顶堆的性质
    3 对交换后的n-1个序列元素进行调整,使其满足大顶堆的性质;
"""
def head_sort(nums):
    build_max_heap(nums)
    n = len(nums)
    while n > 0:
        nums[0],nums[n -1]=nums[n -1],nums[0]
        n -= 1
        adjust_max_heap(nums,n,0)
        
nums =[1,3,4,5,7,2,6,8,0]
head_sort(nums)
nums

2 基数排序

6 基数排序
### 是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

说基数排序之前,我们简单介绍桶排序:算法思想:是将阵列分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递回方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的阵列内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。
简单来说,就是把数据分组,放在一个的桶中,然后对每个桶里面的在进行排序。

 def cardinality_sort(nums):
        
        n = max([len(str(x)) for x in nums])
        for i in range(1, n + 1):
            tank = [[] for _ in range(10)]

            for j in range(len(nums)):
                if len(str(nums[j])) >= i:
                    tank[int(str(nums[j])[-1 * i])].append(nums[j])
                else:
                    tank[0].append(nums[j])
            nums.clear()
            for k in range(10):
                for x in tank[k]:
                    nums.append(x)

nums = [1, 5, 4, 3, 100, 898, 67, 45, 65]
cardinality_sort(nums)
print(nums)

3 快速排序

从序列当中选择一个基准数(pivot)

在这里我们选择序列当中第一个数最为基准数

将序列当中的所有数依次遍历,比基准数大的位于其右侧,比基准数小的位于其左侧

重复步骤1.2,直到所有子集当中只有一个元素为止。

用伪代码描述如下: 1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。 2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。 3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。 4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中

def quick_sort(nums,left,right):
    if left >= right:
        return
    l ,r = left,right
    pivot = nums[left]
    while left < right:
        while left < right and nums[right] > pivot:
            right -= 1
        nums[left] = nums[right]
        while left < right and nums[left] < pivot:
            left += 1
        nums[right] = nums[left]
    nums[left] = pivot
    quick_sort(nums,l,left-1)
    quick_sort(nums,left+1,r)


nums=[1,5,4,3,100,898,67,45,65]
quick_sort(nums,0,len(nums) - 1)
nums  

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值