voidHeapSort(vector<int>& vec) { int length = vec.size();
//构建初始堆 for( int i = length / 2 - 1; i >= 0; i-- ) //从最后一个非叶子节点开始到根节点,从下往上构建堆,1️⃣ { AdjustHeap(vec, i, length - 1); //第三个参数表示堆最后元素的索引,构建初始堆时,堆规模不需要变,所以都用length-1就行 }
for( int i = length - 1; i > 0; i-- ) //i表示每次待确认的元素索引,从最后一个元素到第二个元素 { swap(vec[0], vec[i]); //堆顶元素和待确认元素进行交换 AdjustHeap(vec, 0, i - 1); //堆规模变成从第一个元素到待确认元素的前一个元素 } }
voidAdjustHeap(vector<int>& vec, int start, int end)//end主要就是为了判断子节点是否存在 { int current = start; int left = 2 * current + 1; //2️⃣ int right = 2 * current + 2;
int largestChild = left; //先默认子节点之间左节点最大
while( left <= end ) //子树存在 { if( right <= end && vec[right] > vec[left] ) //right<=end,右节点存在 { largestChild = right; }
2️⃣ int left = 2 * current + 1; int right = 2 * current + 2;
索引为 i 的元素位于第 n 层,第 n 层位于该元素前面的元素个数为 x 个。假设索引为 i 的元素是第y个,y 就等于第1层到第 n-1 层所有的节点数+x+1,即 $\color{blue}{y=(2^{0}+2^{1}+\cdots+2^{n-1})+x+1}$,通过等比数列求和公式 $\color{blue}{S_{n}=\cfrac{a_{1} *\left(q^{n}-1\right)}{q-1}}$ 可以得到 $\color{blue}{y=(2^{n-1}-1)+x+1}$。因为i是y的索引,$\color{blue}{i=y-1}$,所以$\color{blue}{i=2^{n-1}-1+x}$;