1.1排序--常撕

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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值