Daily Leetcode-9 排序

1.排序定义:将一组无序的记录序列按照某种逻辑顺序重新排序,调整为有序的记录序列的过程。

2.排序算法的分类

(1)按待排序的记录数量不同分为:内部排序算法(数据量不大,排序过程中全部记录放在内存中处理);外部排序算法(数据量较大,需要内存和外存之间数据交换,来实现排序目的)。
(2)按相同值的相对位置是否改变分类:稳定性排序算法(相对位置不变);非稳定性排序算法(相对位置改变)。
(3)按记录在存储介质上的组织方式分类:顺序存储结构排序算法链式存储结构排序算法

3.常见的排序算法

(1)O(n2) 冒泡排序算法,选择排序算法,插入排序算法
(2)O(nlogn) 希尔排序算法,归并排序算法,快速排序算法,堆排序算法
(3)O(n) 计数排序算法,桶排序算法,基数排序算法

3.1. 冒泡排序算法(遍历数组,比较相邻元素,交换位置)

3.1.1.基本思想 在这里插入图片描述
3.1.2.基本步骤
在这里插入图片描述3.1.3.算法分析
(1)最好情况:升序排列,O(n)
(2)最差情况:降序排列,O(n2)
(3)需要移动元素次数较多,适合数据量小的情况。
(4)相邻元素交换,不会改变相同元素的相邻位置,是一种稳定性排序算法。
3.1.4.代码实现

	class Solution:
		def bubbleSort(self, arr):
			for i in range(len(arr)):
				for j in range(len(arr)):
					if arr[j]>arr[j+1]:
						arr[j],arr[j+1] = arr[j+1],arr[j]
			return arr

3.2. 选择排序算法(遍历数组,找出剩余数组中最小元素,放在数组最上方)

3.2.1.基本思想
在这里插入图片描述
3.2.2.基本步骤
在这里插入图片描述
3.2.3.代码实现

	class Solution:
		def selectionSort(self, arr):
			for i in range(len(arr)-1):
				min_i = i
				for j in range(i+1,len(arr)):
					if arr[j]<arr[min_i]:
						min_i = j
					if i != min_i:
						arr[i],arr[i+1] = arr[i+1],arr[i]
			return arr

3.3.插入排序算法(遍历数组,将后序无序数组中的元素插入前序有序数组中)

3.3.1.基本思想
在这里插入图片描述
3.3.2.基本步骤
在这里插入图片描述
3.3.3.算法分析
(1)最好情况:升序排列,O(n)
(2)最差情况:降序排列,O(n2)
(3)是一种稳定性排序算法。
3.3.4.代码实现

	class Solution:
		def insertSort(self, arr):
			for i in range(len(arr)):
				temp = arr[i]
				j=i
				while j>0 and arr[j-1]>temp:
					arr[j]=arr[j-1]
					j -= 1
				arr[j] = temp
			return arr

3.4.希尔排序算法

3.4.1.基本思想(等价于 分层插入排序,不同的间隔代表不同的层)
在这里插入图片描述
3.4.2.基本步骤
在这里插入图片描述
3.4.3.算法分析
(1)时间复杂度为O(logn)与O(n)之间
(2)是非稳定性排序算法
3.4.4.代码实现

	class Solution:
		def shellSort(self, arr):
			size = len(arr)
			gap = size//2
			while gap>0:
				for i in range(gap,size):
					temp = arr[i]
					j=i
					while j>=gap and arr[j-gap]>temp:
						arr[j]=arr[j-gap]
						j -= 1
					arr[j] = temp
				gap = gap//2
			return arr

3.5.归并排序算法(递归地将当前序列平均分为两半,再两两合并)

3.5.1.基本思想
在这里插入图片描述
3.5.2.基本步骤
在这里插入图片描述
3.5.3.算法分析
(1)时间复杂度:归并的次数和每一次归并排序的时间复杂度的乘积,O(nlogn)
(2)空间复杂度:需要用到与参加排序的序列同样大小的辅助空间,O(n)
(3)是稳定性排序算法
3.5.4.代码实现

	class Solution:
		def merge(arr_left, arr_right):
			arr=[]
			while arr_left and arr_right:
				if arr_left[0] <= arr_right[0]:
					arr.append(arr_left.pop(0))
				else:
					arr.append(arr_right.pop(0))
			while arr_left:
				arr.append(arr_left.pop(0))
			while arr_right:
				arr.append(arr_right.pop(0))
			return arr
			
		def mergeSort(self, arr):
			size = len(arr)
			if size < 2:
				return arr
			mid = len(arr)//2
			arr_left, arr_right = arr[0:mid], arr[mid:]
			return self.merge(self.mergeSort(arr_left),self.mergeSort(arr_right))

