前言:
本篇博客为学习笔记,用于巩固知识点。其中前五个为重点排序方法,在理解后要自己实现一遍。
实现语言:Python/Go
转载于:必学十大经典排序算法,看这篇就够了 文章中使用Java实现排序,然后自己使用Python/Go都分别实现了一次。也拿了几组数据进行测试过,暂时没发现问题,如果遇到问题还望告知。
算法评判
1、稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 仍然在 b 的前面,则为稳定排序。
2、非稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 可能不在 b 的前面,则为非稳定排序。
3、原地排序:原地排序就是指在排序过程中不申请多余的存储空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序。
4、非原地排序:需要利用额外的数组来辅助排序。
5、时间复杂度:一个算法执行所消耗的时间。
6、空间复杂度:运行完一个算法所需的内存大小。
1、选择排序
简述:
在需要排序的数组中,先找到数值最小的数,然后与数组的第一个元素进行交换。然后在剩余的数组中再继续寻找数值最小的数,与当前第一个元素交换位置(除去已排序的元素)。这种方法我们称之为选择排序。
代码片
# 选择排序-python
def selectSort(a):
lens = len(a)
for i in range(lens - 1): # 最后一个数不用再排序
mina = i # 设当前的数为最小数
for j in range(i, lens): # 除去已排好序的数字,所以从i开始
if a[mina] > a[j]: mina = j # 与最小的数进行比较,若比其还小就替换min
a[i], a[mina] = a[mina], a[i] # 交换
return a
//选择排序-go
func selectSort(a []int) []int{
lens := len(a)
for i:=0; i<lens; i++ {
mina := i
for j:=i; j<lens; j++{
//i开始,去除以排序的数
if a[mina]>a[j]{
mina=j } //记录最小数的索引
}
a[i],a[mina]=a[mina],a[i] //交换最小值到起始位置
}
return a
}
性质:
1、时间复杂度:O(n2) (遍历两次数组)
2、空间复杂度:O(1)
3、非稳定排序 (跳跃式交换位置,原来的排序会被打乱)
4、原地排序 (没有引用额外的数据结构)
2、插入排序
1、从数组第2个元素开始抽取元素。
2、把它与左边第一个元素比较,如果左边第一个元素比它大,则继续与左边第二个元素比较下去,直到遇到不比它大的元素,然后插到这个元素的右边。
3、继续选取第3,4,….n个元素,重复步骤 2 ,选择适当的位置插入。
代码片
# 2.插入排序-python
def insertSort(arr):
if not arr or len(arr)<2:return arr
# 插入排序是从第二个数开始,因此要过滤掉空数组和单个元素的数组。以免后续数组下标越界
n=len(arr)
for i in range(1,n):
temp=arr[i] # 保存需要更换的数值
k=i-1 # 向前查找
while k>=0 and arr[k]>temp: # 向前找到应该插入的位置
k-=1
for j in range(i,k,-1): # 将数据往后移
arr[j]=arr[j-1]
arr[k+1] = temp # 插入数据
return arr
// 2.插入排序-go
func insertSort(arr []int) []int{
if arr ==nil || len(arr)<2{
return arr}
n := len(arr)
for i:=1;i<n;i++{
temp := arr[i]
k := i-1
for k>=0 && arr[k]>temp{
k-- } //找到要插入的点
for j:=i;j>k+1;j--{
arr[j]= arr[j-1] } //将插入点后的数,往后移动
arr[k+1]=temp //将数插入到需插入的位置上
}
return arr
}
性质:
1、时间复杂度:O(n2)
2、空间复杂度:O(1)
3、稳定排序
4、原地排序
3、冒泡排序
1、把第一个元素与第二个元素比较,如果第一个比第二个大,则交换他们的位置。接着继续比较第二个与第三个元素,如果第二个比第三个大,则交换他们的位置….
我们对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样一趟比较交换下来之后,排在最右的元素就会是最大的数。
除去最右的元素,我们对剩余的元素做同样的工作,如此重复下去,直到排序完成。
代码片
# 3.冒泡排序-python
def BubbleSort(arr):
if not arr or len(arr)<2:return arr
n=len(arr)
for i in range(n):
for j in range(n-i-1):
if arr[j]>arr[j+1]:arr[j],arr[j+1] = arr[j+1], arr[j]
return arr
# 建立一个flag信号,用于检测后续的数组是否已经有序了。若是已经有序就直接跳出循环。
# 3.优化冒泡排序
def bubbleSort(arr):
if not arr or len(arr)<2:return arr
n=len(arr)
for i in range(n):
flag=True
for j in range(n-i-1):
if arr[j]>arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
flag=False #只要发生了位置交换,就将flag设为False
if flag:
break
return arr
//3.冒泡排序-go
func BubbleSort(arr []int) []int{
if arr==nil || len(arr)<2{
return arr}
n := len(arr)
for i:=0;i<n;i++{
flag := true