第一种:选择排序

第二种:冒泡排序、改进冒泡排序

第三种:插入排序

第四种:快速排序--->升级版 随即快速排序

第五种:归并排序

第六种:希尔排序

第七种:桶排序(直接下标排序,适合数据范围较小的)

第八种:堆排序(学会手写堆的操作函数,堆调整、删除添加元素等等)

快速排序和归并排序都用到了二分,但是快速排序是先排后递归,归并排序是先二分递归再排(需要两个数组)

#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=1000;
int a[MAXN];
int n;
//选择排序
void xuanze(){
	int k; 
	for(int i=0;i<n;i++){
	 k=i;
	 for(int j=i+1;j<n;j++)
	 if(a[j]<a[k]) k=j;   //注意是a[j]<a[[k] 
	 if(k!=i) {
	 	swap(a[i],a[k]);
	 }
}
cout<<"选择排序如下:  ";
for(int i=0;i<n;i++) cout<<a[i]<<" ";
cout<<endl; 
} 
//冒泡排序
void maopao(){
	for(int i=n-1;i>=1;i--){
		for(int j=0;j<i;j++){
			if(a[j]>a[j+1]) swap(a[j],a[j+1]);
		}
	}
	cout<<"冒泡排序如下:  ";
for(int i=0;i<n;i++) cout<<a[i]<<" ";
cout<<endl; 
}
//改进冒泡排序
void impmaopao(){
	bool ok;
	for(int i=n-1;i>=1;i--){
		ok=true;
		for(int j=0;j<i;j++){
			if(a[j]>a[j+1]) {
				swap(a[j],a[j+1]);
				ok=false;
			}
		}
		if(ok==true) break;
	}
	cout<<"改进冒泡排序如下:  ";
for(int i=0;i<n;i++) cout<<a[i]<<" ";
cout<<endl;

}
//插入排序 
void charu(){
	int temp=0,k,i,j;
	for( i=1;i<n;i++){
		for(j=i-1;j>=0;j--){
			if(a[j]<a[i]) break;
		}
		if(j!=i-1){
			temp=a[i];
			for(k=i-1;k>j;k--) a[k+1]=a[k];
			a[k+1]=temp;
		}
	}
	cout<<"插入排序如下:  ";
for(int i=0;i<n;i++) cout<<a[i]<<" ";
cout<<endl;
}
//快速排序
void qsort(int l,int r){
	int i,j,mid;
	i=l;j=r;
	mid=a[(l+r)/2];
	do{
		while(a[i]<mid) i++;
		while(a[j]>mid) j--;
		if(i<=j){
			swap(a[i],a[j]);
			i++;j--;
		}
	}while(i<=j);
	if(l<j) qsort(l,j);
	if(i<r) qsort(i,r);
	
}
//归并排序 
int r[MAXN];//辅助数组 
int ans=0;  //逆序数 
void msort(int s,int t){
	if(s==t) return; //只有一个元素时不需要比较
	int mid=(s+t)/2;
	msort(s,mid);  //分解左序列 
	msort(mid+1,t); //分解右序列 
	int i=s,j=mid+1,k=s; //合并,注意k的初始值不是为0
	while(i<=mid&&j<=t){
		if(a[i]<=a[j]) r[k++]=a[i++];
		else {
			r[k++]=a[j++];
			ans+=mid-i+1;
		} 
	}
	while(i<=mid) r[k++]=a[i++];
	while(j<=t) r[k++]=a[j++];
	for(int i=s;i<=t;i++) a[i]=r[i]; //注意i的起始和终止值 
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];  //快速排序和归并排序从i=1开始 
	//xuanze();
	//maopao();
	//impmaopao();
	//charu(); 
	
	/*qsort(1,n); 
	cout<<"快速排序如下:  ";
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";
	cout<<endl;
	*/
	msort(1,n);
	 cout<<"归并排序如下:  ";
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";
	cout<<endl;
	return 0; 
} 

  

希尔排序的概念:
希尔排序(Shellsort)也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。希尔(Donald Shell)于1959年提出这种排序算法。
希尔排序是非稳定排序算法。
二、图解希尔排序的基本思想:
 希尔排序是把数据序列按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量逐渐减少,每组包含的数据个数越来越多,当增量减至1时,整个文件恰被分成一组,整个数据序列就已经排序好了,算法便终止。
