Bootstrap

多种排序方法

直接插入排序

#include <iostream>
using namespace std;
void insertsort(int *a,int n){
	for(int i=0;i<n;i++){
		int end=i;
		int tmp=a[end+1];
		while(end>=0){
			if(tmp<a[end]){
				a[end+1]=a[end];
				end--;
			}
			else{
				break;//插入到正确位置 
			}
		}
		a[end+1]=tmp;
	}
}
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	insertsort(a,10);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

双向选择排序

#include <iostream>
using namespace std;
#include <algorithm>
void selectsort(int *a,int n){
	int left=0;
	int right=n-1;
	while(left<right){
		int minindex=left,maxindex=left;//假设最大最小值都在左边界 
		for(int i=left;i<=right;i++){
			if(a[i]<a[minindex]) minindex=i;
			if(a[i]>a[maxindex]) maxindex=i;//更新下标 
		}
		swap(a[left],a[minindex]);//将最小值放在左边界 
		if(maxindex==left) maxindex=minindex;//最大值在左边,更新最大值索引 
		swap(a[right],a[maxindex]);//将最大值放在右边界 
		left++;
		right--; 
	}
}
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	selectsort(a,10);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

冒泡排序

#include <iostream>
using namespace std;
#include <algorithm>
void bubblesort(int *a,int n){
	for(int i=0;i<n-1;i++){//比较的轮数 
		for(int j=0;j<n-i-1;j++){//一趟比较的次数 
			if(a[j]>a[j+1]){
				swap(a[j],a[j+1]);
			}
		}
	}
}
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	bubblesort(a,10);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

归并排序(递归)

#include <iostream>
using namespace std;
#include <cstring>
//归并排序的核心递归函数 
void _mergesort(int *a,int begin,int end,int *tmp){
	if(begin>=end) return;
	//递归到最底层只剩下一个元素或没有元素时返回
	int mid=begin+(end-begin)/2;
	//分别对左右两部分递归排序 
	_mergesort(a,begin,mid,tmp);
	_mergesort(a,mid+1,end,tmp); 
	//开始递归并排序
	int begin1=begin;
	int end1=mid;
	int begin2=mid+1;
	int end2=end; 
	int i=begin;
	while(begin1<=end1&&begin2<=end2){
		if(a[begin1]<=a[begin2]) tmp[i++]=a[begin1++];
		else tmp[i++]=a[begin2++]; 
	}
	//处理剩余部分
	while(begin1<=end1) tmp[i++]=a[begin1++];
	while(begin2<=end2) tmp[i++]=a[begin2++];
	//将排序后的结果拷贝回原数组
	memcpy(a+begin,tmp+begin,(end-begin+1)*sizeof(int));
}
//归并排序的主函数 
void mergesort(int *a,int n){
	try{//try-catch捕获bad_alloc异常,处理内存分配的情况 
    	//使用new分配临时数组 
		int *tmp=new int[n];
		//调用递归函数进行排序 
		_mergesort(a,0,n-1,tmp);
		//释放临时数组
		delete[] tmp; 
	}
	catch(bad_alloc&e){
		cerr<<"Memory allocation falied:"<<e.what()<<endl;
		//cerr标准错误输出
		//通过e.what()获取异常的描述信息 
		throw; //关键字,throw重新抛出捕获的异常,让调用者处理 
	}
} 
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	mergesort(a,10);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

迭代式归并排序

#include <iostream>
using namespace std;
#include <cstdlib>
//归并排序核心为分治合并
//分治:将数组分成多个子数组
//直到每个子数组只有一个元素(自然有序) 
//合并:将有序子数组两两合并,形成完整的有序数组 
void _mergesort(int* a,int* tmp,int begin1,int end1,int begin2,int end2){
	int i=begin1;
	int j=begin1;
	while(begin1<=end1&&begin2<=end2){
		if(a[begin1]<a[begin2]) tmp[i++]=a[begin1++];
		else tmp[i++]=a[begin2++];
	}
	while(begin1<=end1) tmp[i++]=a[begin1++];
	while(begin2<=end2) tmp[i++]=a[begin2++];
	//排序后拷贝回原数组 
	for(;j<=end2;j++) a[j]=tmp[j];
}
void mergesort(int* a,int n){
	try{
		int* tmp=new int[n];
		int gap=1;//分成大小为gap的子数组
		while(gap<n){
			int i=0;
			for(i=0;i<n;i+=2*gap){
				int begin1=i;
				int end1=i+gap-1;
				int begin2=i+gap;
				int end2=i+2*gap-1;
				if(begin2>=n) break;
				//子数组为数组的最后一部分 
				if(end2>=n) end2=n-1;
				//第二个子数组范围超出了数组边界 
				_mergesort(a,tmp,begin1,end1,begin2,end2);
			}
			gap*=2;
		} 
		delete[] tmp;
	}
	catch(bad_alloc&e){
		cerr<<"Memory allocation failed"<<e.what()<<endl;
		exit(EXIT_FAILURE);//终止程序执行 
	}
}
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	mergesort(a,10);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

