編程珠璣之快速排序

我們將需要劃分的目標區間定位[l, u]。
首先給定目標值t = x[l]。我們需要重新組織x[l...u],使得所有小於t的元素都在m的一端,所有大於t的元素在m的另一端。
初始時m = l,我們將i從l+1一直遍歷到u,代碼在檢測第i個元素時必須考慮兩種情況。如果x[i]>=t,那麼一切正常,不變式爲真;如果x[i]<t,可以通過使m增加1(指向小元素的新位置)重新獲得不變式,然後交換x[i]和x[m]。

void q_sort_ori(int *a, int low, int high){
	if (low < high){
		int m = low;
		for(int i = low + 1; i <= high; i++){
			int tmp = a[i];
			if(tmp < a[low]){
				swap(a[++m],a[i]);
			}
		}
		swap(a[m],a[low]);
		for(int i = 0; i <= 7; i++)
			cout<<a[i]<<" ";
		cout<<endl;
		q_sort_ori(a,low,m-1);
		q_sort_ori(a,m+1,high);

	}
}
下標i和j初始化爲待劃分數組的兩端。主循環中有兩個內循環,第一個內循環將i向右移過小元素,遇到大元素時停止;第二個內循環將j向左移過大元素,遇到小元素時停止。然後主循環測試這兩個下標是否交叉並交換它們的值。這樣做雖然交換的次數增加了,但卻將所有元素都相同的最壞情況變成了差不多需要nlog2n次比較的最好情況
void qsort2(int *a, int low, int high) {
    if (low < high) {
        int i = low + 1;
        int j = high;
        int tmp = a[low];
        while (i <= j) {
            while (i <= high && a[i] < tmp) {
                i++;
            }

            while (a[j] > tmp) {
                j--;
            }
            if (i <= j) {
                swap(a[i], a[j]);
            }
        }
        swap(a[low], a[j]);
        for(int i = 0; i <= 7; i++)
			cout<<a[i]<<" ";
		cout<<endl;
        qsort2(a, low, j - 1);
        qsort2(a, j + 1, high);
    }
}

測試代碼
int main(){
	int a[] = {55,41,59,26,53,58,97,93};
	qsort2(a,0,7);
	for(int i = 0; i <= 7; i++)
		cout<<a[i]<<" ";
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章