3.6.快速排序算法(随机找一个分隔结点,与序列中其他元素比较,小的在左边,大的在右边)

3.6.1.基本思想
在这里插入图片描述
3.6.2.基本步骤
在这里插入图片描述
3.6.3.算法分析
(1)最差情况:参加排序的元素初始时已经有序,O(n2)
(2)最好情况:分界元素正好处于序列中间。O(nlogn)
(3)是一种非稳定性排序算法
3.6.4.代码实现

	class Solution:
		def randomPartition(self, arr:[int], low:int, high :int):
			i = random.randint(low, high)
			arr[i], arr[high] = arr[high], arr[i]
			return self.partition(arr, low, high)
			
		def partition(self, arr:[int], low:int, high :int):
			i = low-1
			pivot = arr[high]
			for j in range(low, high):
				if arr[j] < pivot:
					i+=1
					arr[i],arr[j]=arr[j],arr[i]
				arr[i+1],arr[high] = arr[high],arr[i+1]
				
		def quickSort(self, arr, low, high):
			if low < high:
				pi = self.randomPartition(arr, low, high)
				self.quickSort(arr, low, pi-1)
				self.quickSort(arr, pi+1, high)
			return arr

3.7.堆排序算法(构造大顶堆,重复从大顶堆中取出最大节点)

3.7.1.基本思想
在这里插入图片描述
3.7.2.基本步骤
在这里插入图片描述

3.8.计数排序算法(统计不同数值节点的个数,按照数值大小排列新的序列)

3.8.1.基本思想
在这里插入图片描述
3.8.2.基本步骤
在这里插入图片描述
3.8.3.算法分析
(1)时间复杂度O(n+k),对于数据量很大的数组会占用很大的存储空间和时间
(2)是稳定性排序算法

3.8.4.代码实现

	class Solution:
		def countingSort(self, arr):
			arr_min, arr_max = min(arr), max(arr)
			size = arr_max - arr_min + 1
			counts = [0 for _ in range(size)]
	
			for num in arr:
				counts[num-arr_min] += 1
			for j in range(1, size):
				counts[j] += counts[j-1]
			
			res = [0 for _ in range(len(arr))]
			for i in range(len(arr)-1,-1,-1):
				res[counts[arr[i]-arr_min]-1] = arr[i]
				counts[arr[i]-arr_min] -= 1
			return res

3.9.桶排序算法(按节点数值均匀分成n个桶,桶内排序,再依次合并)

3.9.1.基本思想
在这里插入图片描述
3.9.2.基本步骤
在这里插入图片描述
3.9.3.算法实现

#include <iostream>
#include <vector>
#include <list>
using namespace std;
void insert(list<int>& bucket,int val)
{
    auto iter = bucket.begin();
    while(iter != bucket.end() && val >= *iter) ++iter;
    //insert会在iter之前插入数据,这样可以稳定排序
    bucket.insert(iter,val);
}

void BucketSort_1(vector<int>& arr)
{
    int len = arr.size();
    if(len <= 1)
        return;
    int min = arr[0],max = min;
    for(int i=1;i<len;++i)
    {
        if(min>arr[i]) min = arr[i];
        if(max<arr[i]) max = arr[i];
    }
    int k = 10;//k为数字之间的间隔
    //向上取整,例如[0,9]有10个数,(9 - 0)/k + 1 = 1;
    int bucketsNum = (max - min)/k + 1;
    vector<list<int>> buckets(bucketsNum);
    for(int i=0;i<len;++i)
    {
        int value = arr[i];
        //(value-min)/k就是在哪个桶里面
        insert(buckets[(value-min)/k],value);
    }
    int index = 0;
    for(int i=0;i<bucketsNum;++i)
    {
        if(buckets[i].size())
        {
            for(auto& value:buckets[i])
                arr[index++] = value;
        }
    }
}

3.9.4.算法分析
(1)时间复杂度接近O(n)
(2)是稳定性排序算法

3.10.基数排序算法(按整数位从低到高,遍历排序)

3.10.1.基本思想
在这里插入图片描述
3.10.2.基本步骤
在这里插入图片描述
3.10.3.算法分析
(1)时间复杂度O(n+k)
(2)是稳定性排序算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值