[LeetCode]912. 排序数组

题目

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

  1. 1 <= nums.length <= 50000
  2. -50000 <= nums[i] <= 50000

排序算法总结

clipboard.png

一、冒泡排序

代码1:

def bubble_sort(list):    
    length = len(list)
    # 第一级遍历
    for index in range(length):     
        # 第二级遍历
        for j in range(1, length - index): 
            if list[j - 1] > list[j]:
                # 交换两者数据,这里没用temp是因为python特性元组。
                list[j - 1], list[j] = list[j], list[j - 1]
    return list

这种排序其实还可以稍微优化一下,添加一个标记,在排序已完成时,停止排序。
代码2:

def bubble_sort_flag(list):
    length = len(list)
    for index in range(length):
        # 标志位
        flag = True
        for j in range(1, length - index):
            if list[j - 1] > list[j]:
                list[j - 1], list[j] = list[j], list[j - 1]
                flag = False
        if flag:
            # 没有发生交换,直接返回list
            return list
    return list

二、选择排序

def selection_sort(list):
    n=len(list)
    for i in range (0,n):
        min = i
        for j in range(i+1,n):
            if list[j] < list[min]:
                min = j
        list[min], list[i] = list[i], list[min]
    return list

三、插入排序

代码1:

def insert_sort(list):
    n = len(list)
    for i in range(1, n):
        # 后一个元素和前一个元素比较
        # 如果比前一个小
        if list[i] < list[i - 1]:
            # 将这个数取出
            temp = list[i]
            # 保存下标
           index = i
           # 从后往前依次比较每个元素
           for j in range(i - 1, -1, -1):
               # 和比取出元素大的元素交换
               if list[j] > temp:
                   list[j + 1] = list[j]
                   index = j
               else:
                   break
           # 插入元素
           list[index] = temp
   return list

代码2:

def insert_sort(data):
    for k in range(1, len(data)):
        cur = data[k]
        j = k
        while j > 0 and data[j - 1] > cur:
            data[j] = data[j - 1]
            j -= 1
        data[j] = cur
    return data

四、希尔排序

def shell_sort(arr):
    # 取整计算增量(间隔)值
    gap = len(arr) // 2
    while gap > 0:
        # 从增量值开始遍历比较
        for i in range(gap, len(arr)):
            j = i
            current = arr[i] # 保存当前待插入的数
            # 元素与它同列的前面的每个元素比较,如果比前面的小则互换
            while j - gap >= 0 and current < arr[j - gap]:
                arr[j] = arr[j - gap]
                j -= gap
            arr[j] = current # 待插入的数的正确位置
        # 缩小增量(间隔)值
        gap //= 2
    return arr

五、归并排序

# 递归法
def merge_sort(list):
    # 认为长度不大于1的数列是有序的
    if len(list) <= 1:
        return list
    # 二分列表
    middle = len(list) // 2
    left = merge_sort(list[:middle])
    right = merge_sort(list[middle:])
   # 最后一次合并
   return merge(left, right)

# 合并
def merge(left, right):
    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
    # 直到某一指针到达序列尾,将另一序列剩下的所有元素直接复制到合并序列尾
    reslut += left[l:]
    result += right[r:]                
    return result

六、快速排序

代码1:

def partition(arr,i,j):
    p=arr[i] # 基准值为第一个值
    while i!=j:
        while i<j and p<=arr[j]:
            j-=1
        arr[i]=arr[j]
        while i<j and p>arr[i]:
            i+=1
        arr[j]=arr[i]
    arr[i]=p
    return i

def quick_sort(arr,i,j):
    if i<j:
        mid=partition(arr,i,j)
        quick_sort(arr,i,mid-1)
        quick_sort(arr,mid+1,j)

代码2:

# 分区函数
def partition(arr,low,high): 
    # i用来表示遍历过程中,所有比基准小的数组成的子序列中的最后一个元素的索引
    # 最后i+1即为基准在原序列中的位置
    i = low-1         
    pivot = arr[high] # 基准值为最后一个值
    for j in range(low , high): 
        # 当前元素小于或等于 pivot 
        if arr[j] <= pivot:
            i += 1 
            arr[i],arr[j] = arr[j],arr[i] 
    arr[i+1],arr[high] = arr[high],arr[i+1]
    return (i+1)
  
# 快速排序函数
def quickSort(arr,low,high): 
    if low < high: 
        pi = partition(arr,low,high) 
        quickSort(arr, low, pi-1) 
        quickSort(arr, pi+1, high) 

