一、快排
》快排方法,就三步
1.隨便選一個值作為基準值x
2.拿選中的這個x值劃分隊列為左右兩個區間(左邊的都小于x,右邊的都大于x)
3.然后遞歸左區間和右區間就行
》代碼舉例:
#qs排序#1 6 7 8 6 5 4
#先找比較點,再劃分區間,再遞歸---遞歸注意遞歸終止條件
#關鍵劃分區間:一開始l,r都在邊界外,然后q[i]<x i++;q[j]>x j--;
#易錯點:1.將x賦值為索引,而不是具體的值---導致在使用的過程中,索引對應的值一直在變化
#2.忘記i,j的賦值
#3.遞歸調用的時候,選擇應該是l,j和j+1到r,因為注意會有j<r的情況發生,如果選擇是l,i和i+1,r
#就會對應重復的比如2,2,那么就會不斷的滿足遞歸,進而不斷的使用遞歸,無法終止n=1e5+10def qs(l,r,q):if l>=r:returnx=q[(l+r)//2]i=l-1j=r+1while i<j:i+=1while q[i]<x:i+=1j-=1while q[j]>x:j-=1if i<j:q[i],q[j]=q[j],q[i]qs(l,i,q)qs(i+1,r,q)n=int(input())
q=[0]
q.extend(list(map(int,input().split())))
qs(1,n,q)
for i in range(1,n+1):print(q[i],end=" ")
或者看圖片比較清晰:
二、歸并排序
》歸并方法,也是三步
1.首先同樣是排序的套路 確定分界點
2.遞歸左半邊 、右半邊
3合并(這個合并其實就是設計一個k,去存放當前merge的左邊和右邊的合并【同時排序】結果)
//合并這一步,隊列k,是由原隊列依次從L和mid+1開始,依次右移比較最小的,就放到k里面,最后得到的k隊列這就是合并的結果
》代碼舉例:
#先選中值,然后左右遞歸,然后合并
#關鍵點:合并,使用另外一個數組去存最終的結果,并賦值給(更新)原數組---這一步很容易忘記
#易錯點:1像排序這種問題,一般都要寫個終止條件
#2像排序這種問題,最忌直接將傳入的參數l,r直接進行操作,而是將其分別賦給i,j,萬一
#后面你要操作也是對i,j進行操作,而不是對傳入的參數l,r進行操作,防止影響后面的遞歸等等
#3.推薦以后左邊的字母換成L,因為小寫的l和1不好區分
#4注意對于歸并來說要將最后的另外一個數組去賦給原數組,即不斷的更新原數組,進而使得
#在遞歸的時候,是已經排好序的數組,而不是仍為亂序的q
#5同時注意在給將k給q數組賦值的時候,q的起始值是要從L開始,而不是從1開始,因為根據遞歸傳入的
#參數不同,L是時刻在變化的N=1e5+10def merge(l,r,q):if l>=r:returnmid=(l+r)//2merge(l,mid,q)merge(mid+1,r,q)i=lj=mid+1k=[0]if i<j:while i<=mid and j<=r:if q[i]<q[j]:k.append(q[i])i+=1else:k.append(q[j])j+=1while i<=mid:k.append(q[i])i+=1while j<=r:k.append(q[j])j+=1for i in range(l,r+1):q[i]=k[i-l+1]n=int(input())
m=[0]
m.extend(list(map(int,input().split())))
#print(m)
merge(1,n,m)
for i in range(1,n+1):print(m[i],end=" ")
》當然也可以看這個圖片更舒服一點