归并排序&快速排序(递归与分治)


--------------------------------------------------------------------------归并排序---------------------------------------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
int a[10000],b[10000];
void hebin(int l,int mid,int r)
{
	int p = l,q = mid + 1;
	for(int i=l;i<=r;i++)
	{
		if((q > r) || (a[p] <= a[q] && p <= mid))
		{
			b[i] = a[p++];
		}
		else
		{
			b[i] = a[q++];
		}
	}
	for(int i=l;i<=r;i++)
	{
		a[i] = b[i];
	}
}
void merge_sort(int l,int r)
{
	if(l == r) return;
	int mid = (l + r) / 2;
	merge_sort(l,mid);
	merge_sort(mid + 1,r);
	hebin(l,mid,r);
}
int main()
{
	int n;
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i]; 
	}
	merge_sort(1,n);
	for(int i=1;i<=n;i++)
	{
		cout << a[i];
	}
	cout << endl;
	return 0;
}
------------------------------------------------------------------------------------快速排序---------------------------------------------------------------------------------
方法一 :
#include<bits/stdc++.h>
using namespace std;
int a[10000],b[10000];
void quick_sort(int *a,int low,int high){	//快排 
	if(low>=high)   return;  //若待排序序列只有一个元素,返回空 
	int i=low;	//i作为指针从左向右扫描 
	int j=high;	//j作为指针从右向左扫描
	int key=a[low];//第一个数作为基准数 
	while(i<j)
	{
		while(a[j]>=key&&i<j)
		{	//从右边找小于基准数的元素 (此处由于j值可能会变,所以仍需判断i是否小于j) 
			j--;	//找不到则j减一 
		}
		a[i]=a[j];	//找到则赋值 
		while(a[i]<=key&&i<j)
		{	//从左边找大于基准数的元素 
			i++;	//找不到则i加一 
		}
		a[j]=a[i];	//找到则赋值 
	}
	a[i]=key;	//当i和j相遇,将基准元素赋值到指针i处 
	quick_sort(a,low,i-1);	//i左边的序列继续递归调用快排 
	quick_sort(a,i+1,high);	//i右边的序列继续递归调用快排 
}
int main()
{
	int n;
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i]; 
	}
	quick_sort(a,1,n);
	for(int i=1;i<=n;i++)
	{
		cout << a[i];
	}
	cout << endl;
	return 0;
}

方法二:
#include<bits/stdc++.h>
using namespace std;
int a[10000];
void quick_sort(int l,int r)
{
	int key = a[l];
	int mid = (l + r) / 2;
	int i = l,j = r;
	if(l >= r) return;
	while(i < j)
	{
		while(a[j] >= key && j > i)
		{
			j--; 
		}
		while(a[i] <= key && j > i)
		{
			i++;
		}
		if(i < j) swap(a[i],a[j]); 
	}
	a[l] = a[i];
	a[i] = key;
	quick_sort(l,i-1);
	quick_sort(i + 1,r);
}
int main()
{
	int n;
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i];
	}
	quick_sort(1,n); 
	for(int i=1;i<=n;i++)
	{
		cout << a[i];
	}
	cout << endl;
	return 0;
}
快排总结:
        回到刚开始的时候提的问题,当选取最左边的数字为基准数的时候,为什么要先从右边开始搜索? 要回答为什么先从右边开始搜索,不妨我们先从左边开始搜索。比如说“6  1  2 7  9  3  4  5 10  8”的第一轮,我们先让i从左边开始,遇到小于等于6的继续走,大于6的停下,于是i停在了7的位置;再让j从右边走,小于6的时候停下,于是j停在5的位置;这个时候i < j 于是7和5交换位置变成“6  1  2  5  9  3  4  7  10  8”;继续上面的操作,9和4交换,变成“6  1  2  5  4  3  9  7  10  8”,继续,i先走,停在了9的位置,这个时候i == j了,那么这一轮就比较完了,最后需要交换i和base位置的数(基准数归位),这个时候发生了什么??6与9交换,变成了下面的序列:“9  1  2  5  4  3  6  7  10  8”,这个序列并不是完成了一轮处理之后,基准数左边的都比基准数小,右边的都比它大。所以这样先从左边开始搜索得不到正确结果的。
       因此,我们可以得到下面的结论:当基准数选择最左边的数字时,那么就应该先从右边开始搜索;当基准数选择最右边的数字时,那么就应该先从左边开始搜索。不论是从小到大排序还是从大到小排序!
全部评论

相关推荐

能干的三文鱼刷了10...:公司可能有弄嵌入式需要会画pcb的需求,而且pcb能快速直观看出一个人某方面的实力。看看是否有面试资格。问你问题也能ai出来,pcb这东西能作假概率不高
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务