代码3:

def quick_sort(list):
    less = []
    pivotList = []
    more = []
    # 递归出口
    if len(list) <= 1:
        return list
    else:
        # 将第一个值做为基准
        pivot = list[0]
        for i in list:
            # 将比基准小的值放到less数列
            if i < pivot:
                less.append(i)
            # 将比基准大的值放到more数列
            elif i > pivot:
                more.append(i)
            # 将和基准相同的值保存在基准数列
            else:
                pivotList.append(i)
        # 对less数列和more数列继续进行排序
        less = quick_sort(less)
        more = quick_sort(more)
        return less + pivotList + more

代码4:

def qsort(arr):
    if len(arr) <= 1:
        return arr
    else:
        pivot = arr[0]
        less = [x for x in arr[1:] if x < pivot]
        greater = [x for x in arr[1:] if x >= pivot]
        return qsort(less) + [pivot] + qsort(greater)

七、堆排序

def heap_sort(nums):
    # 调整堆
    # 迭代写法
    def adjust_heap(nums, startpos, endpos):
        newitem = nums[startpos]
        pos = startpos
        childpos = pos * 2 + 1
        while childpos < endpos:
            rightpos = childpos + 1
            if rightpos < endpos and nums[rightpos] >= nums[childpos]:
                childpos = rightpos
            if newitem < nums[childpos]:
                nums[pos] = nums[childpos]
                pos = childpos
                childpos = pos * 2 + 1
            else:
                break
        nums[pos] = newitem
    
    # 递归写法
    def adjust_heap(nums, startpos, endpos):
        pos = startpos
        chilidpos = pos * 2 + 1
        if chilidpos < endpos:
            rightpos = chilidpos + 1
            if rightpos < endpos and nums[rightpos] > nums[chilidpos]:
                chilidpos = rightpos
            if nums[chilidpos] > nums[pos]:
                nums[pos], nums[chilidpos] = nums[chilidpos], nums[pos]
                adjust_heap(nums, pos, endpos)

    n = len(nums)
    # 建堆
    for i in reversed(range(n // 2)):
        adjust_heap(nums, i, n)
    # 调整堆
    for i in range(n - 1, -1, -1):
        nums[0], nums[i] = nums[i], nums[0]
        adjust_heap(nums, 0, i)
    return nums

八、计数排序

def counting_sort(nums):
    if not nums: return []
    n = len(nums)
    _min = min(nums)
    _max = max(nums)
    tmp_arr = [0] * (_max - _min + 1)
    for num in nums:
        tmp_arr[num - _min] += 1
    j = 0
    for i in range(n):
        while tmp_arr[j] == 0:
            j += 1
        nums[i] = j + _min
        tmp_arr[j] -= 1
    return nums

九、桶排序

def bucket_sort(nums, bucketSize):
    if len(nums) < 2:
        return nums
    _min = min(nums)
    _max = max(nums)
    # 需要桶个数
    bucketNum = (_max - _min) // bucketSize + 1
    buckets = [[] for _ in range(bucketNum)]
    for num in nums:
        # 放入相应的桶中
        buckets[(num - _min) // bucketSize].append(num)
    res = []

    for bucket in buckets:
        if not bucket: continue
        if bucketSize == 1:
            res.extend(bucket)
        else:
            # 当都装在一个桶里,说明桶容量大了
            if bucketNum == 1:
                bucketSize -= 1
            res.extend(bucket_sort(bucket, bucketSize))
    return res

十、基数排序

def Radix_sort(nums):
    if not nums: return []
    _max = max(nums)
    # 最大位数
    maxDigit = len(str(_max))
    bucketList = [[] for _ in range(10)]
    # 从低位开始排序
    div, mod = 1, 10
    for i in range(maxDigit):
        for num in nums:
            bucketList[num % mod // div].append(num)
        div *= 10
        mod *= 10
        idx = 0
        for j in range(10):
            for item in bucketList[j]:
                nums[idx] = item
                idx += 1
            bucketList[j] = []
    return nums

本题题解

代码

class Solution:
    def sortArray(self, nums: List[int]) -> List[int]:
        # 快速排序
        if len(nums)<=1:
            return nums
        else:
            pivot = nums[0]
            less = [x for x in nums[1:] if x<pivot]
            greater = [x for x in nums[1:] if x>=pivot]
            return self.sortArray(less) + [pivot] +self.sortArray(greater)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值