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

news/2024/5/17 19:32:04 标签: 快排, 归并排序, 递归与分治

归并排序的内容可在紫书P226里面查看,紫书里的代码写得十分简洁,高效,重点要理解好循坏条件的控制。
快排可参考以下的博客:
https://blog.csdn.net/MoreWindows/article/details/6684558
归并排序时间复杂度:O(nlogn);快排时间复杂度:平均O(nlogn),最慢O(n^2)。
归并排序稳定但占空间比较大,快排占空间较小但不稳定。

以下为代码实现:

#include<cstdio>
using namespace std;
int a[105],T[105];  //T[105]作为临时的辅助空间 
void merge_sort(int x,int y)   //归并排序[x,y) 
{
	if(y-x>1)   //要是***只有一个元素就不用进行一下操作了*** 
	{
		int m=x+(y-x)/2;
		int p=x,q=m;
		int i=x;
		merge_sort(x,m);  //左半部分排序 
		merge_sort(m,y);  //右半部分排序
		while(p<m||p<y)   //***左右两个序列,至少有一个要非空***
		{
			if(q>=y||(p<m&&a[p]<=a[q])) T[i++]=a[p++]; //如果第二个序列为空,此时q>=y,直接复制a[p]就好了,如果第二个序列不为空,且第一个序列也不为空(p<m)
			//若a[p]<=a[q],复制a[p],否则复制a[q];而如果第一个序列为空了,则复制a[q] 
			else T[i++]=a[q++];
		} 
		for(i=x;i<y;i++) a[i]=T[i];  //***从辅助空间复制回a数组*** 
	}
}
void quick_sort(int x,int y) //其实,快排的原理就是逐步找到每个数对应的位置(从小到大或从大到小) 
{
	if(y-x>1)  //***只有一个元素就不用进行一下操作了***
	{
		int i,j;
		int X;
		X=a[x];//printf("%d\n",X);
		for(i=x,j=y-1;i<j;)
		{
			while(i<j&&a[j]>=X)  //***必须先从j开始处理*** 
			    j--;
			if(i<j)
			    a[i++]=a[j];
			while(i<j&&a[i]<X)
			    i++;
			if(i<j)
			    a[j--]=a[i];
		//	printf("%d %d\n",a[i],a[j]);
		}a[i]=X;
		quick_sort(x,i);
		quick_sort(i+1,y);
	}
}
int main()
{
	int n,i;
	//归并排序 
	scanf("%d",&n);
	for(i=0;i<=n-1;i++){
		a[i]=n-i;
		printf("%d ",a[i]);
	}
	printf("\n");
	merge_sort(0,n);
	for(i=0;i<=n-1;i++)
	    printf("%d ",a[i]);
	printf("\n\n");
	//快速排序 
	scanf("%d",&n);
	for(i=0;i<=n-1;i++)
	{
		a[i]=2*n-i;
		printf("%d ",a[i]);
	}printf("\n");
	quick_sort(0,n);
	for(i=0;i<=n-1;i++)
	    printf("%d ",a[i]);
	printf("\n");
	return 0;
 } 

http://www.niftyadmin.cn/n/943390.html

相关文章

最大连续子列和(递归与分治)

分治算法一般分为3个步骤&#xff1a; 1.划分问题&#xff1a;把问题的实例划分成若干子问题&#xff1b; 2.递归求解&#xff1a;递归解决子问题&#xff1b; 3.合并问题&#xff1a;合并子问题的解得到原问题的解。 分析此题&#xff1a;此题的答案会在以下三种情况中&#…

杭电ACM——2026,单词首字母变大写(思维)

水题&#xff0c;了解一下代码怎么写就好。 #include<cstdio> #include<cstring> #include<cctype> using namespace std; int main() { char s[105]; char c; int i0,first1; while((cgetchar())!EOF) { if(c!\n) { if(isalpha(c)) { if(first) { s[i]c-32;…

杭电ACM--2018(递推)

emmmmmm…一道水题&#xff0c;结果还是弄错了&#xff0c;把递推公式弄错了&#xff0c;结果一直WA。 正确题解如下&#xff1a; #include<cstdio> using namespace std; int a[60]; int main() { int n; int i; for(i1;i<59;i) { if(i<4) a[i]i; else a[i]a[i-…

Codeforces——1101B_Accordion(贪心)

本题可谓是历经波折啊。这也是一道具有贪心思想的题&#xff0c;要尽可能多的裁剪选出最长的“Accordion”&#xff0c;仔细分析一下可知&#xff0c;由于一个“Accordion”是以“[:||||…|||:]”的形式出现的&#xff0c;左右必有一个反向括号&#xff0c;内部左右顶端必有一个…

Codeforces--1062A_APrank(贪心)

根据题意&#xff0c;不难分析出&#xff0c;JATC必须在一段连续递增 1 的数列里面删除元素&#xff0c;否则删除后将不可能复原。 于是&#xff0c;此题贪心的策略就为&#xff0c;选取一段最长的连续递增 1 的数列进行所要的操作。 特别地&#xff0c;要注意满足要求的数列中…

杭电ACM——通畅工程(并查集)

本题属于并查集的内容&#xff0c;最终剩下几个集合&#xff0c;则输出集合数-1即可&#xff0c;这个对象要找清。 这道题是普通的并查集&#xff0c;并不用考虑每个集合的秩&#xff0c;合并后的集合即使呈现链状结构也没问题。 #include<cstdio> #include<> usi…

杭电ACM——2049(递推)

此题跟2048很相似&#xff0c;都是错排的问题&#xff0c;只不过加入组合数的知识罢了。 代码如下&#xff1a; #include<cstdio> #include<iostream> using namespace std; long long array[25]; int main() {long long n,m;int i,kase;long long a,b;for(i2;i&l…

杭电ACM——2050(递推)

折线分割平面&#xff0c;要求尽可能分割出最多的平面&#xff0c;原理其实和直线分割平面一样&#xff0c;都是要使最终所有线之间的交点最多。 先把递推公式放上&#xff0c;有空自己理解理解。 直线&#xff1a;f(n)f(n-1)n; 折线&#xff1a;f(n)f(n-1)4*(n-1)1; 代码如下 …