https://blog.csdn.net/weiwenhp/article/details/8621049
void MergeSortIteration(int A[], int len) // 非遞歸(迭代)實現的歸併排序(自底向上)
{
int left, mid, right;// 子數組索引,前一個爲A[left...mid],後一個子數組爲A[mid+1...right]
for (int i = 1; i < len; i *= 2) // 子數組的大小i初始爲1,每輪翻倍
{
left = 0;
while (left + i < len) // 後一個子數組存在(需要歸併)
{
mid = left + i - 1;
right = mid + i < len ? mid + i : len - 1;// 後一個子數組大小可能不夠
Merge(A, left, mid, right);
left = right + 1; // 前一個子數組索引向後移動
}
}
}
當我們利用left mid right 進行步長i遞增的時候,如果設right=mid+i如果要保證left到mid mid+1到right 兩個隊列數目相等。那麼這個mid就必須爲mid=left+i-1.。直觀的來講如果mid=left+i 。那麼左隊列就有1(left本身) 加i個,右隊列只有i個,不對等。所以在約束定義爲“:左隊列爲left到mid 右隊列 mid+1到right 時,應該用mid=left+i-1,right=mid+i,來保證左右隊列皆爲i個元素。或者用mid=left+i right=mid+i+1來保證左右隊列各i+1各元素。很顯然在歸併排序中,應該使用最小粒度的分組,即爲前者。
int Partition(int A[], int left, int right) // 劃分函數
{
int pivot = A[right]; // 這裏每次都選擇最後一個元素作爲基準
int tail = left - 1; // tail爲小於基準的子數組最後一個元素的索引
for (int i = left; i < right; i++) // 遍歷基準以外的其他元素
{
if (A[i] <= pivot) // 把小於等於基準的元素放到前一個子數組末尾
{
Swap(A, ++tail, i);
}
}
Swap(A, tail + 1, right); // 最後把基準放到前一個子數組的後邊,剩下的子數組即是大於基準的子數組
// 該操作很有可能把後面元素的穩定性打亂,所以快速排序是不穩定的排序算法
return tail + 1; // 返回基準的索引
}
在以上編碼中
int tail = left - 1; 與
Swap(A, ++tail, i);