python冒泡排序
说实话,做过快排后比较起冒泡排理解起来容易很多。。
冒泡排每次都会遍历都会找出一个最大值。
代码来源菜鸟教程,不是懒得写代码,是因为人家写的标准
递增式冒泡排
def bubbleSort(arr):
n=len(arr)
for i in range(n):
for j in range(0,n-i-1):
if arr[j]>arr[j+1]:
arr[j],arr[j+1]=arr[j+1],arr[j]
arr=[64, 34, 25, 12, 22, 11, 90]
bubbleSort(arr)
这里j的最后遍历到的位置: n-i-1 ,我理解是i=0时,遍历到n-1,排好一个数,排好的数下次不需要遍历
先遍历第i个元素,在嵌套for遍历做AB BC CD形式的比较。
递减式冒泡排
看某佬哥做了一道蓝桥杯的冒泡排,写了种逆向排
佬哥的代码
def bubble_sort(arr):
num = 0
for i in range(len(arr)-1,0,-1):
for j in range(i):
if arr[j] > arr[j+1]:
num += 1
arr[j],arr[j+1] = arr[j+1],arr[j]
return num
print(bubble_sort(list('jonmlkihgfedcba')))
代码审计: 这里的for里的i遍历从 len(arr)-1 开始,排好一个数,下次不需要遍历。
字符串的长度为15,首次遍历就是 range(14,0,-1),从后遍历;第二个j从0开始遍历到14,递减式的冒泡排。
分区间式快排
python 快排
这段快排是从菜鸟教程摘过来的。觉得写的很不错,仅仅为了学习排序,并没想过实用,因为效率比不上sort
def partition(arr,low,high):
i=(low-1)
pivot=arr[high]
for j in range(low , high):
if arr[j] <= pivot:
i = 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)
假设数组为
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr,0,n-1)
我比较无脑,看到上面的算法没有头脑,就把他列了一遍
low=0=j,high=5
arr[4]<high : arr[0],arr[4]=arr[4],arr[0]
1,7,8,9,10,5
low=1=j,high=5: arr[1],arr[5]=arr[5],arr[1]
1,5,8,9,10,7
low=2=j.high=5: arr[2],arr[5]=arr[5],arr[2]
1,5,7,9,10,8
low=3=j.high=5: arr[3],arr[5]=arr[5],arr[3]
1,5,7,8,10,9
low=4=j.high=5: arr[4],arr[5]=arr[5],arr[4]
1,5,7,8,9,10
这段代码是我吧上面的
arr[i+1],arr[high] = arr[high],arr[i+1]
return ( i+1 )
放到那个for里跑,后面发现不在循环里。但观察了下值,问题不大。。
观察了一晚上和一早上,按我的理解,这个过程是这样的。
第一次比较,high=5,这个值在循环是一个定值,不变的,arr[4]<5,所以和arr[0]换位置,这里换位置只是模糊换,不代表arr[0]>arr[4]…
arr[4]<high : arr[0],arr[4]=arr[4],arr[0]
1,7,8,9,10,5
然后 i的值是一直加的,在def函数里面。所以在不满足 if arr[j] <= pivot:
时
他的区间就限制的很小,这里就有点精准排序了,这个我找到的快排的最重要的点。
arr[i+1],arr[high] = arr[high],arr[i+1]
return ( i+1 )
看这里,排序后的值为1,7,8,9,10,5
arr[4]<high : i=0 ,arr[0],arr[4]=arr[4],arr[0]
1,7,8,9,10,5
return (i+1)
但你在7开始后找不到比5小的数,所以5肯定最小,但7可能不是最大。
low=1=j,high=5: arr[1],arr[5]=arr[5],arr[1]
1,5,8,9,10,7
return (i+1)
所以接着来
i++,你在8后找不到比7小的数,所以7最小,但8可能不是最大,最后缩小区间排满。
low=2=j.high=5: arr[2],arr[5]=arr[5],arr[2]
1,5,7,9,10,8
return (i+1)
他这里原代码是通过不满足if后通过i的值分段。
quickSort(arr, low, pi-1)
quickSort(arr, pi+1, high)
但说实话有点思路有点乱,小结就是
1.if函数做模糊排序,大致排序。
2.不满足if,通过缩小区间做精准排序。
当然还有C++的写法,但那个是比较两个值,左一个i,右一个j,写起来更复杂,会python快排应该够用了。
**
无脑之选择排序
菜鸟教程的代码
假设数组A=[22,25,23,21,11]
for i in range(len(A)):
min_idx = i
for j in range(i+1, len(A)):
if A[min_idx] > A[j]:
min_idx = j
A[i], A[min_idx] = A[min_idx], A[i]
我这只需要知道他的遍历到时候就能写出来:
首先遍历第一个元素
A=[22,25,23,21,11]
i=0
min_idx=0
21<22
min_idx=3
11<21
min_idx=4
arr[0],arr[4]=arr[4],arr[0]
A=[11,25,23,21,22]
思路就是:21肯定比22小,但11比21还小,结果肯定最小
#遍历第二个元素
i=1,min_idx=1
23<25
min_idx=2
21<23
i=2,min_idx=3
arr[1],arr[3]=arr[3],arr[1]
A=[11,21,23,25,22]
这个遍历很容易,思路参考上面快排,
22向后找到21,22>21,不着急换位置,用21和剩下的比较,找到最小的数,这个数在这个位置上就是最小(这个位置是我摸索出来的重点 ),
遍历一次出现一个最小数,(比后面的都小)。遍历结果结果就出来了,唯一注意的一个点就是 上面代码min_idx = j ,arr[j]是原数列的值,并没有做替换,
无脑之插入排序
def insertionSort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
arr = [12, 11, 13, 5, 6]
insertionSort(arr)
这里主要看while这里 , key<arr[j],j用来遍历前面的值,key表当前遍历的元素值
如果key和前面的值比较,比前面的值小替换,通过每执行一次while就会有j–,比如这里这个key为5时,这就是这个排序就重要的一点。
谈若不满足while ,key>=arr[j],那arr[j+1]=key这个位置就没要替换。
12,11,13,5,6
key=11 ;j=0
12>11;arr[1]=arr[0];j=-1
arr[0]=11
11,12,13,5,6
key=13,j=12
arr[2]=13
key=5,j=13
13>5 ;arr[3]=arr[2],11,12,5,13,6
12>5,arr[2]=arr[1].11,5,12,13,6
11>5,arr[1]=arr[0] 5,11,12,13,6