清华大学算法训练营week2——排序算法

输入n个数,按升序排列

选择排序 :每次选择最小的排在前面——大概率的 θ ( n 2 ) θ(n^2) θ(n2)

#include<cstdio> 
#include<algorithm>
using namespace std;

int main() {
	int a[500005];
	int n;
	scanf("%d",&n);
	for(int i=0; i < n; i++){
			 scanf("%d",&a[i]);
	}
	for(int i=0; i<n; ++i){	
		for( int j=i+1; j<n; ++j){
				if(a[i]>a[j]){
	//			int b=a[i];
	//			a[i]=a[j];
	//			a[j]=b;
	
	//或
	//int c=min(a[i],a[j]);
	//int b=max(a[i],a[j]);
	//a[i]=c;
	//a[j]=b;
	 
	//或 
	//			swap(a[i],a[j]);
			}		
		}
	}
		
	for(int i=0; i < n; i++){
			printf("%d%c",a[i]," \n"[i==n-1]);	
	}

	return 0;
}

标题冒泡排序:每次讲最大的冒泡放在最后

	for(int i=1;i<n;++i)
		for(int j=0;j<n-i;++j)//边界分析:i=0时,j最大是n-1,此时出错,j必须衡恒<=n-2  ——>i从1开始;j=0时 ;i=n-1时,j只能取0; 
			if(a[j]>a[j+1])
			swap(a[j+1],a[j]);
				

标题插入排序——小概率的 O ( n 2 ) O(n^2) O(n2)

for(int i=0; i<n; ++i)
		for(int j=i; j>0;--j)//边界考虑法:i=0时不考虑,至少有两个相比较 所以j>0. 
			if(a[j]<a[j-1])
				swap(a[j],a[j-1]);
			else
			  	break;   

归并排序—— O ( n l o g n ) O(nlogn) O(nlogn)

数组作为参数传入
//问题:当数组a,b开在260 000左右,它编译不出错,运行出错(在sort位置)。如何解决?

#include<cstdio> 
#include<iostream>
void sort(int L, int R, int a[],int b[]){
/*数组的作为函数参数传入的方法,最重要的是数组作为参数时, 
在函数中对数组元素的修改就等同于对原数组元素的
修改(这与普通的局部变量不同) 
*/ 
	if(L==R)
	return;
	int mid=(L+R) >> 1;
	sort(L,mid,a,b);
	sort(mid+1,R, a, b);
/*sort(mid+1,R, a[], b[])——>出错,声明的时候才这么使用;
sort(mid+1,R,int a[],int b[])-->出错,此处不是函数的声明,而是调用;
 */
	int L_idx=L;
	int R_idx=mid+1;
	int b_idx=L;
	while (L_idx <= mid && R_idx<= R)
		if(a[L_idx]<a[R_idx])
			b[b_idx++]=a[L_idx++];
		else
			b[b_idx++]=a[R_idx++];
		
	while(L_idx<=mid)
		b[b_idx++]=a[L_idx++];
	while(R_idx<=R)
		b[b_idx++]=a[R_idx++];
	for(int i=L;i<=R;++i)
		a[i]=b[i];
	
} 

int main() {
	int a[500000];
	int b[500000];
    //int a[260 000];//出错
	//int b[260 000];//出错
	int n;
	scanf("%d",&n);
	for(int i=0; i < n; i++)
		 scanf("%d",&a[i]);
	sort(0,n-1,a,b);
	for(int i=0; i < n; i++)
		printf("%d%c",a[i]," \n"[i==n-1]);
	system("pause");	
	return 0;
}
数组作为全局变量
#include<cstdio> 
#include<iostream>
	int a[50000];
	int b[50000];
void sort(int L, int R){
/*数组的作为函数的方法,最重要的是数组作为参数时, 
在函数中对数组元素的修改就等同于对原数组元素的
修改(这与普通的局部变量不同) 
*/ 
	if(L==R)
		return;//边界考虑: L-R=1的情况也需要排序 R不是"开区间",传入已做考虑n-1 
	int mid=(L+R) >> 1;
	sort(L,mid);
	sort(mid+1,R);//sort(mid+1,R, a[], b[])——>出错,声明的时候才这么使用 ;sort(mid+1,R,int a[],int b[])-->出错,此处不是函数的声明,而是调用; 
	int L_idx=L;
	int R_idx=mid+1;
	int b_idx=L;
	while (L_idx <= mid && R_idx<= R)
		if(a[L_idx]<a[R_idx])
			b[b_idx++]=a[L_idx++];
		else
			b[b_idx++]=a[R_idx++];
		
	while(L_idx<=mid)
		b[b_idx++]=a[L_idx++];
	while(R_idx<=R)
		b[b_idx++]=a[R_idx++];
	for(int i=L;i<=R;++i)
		a[i]=b[i];
	
} 

int main() {
	int n;
	scanf("%d",&n);
	for(int i=0; i < n; i++)
			 scanf("%d",&a[i]);
	sort(0,n-1);		
		for(int i=0; i < n; i++)
			printf("%d%c",a[i]," \n"[i==n-1]);		
	system("pause");
	return 0;
}

快速排序—— O ( n l o g n ) O(nlogn) O(nlogn)见讲义1324-1328

//快速排序——快速划分:LUG版 见邓俊辉mooc讲义1315-1320
#include <cstdio>   
#include <iostream>
using namespace std;

#define maxn 500005
int n,a[maxn];
int partition(int l,int r){
	int pivot=a[l];
	while(l<r){
		while(l<r&&a[r]>=pivot) r--; a[l]=a[r];
		while(l<r&&a[l]<=pivot) l++; a[r]=a[l];
	}
	a[l]=pivot;
	return l;
}
void solve(int l,int r){
	if(r-l+1<=1) return;
	int mid=partition(l,r);
	solve(l,mid);
	solve(mid+1,r);
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;++i){
		scanf("%d",a+i);
	}
	solve(0,n-1);
	for(int i=0;i<n;++i){
		printf("%d",a[i]);
		if(i!=n-1) printf(" ");
		else printf("\n");
	}
	system("pause"); 
	return 0;
}
以下错误版本原因爆栈,具体未知???
//当输入为n=5时,就已经爆栈了,具体解释未知??????
#include<cstdio> 
#include<algorithm>
#include<stdlib.h>
#include<iostream>
using namespace std;
	int a[50];
	
void sort(int L, int R){
	if(L>=R)
		return;
	int bound=a[rand()%abs(R-L)];
	int L_idx=L;
	int R_idx=R;
	while(L_idx <= R_idx){
		while(a[L_idx]<bound)
			++L_idx;
		while(bound<a[R_idx])
			--R_idx;
		if(L_idx<=R_idx)
			swap(a[L_idx++],a[R_idx--]);
			
	}
	sort(L,R_idx);
	sort(L_idx,R);   
	
	
} 

int main() {
	int n;
	scanf("%d",&n);
	for(int i=0; i < n; i++)
			 scanf("%d",&a[i]);
	sort(0,n-1);		
		for(int i=0; i < n; i++)
			printf("%d%c",a[i]," \n"[i==n-1]);		
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值