排序算法整理(C++):插入排序、交换排序、选择排序、归并排序

33 篇文章 0 订阅

  结合《王道》,整理了常用的排序算法,包括直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序、二路归并排序。

  各排序算法的性能平均表:


代码如下:

#include <iostream>
#define N 10
using namespace std;

void InsertSort(int arr[]);//直接插入排序,时间复杂度O(n2),空间复杂度O(1)
void ShellSort(int arr[]);//希尔排序
void BubbleSort(int arr[]);//冒泡排序,时间复杂度O(n2),空间复杂度O(1)
void QuickSort(int arr[]);//快速排序,时间复杂度O(nlogn),O(nlogn)
void quickSort(int arr[], int low, int high);
int Partition(int arr[], int low, int high);//划分算法,两个指针分别从首尾向中间
int Partition_l2r(int arr[], int low, int high);//划分算法,两个前后指针,从首向尾,左半部分顺序不变
int Partition_r2l(int arr[], int low, int high);//划分算法,两个前后指针,从尾向首,右半部分顺序不变
void SelectSort(int arr[]);//简单选择排序,时间复杂度O(n2),空间复杂度O(1)
void HeapSort(int arr[], int len);
void BuildMaxHeap(int arr[], int len);//构建大根堆,len为元素个数N-1(因为下标从0开始)
void AdjustDown(int arr[], int k, int len);//从上往下调整
void AdjustUp(int arr[], int k);//从下往上调整
void MergeSort(int arr[]);//归并排序
void mergeSort(int arr[], int low, int high);//原始归并变换
void Merge(int arr[], int low, int mid, int high);//合并两个有序数组(有辅助数组)
void Merge_b(int arr[], int low, int mid ,int high);//合并两个有序数组(无辅助数组)
void reverse(int arr[], int low, int high);//(翻转数组元素)
void exchange(int arr[], int low, int mid, int high);//(交换两个数组位置)
int main(){
	int arr[] = {1, 6, 4, 9, 0, 5, 8, 2, 7, 3};
	//int arr[] = {20, 18, 22, 16, 30, 19};
	//int arr[] = {87, 45, 78, 32, 17, 65, 53, 9, 63};
	//InsertSort(arr);
	//ShellSort(arr);
	//BubbleSort(arr);
	//QuickSort(arr);
	//SelectSort(arr);
	//BuildMaxHeap(arr, N-1);
	//HeapSort(arr, N-1);
	//AdjustUp(arr, N-1);
	MergeSort(arr);
	
	for(int i=0; i<N; ++i)
		cout << arr[i] << ' ';
	cout << endl;
	return 0;
}
void MergeSort(int arr[]){
	int len = N-1;
	mergeSort(arr, 0, len);
}
void mergeSort(int arr[], int low, int high){
	if(low < high){
		int mid = (low+high)/2;//分解
		mergeSort(arr, low, mid);//
		mergeSort(arr, mid+1, high);
		//Merge(arr, low, mid, high);//合并(方式一)
		Merge_b(arr, low, mid, high);//合并(方式二)
	}
}
void Merge_b(int arr[], int low, int mid ,int high)
{
	int i=low, j=mid+1, k = high;
	while(i<= mid && j<= high){
		int step=0;
		while(i<=mid && arr[i]<=arr[j]) ++i;
		while(j<=high && arr[j]<=arr[i]){
			++j;
			++step;
		}
		exchange(arr, i, mid, j-1);
		i += step;
		mid += step;
	}
}
void reverse(int arr[], int low, int high){
	int stop = (low+high)/2;
	for(; low<=stop; ++low, --high){
		int temp = arr[low];
		arr[low] = arr[high];
		arr[high] = temp;
	}
}
void exchange(int arr[], int low, int mid, int high){
	reverse(arr, low, mid);
	reverse(arr, mid+1, high);
	reverse(arr, low, high);
}
void Merge(int arr[], int low, int mid, int high){
	int i=low, j=mid+1, k=low;
	int *arr_temp = new int[high+1];//辅助数组
	while(i<=mid && j<=high){//遍历两个子数组
		if(arr[i] > arr[j]){//把较小的先放入辅助数组中
			arr_temp[k] = arr[j];
			++j;
			++k;
		}
		else{
			arr_temp[k] = arr[i];
			++i;
			++k;
		}
	}
	while(i<=mid)//若左端子数组有剩余,把剩余的数字放入辅助数组
		arr_temp[k++] = arr[i++];
	while(j<=high)//若右端子数组有剩余,把剩余的数字放入辅助数组
		arr_temp[k++] = arr[j++];
	for(i=low; i<=high; ++i){//把辅助数组复制到arr中
		arr[i] = arr_temp[i];
	}
}
void HeapSort(int arr[], int len){
	BuildMaxHeap(arr, len);
	for(int i=len; i>0; --i){
		int temp = arr[0];//交换堆顶和最后一个元素
		arr[0] = arr[i];
		arr[i] = temp;
		AdjustDown(arr, 0, i-1);//注:这里一直k=0,即从堆顶开始向下把剩余i-1个数进行调整
	}
}
void BuildMaxHeap(int arr[], int len){
	for(int i=(len-1)/2; i>=0; --i){
		AdjustDown(arr, i, len);
	}
}
void AdjustDown(int arr[], int k, int len){
	int temp = arr[k];
	for(int i=2*k+1; i<=len; i = 2*i+1){
		if(i<=len-1 && arr[i+1] > arr[i])
			i++;
		if(temp >= arr[i])//不交换
			break;
		else{
			arr[k] = arr[i];//替换
			k=i;//下移
		}
	}
	arr[k] = temp;//替换
}
void AdjustUp(int arr[], int k){
	int temp = arr[k];//暂存
	int i = (k-1)/2;//初始化父节点
	while(i>=0 && temp > arr[i]){//如果插入节点比父节点大
		arr[k] = arr[i];
		k = i;
		i = (k-1)/2;
	}
	arr[k] = temp;
}
void SelectSort(int arr[]){
	for(int i=0; i<N-1; ++i){
		int min = i;
		for(int j=i+1; j<N; ++j){
			if(arr[j] < arr[min]){
				int temp = arr[j];
				arr[j] = arr[min];
				arr[min] = temp;
			}
		}
	}
}
void QuickSort(int arr[]){
	quickSort(arr, 0, N-1);
}
void quickSort(int arr[], int low, int high){
	if(low < high){
		//int k = Partition(arr, low, high);
		//int k = Partition_l2r(arr, low, high);
		int k = Partition_r2l(arr, low, high);
		quickSort(arr, low, k-1);//递归
		quickSort(arr, k+1, high);
	}
}
int Partition(int arr[], int low, int high){
	int temp = arr[low];
	while(low<high){
		while(low < high && arr[high] > temp) --high;
		arr[low] = arr[high];
		while(low < high && arr[low] < temp) ++low;
		arr[high] = arr[low];
	}
	arr[low] = temp;
	return low;
}
int Partition_l2r(int arr[], int low, int high){
	int temp = arr[high];
	int i=low-1, j=low;
	for(; j < high; ++j){
		if(arr[j]<=temp){//控制升序降序
			++i;
			int t = arr[j];
			arr[j] = arr[i];
			arr[i] = t;
		}
	}
	int t = arr[i+1];
	arr[i+1] = arr[high];
	arr[high] = t;
	return i+1;
}
int Partition_r2l(int arr[], int low, int high){
	int temp = arr[low];
	int i=high, j=high+1;
	for(; i > low; --i){
		if(arr[i] >= temp){//控制升序降序
			--j;
			int t = arr[j];
			arr[j] = arr[i];
			arr[i] = t;
		}
	}
	int t = arr[j-1];
	arr[j-1] = arr[low];
	arr[low] = t;
	return j-1;
}
void BubbleSort(int arr[]){
	int i, j;
	for(i=1; i<N; ++i){
		for(j=0; j<N-i; ++j){//每排序一轮,就确定一位较大的值,并放在次尾部
			if(arr[j]>arr[j+1]){
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}
	}
}
void ShellSort(int arr[]){
	int dist=N/2;
	int temp;
	int i, j;
	for(;dist>0; dist/=2){//与直接排序的区别
		for(i=dist+1; i<N; ++i){
			if(arr[i]<arr[i-dist]){
				temp = arr[i];
				for(j=i-dist; arr[j]>temp; j-=dist)
					arr[j+dist] = arr[j];
				arr[j+dist] = temp;
			}
		}
	}
}
void InsertSort(int arr[]){
	int temp;
	int i, j;
	for(i=1; i< N; ++i){
		if(arr[i] < arr[i-1]){
			temp = arr[i];
			for(j=i-1; arr[j]>temp; --j)
				arr[j+1] = arr[j];
			arr[j+1] = temp;
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值