龜哥今天和大家分享下快速排序,堆排序算法。
首先快速排序的思想,給定一個無序的數組,首先用兩個指針left和right分別指向數組的頭部和尾部,將數組的第一個元素array[0]作為和left,right指針比較的元素。如果將無序的數組排列成從小到大的有序數組的話,首先right指針array[array.length-1]數組的最後一個元素,array[array.length-1]和array[0]進行比較,如果array[array.length-1]>array[0],則右指針往左移,直到找到一個元素比array[0]小的元素,跳出循環。同理做指針與array[0]比較,直到找到一個比array[0]大的跳出循環,然後進行交換,小於array[0]在左邊,大於array[0]的在右邊,最後是遞歸調用函數。那龜哥踩過的坑是沒有判斷
if(low>high){ return; }造成執行錯誤的情況。核心代碼:
while(i<j) {
while(temp<=array[j]&&i<j) {
j--;}
while(temp>=array[i]&&i<j) {
i++;}
if(i<j) {
int t=array[j];
array[j]=array[i];
array[i]=t;} }
array[low]=array[i];
array[i]=temp;
func(array,low,j-1);
func(array,j+1,high);
第二個龜哥分享的是堆排序,它的思想首先建堆,然後堆排序。初始建堆:
for(int i=(array.length-2)/2;i>=0;i--) {
adjustDownToUp(array,i,array.length); }初始建堆的時候我們從最後一個非葉子節點開始,調用調整堆adjustDownToUp的函數。
public static void adjustDownToUp(int[] array, int k, int length) {
int temp=array[k]; //首先拿到依次拿到非葉子節點的數據
for(int i=2*k+1;i<length-1;i=2*i+1) {
if(i<length && array[i]<array[i+1]) {//如果父節點的左節點的值大於右節點的值
i++; }
if(temp>array[i]) {//如果父節點的值大於任何一個節點的值,符合大頂堆,不再進行比較
break;
}else {
array[k]=array[i];//如果父節點的值不大於較大節點的值,把較大節點的值賦值給k
k=i;//把i的索引賦值給k索引} }
array[k]=temp;//然後將父節點k賦值給i的索引。}
初始堆構建完成後,最後一步是堆排序,初始堆中根節點是最大值,把這個最大值放到有序數列中,和最後一個葉節點進行交換,就是說交換後最後一個節點i之前的數據都是無序的,需要重新進行構建,然後根節點又找到一個,和i-1進行交換,知道n-1次交換完成,直至使變成有序數組。
for(int i=array.length-1;i>1;i--) {
//找到根節點的最大值與array[0]進行交換
int temp=array[0];
array[0]=array[i];
array[i]=temp;
adjustDownToUp(array,0,i);}
好了 龜哥的分享就到這了,又什麼問題可以留言呀