本文主要內容是快速排序的**編寫及其優化,還有快速選擇演算法(在無序的數中尋找第k大或小的元素)
上**:
#include #include #include #include #include #include #include #include #include #include using namespace std;
#define max_n 10000
// arr :用來儲存待排序的元素
// n :代表元素數量
// output :輸出過程中的除錯資訊
// debug = 1 開啟除錯資訊
// debug = 0 關閉除錯資訊
int arr[max_n + 5];
int n;
#define debug 1
void output(int,int,int);
// 快速排序: 對arr中 l 到 r 位進行排序
// arr: 待排序陣列
// l : 待排序區間起始座標
// r : 待排序區間結束座標
void quick_sort(int *arr,int l,int r)
//將基準值pivot放到陣列x位
arr[x] = pivot;
output(l,x,r);
quick_sort(arr,l,x-1);
quick_sort(arr,x+1,r);
return;
}void output(int l,int x,int r)
for(int i = 1; i < l; i++) printf("%d ",arr[i]);
printf("[");
for(int i = l; i <= r; i++)
printf("]");
for(int i = r + 1; i <= n; i++) printf("%d ",arr[i]);
printf("\n");
for(int i = 0; i < cnt; i++) printf(" ");
printf("^\n");
for(int i = 0; i < cnt; i++) printf(" ");
printf("|\n");
printf("\n");
return;
}void read_data()
while(getchar() != '\n');
return;
}int main()
printf("\n");
return 0;
}
下面再來看下對快速排序的優化。
主要分三點優化:
1)單邊遞迴優化--本層函式呼叫中完成本層的partition後,依舊在本層對左半邊進行partition,對右半邊進行遞迴呼叫,這樣一來,函式呼叫的次數會減半,大大降低了演算法的時間複雜度.
2)基準值選擇優化--三點取中,對排序區間最左邊的值、中間值、最右邊的值進行取中值作為基準值,這樣會使得演算法的時間複雜度穩定在o(nlogn)
3)對partition操作進行優化,利用兩個指標分別從前向後、從後向前,交換比基準值小和比基準值大的元素,直到兩指標相遇.
看**:
#include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define time(func) ()
void quick_sort_old(int *arr, int l, int r)
arr[x] = z;
quick_sort_old(arr, l, x - 1);
quick_sort_old(arr, x + 1, r);
return ;
}int select_value(int a, int b, int c)
void quick_sort_new(int *arr, int l, int r)
}while(x <= y);
quick_sort_new(arr,x,r);
//單邊遞迴優化
r = y;
}return;
}#define max_n 1000000
int a1[max_n + 5], a2[max_n + 5];
void test_one(int t)
int t1 = time(quick_sort_old(a1,0,max_n - 1));
int t2 = time(quick_sort_new(a2,0,max_n - 1));
printf("第%d輪測試,quick_sort_old(%dms), quick_sort_new(%dms)\n", t, t1, t2);
return;
}void test_random(int n)
return;
}int main()
看完上述**,相信你對快速排序演算法有了一定的認知,如果我問你,如何在無序的數中選擇第k大的元素呢,我們的第一反應可能是對所有元素排序,然後取第k大的元素,仔細想想,有必要嗎?
其實,在我們完成一次partition操作之後,我們就可以知道基準值的排名, 假設為ind,我們可以比較ind和k的大小,如果ind和k相等,那麼基準值就是第k大的值,如果ind比k大,那麼我們只需在左半邊遞迴查詢第k大的值即可,如果ind比k小,那麼我們只需在右半邊遞迴查詢第k-ind大的值即可,因為已經可以排除左半邊的元素,而左半邊的元素有ind個。
這樣說你理解了嗎?接下來看**如何實現.
//arr :待查詢陣列
//l--r:待查詢區間
//k :待查詢元素的排名
//在arr陣列的l到r區間內,查詢排名為k的元素
int quick_select()
arr[x] = z;
//ind為當前基準值的排名
int ind = x - l + 1;
if(ind == k) return arr[x];
if(ind > k) return quick_select(arr,l,x-1,k);
return quick_select(arr,x+1,r,k-ind);
}
快速排序及其優化
include include 呼叫c 自帶sort include include include using namespace std define max 1000000 define k 12 ifdef debug define new new normal block,file lin...
快速排序及其優化
快速排序是比較經典 常用的演算法,下面簡要介紹其思路。對於乙個陣列,選取某個元素作為切分元素 比如第乙個元素 然後把比這個元素小的都放到它前面,比這個元素大的都放到它後面,這樣切分元素的最終位置就確定了,並且陣列被劃分為兩個子陣列。然後再用同樣的方法分別對子陣列進行排序,最終整個陣列將變成有序的。這...
快速排序及其優化
package com.zc.algorithm public class quicksort 如果不大於,則把右邊的數賦值給左邊 arr left arr right 如果左邊的數小於基數,則向右移動 while left arr right 把最大值放在陣列的末尾 if arr mid arr ...