1.快排:
1.找到界点:两端比较,左段<界点<右段;递归;结束条件:左段指针与右段指针重叠。
int quick(int a[], int low, int high){
int tmp = a[low];
while(low<high){
while(low<high && a[high]>=tmp) --high;
a[low] = a[high];
while(low<high && a[low]<=tmp) ++low;
a[high] = a[low];
}
a[low] = tmp;
returh low;
}
//---------main-------------
int pre(int a[], int low, int high){
int r = quick(a, 0, len);
pre(a, low, r-1);
pre(a, r+1, high);
}
常考变形:查找第K大的元素(top K)
int quick(int a[], int low, int high){
// 同上
}
//----------------main--------------------
int pre(int a[], int low, int high, int k){
int r = quick(a,low,high);
if (r == k) return a[k];
if (r>k) return pre(a, low, r, r-1);
else return pre(a, r+1, high, k-r);
}
2.堆排序:大根堆和小根堆,常考 top k–先选k个建堆,然后剩下的比较堆顶!并调整。
特点明显:A[K]>(A[2K], A[2K+1])
//1. 原始数组建堆,对每一个非叶节点检查并调整;2. 出一个元素就调整堆,至出完。
//-----------------调整----------
void tiaozheng(int a[], int i, int len){
int k = 2*i, int tmp = a[i];
while(k<=len){
if(k<len && a[k]<a[k+1]) k++;
if(a[k]<=tmp) break;
else{
a[i] = a[k];
i = k; //非常重要:被调整剥夺值的节点,将作为目标节点继续被调整;
k = 2*i; //没有break说明有节点被调整,那么就要对新的“i”节点进行调整,k为左孩子;
}//--end else
}//--end while
a[i] = tmp; //非常重要:在对i的调整过程中,第一次跟之后的每次调整均会与tmp有关,最终i位置的值即为tmp。
//说白了,就是一直在找tmp的合适位置,找到后还保证堆结构。
}
//------------------建堆----------
void build(int a[], int len){
for( int i = len/2; i>1; i++)
tiaozheng(a, i, len);
}
//---------------main---------
void dui(int a[], int len){
build(a, len); //堆已经建好----建堆函数不重要,最重要是调整!!!!调整!!!
for (int i = len, i>1,i--){
swap(a[i], a[1]); //获取堆顶元素,剩下的怎么办??继续保持堆结构!那就-> 最后一个元素换到堆顶 长度-1,调整!
tiaozheng(a, 1, i-1);
}
}
3.归并:分而治之,保持最小序列有序,再由少至多合并即可。(归并需要将元素递归分解再合并)
void merge(int a[], int low, int mid, int high){
int b[high] = {0}; //复制数组a,便于比较及修改。
for (int i = low; i<=high; i++)
b[i] = a[i];
i = low;
while(low<=mid && high>=mid+1){
if(b[low]<=b[high]) a[i++] = b[low++]; // 两段中较小的数字写入
else a[i++] = b[high--]; // 两段中较小的数字写入
}
while(low<=mid) a[i++] = b[low++]; // 没写完的那段继续写至结束
while(high>=mid+1) a[i++] = b[high--]; // 没写完的那段继续写至结束
}// 两段都写完了,意味着归并结束。
//-----------main----------
void guibing(int a[], int low, int high){
int mid = (low+high)/2;
guibing(a, low, mid);
guibing(a, mid+1,high);
merge(a, low, mid, high);
}