快速排序(递归)–挖坑法

#include <iostream>
using namespace std;
#include <algorithm> 
//三数取中法 
int getmidindex(int* a,int left,int right){
	int mid=left+(right-left)/2;
	if(a[left]<a[mid]){
		if(a[mid]<a[right]) return mid;
		else if(a[right]<a[left]) return left;
		else return right; 
	}
	else{
		if(a[mid]>a[left]) return mid;
		else if(a[right]>a[left]) return left;
		else return right; 
	}
} 
//分区函数
int partsort(int* a,int left,int right){
	int mid=getmidindex(a,left,right);
	//使用三数取中法选择基准值 
	swap(a[left],a[mid]);//将基准值交换到最左边 
	int key=a[left];//基准值 
	int hole=left;//当前坑位索引
	//将大于基准值的数放在基准值右边 
	while(left<right){
		//从右到做找到第一个大于基准值的元素 
		while(left<right&&a[right]>=key) right--;
		a[hole]=a[right];//将找到的元素放入坑位
		hole=right;//更新坑位 
		while(left<right&&a[left]<=key) left++;
		a[hole]=a[left];
		hole=left;
	} 
	//将基准值放回最终坑位
	a[hole]=key;
	return hole; 
} 
//快速排序主体函数
void quicksort(int* a,int left,int right) {
	if(left>=right) return;
	int keyi=partsort(a,left,right);//返回基准值的索引
	quicksort(a,left,keyi-1);//递归排序左半部分
	quicksort(a,keyi+1,right);//递归排序右半部分 
}
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	quicksort(a,0,9);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

快速排序(非递归法)

#include <iostream>
using namespace std;
#include <vector> 
//栈的实现
struct stack{
	vector<int> data;
};
//栈初始化
void initstack(stack* st){
	st->data.clear();
} 
//检查栈是否为空
bool stackempty(const stack* st){
	return st->data.empty();
} 
//压入元素
void stackpush(stack* st,int value){
	st->data.push_back(value);
} 
//获取栈顶元素
int stacktop(const stack* st){
	return st->data.back();
} 
//弹出栈顶元素
void stackpop(stack* st){
	st->data.pop_back();
}
//销毁栈
void stackdestroy(stack* st){
	st->data.clear(); 
} 
//分区函数
int partsort(int* a,int left,int right){
	//三数取中法,将中间值放到 最右边 
	int mid=left+(right-left)/2;
	if(a[left]>a[mid]) swap(a[left],a[mid]);
	if(a[left]>a[right]) swap(a[left],a[right]); 
	if(a[mid]>a[right]) swap(a[mid],a[right]);
	int key=a[right];
	int i=left,j=right-1;
	while(i<=j){
		while(i<=j&&a[i]<=key) i++;
		while(i<=j&&a[j]>key) j--;
		if(i<j) swap(a[i],a[j]);
	}
	swap(a[i],a[right]) ;
	return i;//返回基准值最终位置 
} 
void quicksort(int* a,int begin,int end){
	stack st;
	initstack(&st);
	stackpush(&st,begin);
	stackpush(&st,end);
	//利用压栈模拟递归思想 
	while(!stackempty(&st)){
		//先取右数据,右数据后压 
		int right=stacktop(&st);
		stackpop(&st);
		int left=stacktop(&st);
		stackpop(&st);
		if(left>=right) continue;
		int keyi=partsort(a,left,right);
		if(keyi+1<right){
			stackpush(&st,keyi+1); 
			stackpush(&st,right);//压入右子区间
		}
		if(keyi-1>left){
			stackpush(&st,left); 
			stackpush(&st,keyi-1);//压入左子区间
		}
	}
	stackdestroy(&st);
} 
int main()
{
	int a[10]={67,12,33,56,78,99,11,0,90,66};
	quicksort(a,0,9);
	for(int i=0;i<10;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}
;