1.排序
排序算法 | 时间复杂度 | 是否基于比较 |
---|---|---|
冒泡、插入、选择 | O ( n 2 ) O(n^2) O(n2) | true |
快排、归并 | O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)) | true |
桶、计数、基数 | O ( n ) O(n) O(n) | false |
Question:插入排序和冒泡排序的时间复杂度都是 O ( n 2 ) O(n^2) O(n2),但实际开发中为什么更倾向于使用插入排序而不是冒泡排序?
冒泡排序每次交换需要三次赋值操作,而插入排序只用一次。
分析一个算法要从哪些方面入手呢?
1.最好最坏平均情况时间复杂度
2.时间复杂度的系数、常数、低阶
3.比较次数和交换(移动)次数
排序算法的内存消耗:
原地排序:特指空间复杂度是O(1)的排序算法。
排序算法的稳定性:
待排序的序列中存在值相等的元素,经过排序后相等元素之间原有的先后顺序不变。
1).冒泡排序
'''冒泡排序'''
def bubble_sort(int_arr):
n=len(int_arr)
if(n<=1):
return int_arr
while(n>0):
i=0
flag=False
while(i<n-1):
if(int_arr[i]>int_arr[i+1]):
temp=int_arr[i]
int_arr[i]=int_arr[i+1]
int_arr[i+1]=temp
flag=True
i+=1
if(flag==False):
break
n-=1
return int_arr
2). 插入排序
'''插入排序'''
def insertion_sort(int_arr):
n=len(int_arr)
if(n<=1):
return int_arr
i=1
while(i<n):
j=i-1
value=int_arr[i]
while(j>=0):
if(value<int_arr[j]):
int_arr[j+1]=int_arr[j]
j-=1
else:
break
int_arr[j+1]=value
i+=1
return int_arr
3). 选择排序
'''选择排序'''
def selection_sort(int_arr):
n=len(int_arr)
if(n<=1):
return int_arr
i=0
while(i<n):
value = i
j=i+1
while(j<n):
if(int_arr[j]<int_arr[value]):
value=j
j+=1
temp=int_arr[i]
int_arr[i]=int_arr[value]
int_arr[value]=temp
i+=1
return int_arr
4).归并排序:
先把一个数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,然后整个数组就有序了。
归并排序使用的是分治思想。分治是一种解决问题的处理思想,递归式一种编程技巧。
归并递推公式:merge_sort(p…r) = merge(merge_sort(p…q) , merge_sort(q+1,r))
'''归并排序'''
def merge(int_arr_1, int_arr_2):
n1=len(int_arr_1)
if(n1<1):
return int_arr_2
n2=len(int_arr_2)
if(n2<1):
return int_arr_1
int_arr=[]
i=0
j=0
while(i<n1 and j<n2):
if(int_arr_1[i]<int_arr_2[j]):
int_arr.append(int_arr_1[i])
i += 1
else:
int_arr.append(int_arr_2[j])
j += 1
while(i<n1):
int_arr.append(int_arr_1[i])
i += 1
while (j < n2):
int_arr.append(int_arr_2[j])
j += 1
return int_arr
def merge_sort(int_arr):
n=len(int_arr)
if(n<=1):
return int_arr
'''//除取整'''
middle=n//2
left= merge_sort(int_arr[:middle])
right=merge_sort(int_arr[middle:])
return merge(left,right)
5).快速排序:
快排:选任意一个数据作为Pivot(分区点),将数据分为三部分,直到有序。
快速排序递推公式:quick_sort(p…r) = quick_sort(p…q-1) + quick_sort(q+1…r)
'''快速排序'''
def quick_sort(int_arr,start,end):
left=start
right=end
if(left>=right):
return int_arr
key=int_arr[left]
while(left < right):
while (left < right) and (int_arr[right] >= key):
right -= 1
int_arr[left]=int_arr[right]
while(left < right) and (int_arr[left] <= key):
left += 1
int_arr[right]=int_arr[left]
int_arr[left]=key
quick_sort(int_arr,start,left-1)
quick_sort(int_arr,left+1,end)
6).线性排序
线性排序的时间复杂度是线性的。包括:桶排序、计数排序、基数排序
桶排序:将要排序的数据分到几个有序的桶中,再对桶中的数据进行排序,最后依次取出,结果就是有序的了。
桶排序比较适用于外部排序中。所谓的外部排序就是数据存储在外部磁盘中,数据量较大,内存有限,无法将数据全部加载到内存中。
计数排序:可看作是桶排序的一种特殊情况。当要排序的n个数据所处的范围并不大的时候。例如最大值是k,可以把数据划分为k个桶,这样就可以省略桶内排序的时间。
基数排序:如给手机号按大小排序。先根据最后一位排序,在根据倒数第二位,经过十一次排序后就是有序的了。例二:给不同单词排序。可以给单词末位补0。