2022計算機考研408—數據結構—排序
手把手教學考研大綱范圍內的排序
22考研大綱數據結構要求的是C/C++,筆者以前使用的都是Java,對于C++還很欠缺,
如有什么建議或者不足歡迎大佬評論區或者私信指出
Talk is cheap. Show me the code.
理論到處都有,代碼加例題自己練習才能真的學會
排序過程步驟顯示
文末投票:下篇22考研數據結構的博客寫什么(歡迎評論區指出)
排序定義
冒泡排序
直接插入排序
二分插入排序
希爾排序?
快速排序
二路歸并排序?
基數排序(附加計數排序)?
簡單選擇排序
堆排序??
排序
排序的基本概念
顧名思義,給一個無序數組的值進行順序存儲
原數組:2 3 1 5 6 4 8 9 7
排序后:1 2 3 4 5 6 7 8 9
冒泡排序
思路:
從頭到尾每兩個相鄰的元素,進行比較,前面的比后面的大就進行交換
循環一遍后,數組元素最大的就到了最后面,
第二次循環的時候,就可以不循環到最后一個了,最后一個上次循環已經是整個數組最大的值了
然后把這次最大的放到倒數第二個元素,
第三次循環的就可以忽略最后兩個元素
以此類推,全部循環后,即可完成排序
#include <iostream>
#include <vector>using namespace std
;void bubbleSort(vector
<int> &num
);
int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}bubbleSort(num
); cout
<< "排序后" << "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void bubbleSort(vector
<int> &num
) {for (int i
= 0; i
< num
.size(); i
++) {for (int j
= 0; j
< num
.size() - i
; j
++) {if (num
[j
] > num
[j
+ 1]) {
num
[j
] ^= num
[j
+ 1]; num
[j
+ 1] ^= num
[j
];num
[j
] ^= num
[j
+ 1];}}for (int j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}cout
<< "\n";}
}
#include <iostream>
#include <vector>using namespace std
;void bubbleSort(vector
<int> &num
);
int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}bubbleSort(num
); for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void bubbleSort(vector
<int> &num
) {int flag
= 1; int arrBoundary
= num
.size() - 1; int largestSwapIndex
= 0; for (int i
= 0; i
< num
.size(); i
++) {flag
= 1;for (int j
= 0; j
< arrBoundary
; j
++) {if (num
[j
] > num
[j
+ 1]) {int temp
= num
[j
];num
[j
] = num
[j
+ 1];num
[j
+ 1] = temp
;flag
= 0; largestSwapIndex
= j
; }}arrBoundary
= largestSwapIndex
; if (flag
) { break;}}}
直接插入排序
思路:
插入 == 把數插進去
也是兩層循環
數組num
第一層循環從下標為1的值開始,循環變量為i
第二層循環就是把第一層的值拿出來,然后從第i-1個向前循環,找到第一個小于 num[i] 的值,
這個值的下標如果是j-1的話,那么 num[j] 就是第一個大于 num[i] 的值
把 num[i] 用一個變量 temp 保存一下
把下標為j到i-1的值依次向后移動一位,也就是說下標j到i-1的值移動到j+1到i,
然后把 temp(原num[i])放到下標為j的地方(之前的num[j]已經移動到num[j+1]了),
按照這種排序,每次循環的都是i之前的,i之前的元素都是順序存儲的,
文字表述的不清楚的可以看每次循環i更改后數組的元素情況
#include <iostream>
#include <vector>using namespace std
;void insertSort(vector
<int> &num
);
int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}insertSort(num
); cout
<< "排序后" << "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void insertSort(vector
<int> &num
) {for (int i
= 1; i
< num
.size(); i
++) {int temp
= num
[i
]; int j
;for (j
= i
- 1; j
>= 0 && num
[j
] > temp
; j
--) {num
[j
+ 1] = num
[j
];}num
[j
+ 1] = temp
;for(j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}cout
<<"\n";}
}
運行截圖:
二分插入排序
思路:
二分插入和簡單插入基本類似
不過是在尋找插入位置的時候不在采用簡單插入的循環查找,而是使用二分查找
減少比較的次數,提升效率
#include <iostream>
#include <vector>using namespace std
;void binInsertSort(vector
<int> &num
);
int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}binInsertSort(num
); cout
<< "排序后" << "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void binInsertSort(vector
<int> &num
) {for (int i
= 1; i
< num
.size(); i
++) {int temp
= num
[i
]; int left
= 0; int right
= i
- 1;while (left
<= right
) {int mid
= (left
+ right
) / 2;if (num
[mid
] > temp
) {right
= mid
- 1;} else {left
= mid
+ 1;}}for (int j
= i
- 1; j
>= left
; j
--) {num
[j
+ 1] = num
[j
]; }num
[left
] = temp
; for (int j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}cout
<< "\n";}
}
希爾排序
思路:
希爾排序其實可以看做是插入排序的變種
插入排序是循環到某個元素就像前找合適的位置,把當前元素到合適位置的值都要向后移動一遍
插入排序對于有序的數組,比較和移動的次數都比較少
希爾排序就是把插入排序進行分組化
分組是按照長度每次除2分的,這樣最后一次肯定是一個組一個元素,就相當于最原始的插入排序了
而他前面做的按組排序就是為了讓這個數組變成一個有大概順序的數組,使后面的插入排序能減少比較和移動的次數
按下圖為例子,數組長度
15 第一次按照
7個增量分組,第二次按照
3個增量,第三次按照
1個增量分組第一次循環的增量為
7
第一次是下標
0 與
0+7比較
1與
1+7比較 ……
7 與
7+7比較
第一次循環完,這些位置上有了個大概的順序第二次循環的增量為
3
第二次是下標
0與
3與
6與
9與
12比較
1與
4與
7與
10與
13 2與
5與
8與
11與
14
第二次循環完,這些位置上有了大概的順序第三次循環的增量為
1
就相當于簡單的插入排序
希爾排序的精髓就在于,對于一個大概有序的數組,插入排序的比較和移動次數都比較少
PS:小編作圖能力有限,上圖是當來的
#include <iostream>
#include <vector>using namespace std
;void shellSort(vector
<int> &num
);int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}shellSort(num
); cout
<< "\n\n排序后" << "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void shellSort(vector
<int> &num
) {int len
= num
.size();for (int d
= len
/ 2; d
> 0; d
/=2) { cout
<< "\n\n增量為" << d
;for (int i
= d
; i
< len
; i
++) { cout
<< "\n此次排序的下標為:" << i
;for (int j
= i
- d
; j
>=0; j
-=d
) {cout
<< " " << j
;if (num
[j
] > num
[j
+ d
]) { int temp
= num
[j
];num
[j
] = num
[j
+ d
];num
[j
+ d
] = temp
;}}cout
<< "\n";for (int j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}}}
}
快速排序
思路:
從未排序的數組中,一個一個的尋找,尋找當前值應該在排序后數組的位置,
以此類推,把每個值的位置都確定了以后,此數組就變成了排序后的數組
也是分段進行確定某個值最終排序后的下標
先選取第一個值,用一個臨時變量保存這個值,然后雙指針i表示這段范圍的開頭,j這段范圍的結尾 j負責從后向前找小于臨時變量的值,找到以后就把j的值放到i那,此時j位置就空出來了,我們當作把臨時變量的值放到j這里i負責從前向后找大于臨時變量的值,找到后就放到j那里,此時i位置就空出來了,我們同樣當作把臨時變量的值放到i這里不斷循環這兩步的操作,i是從前向后,j是從后向前循環結束的條件就是i==j 也就是臨時變量排序后數組的位置,按照這種排序方式,結束后,比臨時變量小的都在臨時變量左邊(左邊不一定是排好序的),比臨時變量大的都在臨時變量右邊(右邊不一定是排好序的),也就是說臨時變量當前的下標就是排序后的下標 當前臨時變量的位置確定好以后,我們可以分為前半部分和后半部分繼續這種操作
以此類推,當每個值最終排序后的位置都確定的時候,此數組為排序后的數組
下圖為確定好一個值的最終位置的排序圖
臨時變量為50,左指針low,右指針high
右指針找到20比臨時變量小,交換兩個值
左指針找到90比臨時變量大,交換兩個值
右指針找到40比臨時變量小,交換兩個值位置
左指針找到70比臨時變量小,交換兩個值的位置
右指針左移與左指針重合,當前位置為50排序后的最終位置
我們發現,左邊的數都比50小,右邊的數都比50大,
當前數的位置就是排序后當前數的位置 然后在把左邊的數組按照這種方法,右邊的數組按照這種方法
以此類推每個值的最終下標都確定下來了,數組為排序后的數組
PS:圖仍然是某度當來的o( ̄▽ ̄)ブ
#include <iostream>
#include <vector>using namespace std
;void quickSort(vector
<int> &num
, int left
, int right
);int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}quickSort(num
, 0, num
.size() - 1); cout
<< "\n\n排序后" << "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void quickSort(vector
<int> &num
, int left
, int right
) {if (left
>= right
) return; int temp
= num
[left
]; int l
= left
; int r
= right
;while (left
< right
) { while (left
< right
&& temp
< num
[right
]) { right
--;}if (left
< right
) { num
[left
] = num
[right
]; left
++; } while (left
< right
&& num
[left
] < temp
) { left
++;}if (left
< right
) { num
[right
] = num
[left
];right
--;}}num
[left
] = temp
; cout
<< "\n左邊界下標:" << l
<< " 右邊界下標:" << r
<< " 當前循環確定的下標為:" << left
<< "\n";for (int j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}quickSort(num
, l
, left
- 1); quickSort(num
, left
+ 1, r
);
}
二路歸并排序
思路:
二路歸并,就是把一個數組,先分開,然后在合并的過程中逐步排序
二路就是分開的時候每次分成兩個,分成兩種路
歸并就是把他分開在合上
二路分割數組,一直把數組分割到一路只有一個數為止
然后再把他們兩路合一路,兩路合一路,在合路的過程中把無序的路合成有序的路,慢慢的合成后的路都為有序的路,大致原理如下圖
分路沒有什么說的,一分為,對半分即可
合路的時候,AB兩個路合成C路,分別兩個指針i,j,k對應著A,B,C數組的下標
循環AB兩個數組,每次都比較A[i]與B[j] 取兩個數組中對應值小的放到C[k]
然后k下標右移,i或者j小的下標右移,完全循環后,C==A+B的有序路
#include <iostream>
#include <vector>using namespace std
;void mergeSort(vector
<int> &num
, int left
, int right
);int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}mergeSort(num
, 0, num
.size() - 1); cout
<< "\n\n排序后" << endl
;for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void mergeSort(vector
<int> &num
, int left
, int right
) {if (left
== right
) return; int m
= (left
+ right
) / 2; mergeSort(num
, left
, m
); mergeSort(num
, m
+ 1, right
); int temp
[right
- left
+ 1]; int l
= left
; int r
= m
+ 1; int k
= 0; while (l
<= m
&& r
<= right
) { if (num
[l
] <= num
[r
]) { temp
[k
++] = num
[l
++];} else {temp
[k
++] = num
[r
++];}}while (l
<= m
) {temp
[k
++] = num
[l
++];}while (r
<= right
) {temp
[k
++] = num
[r
++];}for (int i
= left
, k
= 0; i
<= right
; i
++, k
++) {num
[i
] = temp
[k
];}cout
<< "此次合并的是下標:" << left
<< "-" << right
<< "\n";for (int j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}cout
<< "\n";
}
Acwing,這個題就是歸并排序
788. 逆序對的數量給定一個長度為 n 的整數數列,請你計算數列中的逆序對的數量。逆序對的定義如下:對于數列的第 i 個和第 j 個元素,如果滿足 i
<j 且 a
[i
]>a
[j
],則其為一個逆序對;否則不是。輸入格式
第一行包含整數 n,表示數列的長度。第二行包含 n 個整數,表示整個數列。輸出格式
輸出一個整數,表示逆序對的個數。數據范圍
1≤n≤
100000,
數列中的元素的取值范圍
[1,109]。輸入樣例:
6
2 3 4 5 6 1
輸出樣例:
5#include <iostream>
#include <vector>using namespace std
;void mergeSort(vector
<int> &num
, int left
, int right
);int res
= 0;
int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}mergeSort(num
, 0, num
.size() - 1); cout
<< res
;return 0;
}void mergeSort(vector
<int> &num
, int left
, int right
) {if (left
== right
) return; int m
= (left
+ right
) / 2; mergeSort(num
, left
, m
); mergeSort(num
, m
+ 1, right
); int temp
[right
- left
+ 1]; int l
= left
; int r
= m
+ 1; int k
= 0; while (l
<= m
&& r
<= right
) { if (num
[l
] <= num
[r
]) { temp
[k
++] = num
[l
++];} else {temp
[k
++] = num
[r
++];res
+= m
- l
+ 1; }}while (l
<= m
) {temp
[k
++] = num
[l
++];}while (r
<= right
) {temp
[k
++] = num
[r
++];}for (int i
= left
, k
= 0; i
<= right
; i
++, k
++) {num
[i
] = temp
[k
];}}
基數排序
說基數排序之前,先大概說一下計數排序
計數排序
計數排序就是把元素的值當作下標使用,數量用那個下標對應的值記錄
例如int num[]={5,2,1,4,3,2,1,2,6,4,1,2,5,2}
這樣的數組我們就用計數排序
count的長度是上面數組的最大值-最小值+1或者最大值-最小值+1
循環上面的數組 count[num[i]]++;
到時候判斷這個值存不存在,直接判斷count[值]是否大于0
顯而易見,計數排序的缺點就是如果數組中最大值很大,那么這個效率會很低
leetcode 計數排序例題
1122. 數組的相對排序
給你兩個數組,arr1 和 arr2,arr2 中的元素各不相同
arr2 中的每個元素都出現在 arr1 中
對 arr1 中的元素進行排序,使 arr1 中項的相對順序和 arr2 中的相對順序相同。未在 arr2 中出現過的元素需要按照升序放在 arr1 的末尾。示例:輸入:arr1
= [2,3,1,3,2,4,6,7,9,2,19], arr2
= [2,1,4,3,9,6]
輸出:
[2,2,2,1,4,3,3,9,6,7,19]提示:
1 <= arr1
.length
, arr2
.length
<= 1000
0 <= arr1
[i
], arr2
[i
] <= 1000
arr2 中的元素 arr2
[i
] 各不相同
arr2 中的每個元素 arr2
[i
] 都出現在 arr1 中
class Solution {
public:vector
<int> relativeSortArray(vector
<int>& arr1
, vector
<int>& arr2
) {int upper
= *max_element(arr1
.begin(), arr1
.end());vector
<int> count(upper
+ 1);for (int x
: arr1
) {++count
[x
];}vector
<int> ans
;for (int x
: arr2
) {for (int i
= 0; i
< count
[x
]; ++i
) {ans
.push_back(x
);}count
[x
] = 0;}for (int x
= 0; x
<= upper
; ++x
) {for (int i
= 0; i
< count
[x
]; ++i
) {ans
.push_back(x
);}}return ans
;}
};
再回來說基數排序
基數排序也是大概這個意思,不過不是直接把值當作下標,而是把值的每一位當作下標排序
這個也需要保存一下最大值,因為要判斷最高有多少位。
先把個位放進去,排序,再把十位放進去排序,然后……
把個位放進去后,就按照個位排序好了,把數取出,記得按照順序取出, 然后十位放進去排序,把數按順序取出……
思路大概就是這樣
順序放入順序取出,在進行下一位的排序
PS:
如果是Java的話,直接用一個ArrayList[] temp; 這種數組就可以
PS:當來的圖片
#include <iostream>
#include <vector>using namespace std
;void radixSort(vector
<int> &num
);int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}radixSort(num
); cout
<< "\n\n排序后" << endl
;for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void radixSort(vector
<int> &num
) {int max
= -1;for (int i
= 0; i
< num
.size(); i
++) {max
= max
< num
[i
] ? num
[i
] : max
;}int temp
[num
.size()];int count
[10] = {0};for (int i
= 0; i
< num
.size(); i
++) {temp
[i
] = 0; }for (int places
= 1; places
<= max
; places
*= 10) { for (int i
= 0; i
< num
.size(); i
++) {count
[(num
[i
] / places
) % 10]++; } for (int i
= 1; i
< 10; i
++) {count
[i
] = count
[i
- 1] + count
[i
];}for (int i
= num
.size() - 1; i
>= 0; i
--) {int k
= (num
[i
] / places
) % 10; temp
[count
[k
] - 1] = num
[i
]; count
[k
]--; }for (int i
= 0; i
< 10; i
++) {count
[i
] = 0;}for (int i
= 0; i
< num
.size(); i
++) {num
[i
] = temp
[i
];}cout
<< "\n哪一位是1,此次排序就是排的哪一位 " << places
<< "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " ";}}}
簡單選擇排序
思路:
簡單選擇排序,顧名思義,簡單的選擇一個元素排序
兩層循環,第一層循環就是循環每一位
第二層循環,定義臨時變量保存當前下標,循環后面每一位,
如果找到比當前下標對應的值小的,那么就用這個變量保存這個值小的下標,一直循環到結束
第一層循環結束后,變量保存的就是整個數組最小的值的下標,與第一位交換,第一位就是最小的值
如此往復,第二次循環,就從第二位開始向后找,記錄除第一位最小的值的下標,循環結束后與第二位進行交換
以此類推,循環后即可完成排序。
#include <iostream>
#include <vector>using namespace std
;void selectSort(vector
<int> &num
);int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}selectSort(num
); cout
<< "排序后" << "\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void selectSort(vector
<int> &num
) {for (int i
= 0; i
< num
.size(); i
++) { int temp
= i
; for (int j
= i
+ 1; j
< num
.size(); j
++) { if (num
[j
] < num
[temp
]) {temp
= j
;}}int n
= num
[i
]; num
[i
] = num
[temp
]; num
[temp
] = n
;for (int j
= 0; j
< num
.size(); j
++) {cout
<< num
[j
] << " ";}cout
<< "\n";}
}
運行結果如下:
堆排序
思路:
首先要強調一下,堆排序并不是要構成一個堆,它本身還是個數組,只不過是我們在排序的時候把他看成一個堆,他實際上還是一個數組
我們這里用到的堆是大根堆和小根堆,他們都是完全二叉樹
完全二叉樹就是他們結點位置和滿二叉樹的位置是一樣的
紅色角標為真實數組的下標
PS:圖片來源
這是大根堆和小根堆
完全二叉樹和滿二叉樹基本相同
每一層的數量都是上一層的二倍
某一層最左邊結點下標*2就是最右邊結點下標
完全二叉樹中子結點和父結點之間還有一些顯著的關系
一個數的下標為x
他的父節點下標為(x - 1)/ 2 這里的除2是計算機除2,不保存余數,整除不成為小數
他的左子結點為 2 * x + 1
他的右子結點為 2 * x + 2
如果還不明白,可以自己帶個結點試一下(看堆分析容易理解)
(左子結點-1)/2就是父節點 (右子結點 - 1)/2也是父節點,它除2的時候會把余數直接省去
大根堆就是 父節點 > 左子結點 并且 父節點 > 右子結點
小根堆就是 父節點 < 左子結點 并且 父節點 < 右子結點
構建大根堆只是思想構建,不是實際構建,實際還是數組
先把數組構建成大根堆,大根堆不一定是有序的,但一定是符合大根堆的規律,父結點一定比子結點大,全部構建好(構建大根堆,一定要從下向上構建,如果無序直接從上向下構建,有的會不符合大根堆定義)
默認葉子結點為排好序的堆(葉子結點沒有子結點,只有一層,符合大跟堆得特征)
先添加非葉子結點,逐步向上添加
如果從上到下結點添加,葉子結點為有序堆,上到下添加會把有序堆打散,無法完成堆排序
完全二叉樹的特點,n個結點,最后一個非葉子結點二叉樹為(n/2)下標為(n/2-1),逐步向上添加
構建好大根堆后,轉換成小根堆
轉換小根堆的步驟,先把大根堆最大的(也就是堆頂)與最后面的結點換位置,這樣能保證最大的在最后面,也就是說,數組第一位與最后一位交換
交換完,小的就到了最上面,把剛交換完最大的固定不動,其他的重新構建大根堆
此時最大的在最后面,其他的仍然是大根堆
第二次的時候,把當前大根堆最大的值(當前堆頂)與倒數第二位交換(倒數第一位是剛才的堆頂,最大的,已經固定了,保持不變),最小的又到了堆頂,繼續重建大根堆
如此往復,大根堆就變成了小根堆,此時的小根堆就是有序的
#include <iostream>
#include <vector>using namespace std
;void heapSort(vector
<int> &num
);void heapBuild(vector
<int> &num
, int fatherIndex
, int len
);int main() {int n
; cin
>> n
; vector
<int> num
; int temp
; for (int i
= 0; i
< n
; i
++) {cin
>> temp
; num
.push_back(temp
);}heapSort(num
); cout
<< "\n\n排序后" << endl
;for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " "; }return 0;
}void heapSort(vector
<int> &num
) {for (int i
= num
.size() / 2 - 1; i
>= 0; i
--) { heapBuild(num
, i
, num
.size()); }cout
<< "構建完大根堆后的數組\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " ";}int len
= num
.size();while (len
> 1) {int temp
= num
[0];num
[0] = num
[len
- 1];num
[len
- 1] = temp
;len
--; heapBuild(num
, 0, len
); cout
<< "\n下標:"<< len
<< " 值:" << num
[len
] <<" 確定好位置了\n";for (int i
= 0; i
< num
.size(); i
++) {cout
<< num
[i
] << " ";}}
}void heapBuild(vector
<int> &num
, int fatherIndex
, int len
) {int left
= fatherIndex
* 2 + 1;int right
= fatherIndex
* 2 + 2;while (left
< len
) {int largestIndex
; if (num
[left
] < num
[right
] && right
< len
) {largestIndex
= right
;} else {largestIndex
= left
;}if (num
[largestIndex
] < num
[fatherIndex
]) { largestIndex
= fatherIndex
;break;}int temp
= num
[largestIndex
];num
[largestIndex
] = num
[fatherIndex
];num
[fatherIndex
] = temp
;fatherIndex
= largestIndex
;left
= fatherIndex
* 2 + 1;right
= fatherIndex
* 2 + 2;}
}
總結
以上是生活随笔為你收集整理的22计算机408考研—数据结构—排序(详解加例题)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。