原文链接:https://blog.csdn.net/qq_33479129/article/details/110599751

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
typedef long long LL;
typedef unsigned long long ull;

int a[maxn];
void shellsort(int length){
	int gap=0,temp;
	int i,j;
	for(gap=length/2;gap>=1;gap/=2){
		for(i=gap;i<length;i++){
			temp=a[i];
			for(j=i-gap;j>=0&&temp<a[j];j=j-gap){
				a[j+gap]=a[j];
			}
			a[j+gap]=temp;
		}
	}
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	shellsort(n);
	for(int i=0;i<n;i++) cout<<a[i]<<"  ";
return 0;
}

  

第七种:桶排序

适用于数字范围较小的

1184:明明的随机数

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

int n;
int a[101];
int b[1001];
int main(){
	cin>>n;
	int m=0;
	memset(b,0,sizeof(b));
	for(int i=0;i<n;i++){
		cin>>a[i]; 
		
		if(b[a[i]]==0) m++;   
		b[a[i]]++;
	}
	cout<<m<<endl;
	for(int i=0;i<=1000;i++){
		if(b[i]!=0) cout<<i<<" ";
	}
	cout<<endl;
return 0;
}

  

第八种:堆排序(基本的堆的操作)

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
//堆排序 
//小根堆 
int n,heap[100001];
//堆调整 
void heapadjust(int x,int high){  //后面的high必须要有 
	int i=x,j=2*i;
	while(j<=high){
		if((j+1<=high)&&heap[j]>heap[j+1]) j++;
		if(heap[j]<heap[i]){
			swap(heap[i],heap[j]);
			i=j;
			j=2*i;
		}
		else break;
	}
}
//删除堆顶元素
int delete(){
  int ans=heap[1];
  heap[1]=heap[n--];
  heapadjust(1,n);
  return ans;
} 
//添加堆顶元素
void insert(int x){
	heap[++n]=x;
	heapadjust(1,n);//向上调整新加入的节点 
} 
//建堆 
void heapsort(){
	for(int i=n/2;i>=1;i--) heapadjust(i,n); //建立一个初始小根堆
	for(int i=n;i>1;i--){
		swap(heap[1],heap[i]);  //将最后一个与第一个交换,最小值到了最后 
		heapadjust(1,i-1);
	} 
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>heap[i]; 
	heapsort();
	for(int i=n;i>1;i--) cout<<heap[i]<<" ";
	cout<<heap[1]<<endl; 
return 0;
}

  

随机选择算法

求出无序序列中第k大的数

利用随机选择排序的函数,因为快速排序是查找一个数左边有多少小于他即temp,如果小于他就往后走,直到>temp,右边也是查找有多少大于temp,如果大于就往前走,直到<temp,这个时候才交换这两个指针指向的对象,这里就可以用来判断有多少值是小于temp的,即temp是第几大的。

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long LL;
int a[1010];
int randpar(int left,int right){
	int p=round(1.0*rand()/RAND_MAX*(right-left)+left);
	swap(a[p],a[left]);
	int temp=a[left];
	
	while(left<right){
		while(left<right&&a[right]>temp) right--;
		a[left]=a[right];
	
		while(left<right&&a[left]<=temp) left++;
		a[right]=a[left];
		
	}
	a[left]=temp;
	return left;
}
//int randsel(int left,int right,int k){
//	if(left==right) return a[left];
//	int p=randpar(left,right);
//	int m=p-left+1;
//	if(m==k) return a[p];
//	if(k<m){ //在左侧 
//		return randsel(left,p-1,k);
//	}
//	else return randsel(p+1,right,k-m);
//}
/*
8 3
7 6 9 3 1 5 2 4
*/
void  randsel(int l,int r){
	if(l>r) return;
	int p=randpar(l,r);
	randsel(l,p-1);
	randsel(p+1,r);
}
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
//	cout<<randsel(1,n,k);
	randsel(1,n);
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}

  

 posted on 2020-01-29 22:34  shirlybabyyy  阅读(103)  评论(0编辑  收藏  举报