数据结构常用算法总结(二)手写八大排序(插入,希尔,简单选择,冒泡,快排,归并,堆排,基数排序)

1,插入排序
2,希尔排序
3,简单选择排序
4,冒泡排序
5,快速排序
6,归并排序
7,堆排序
8,还有基数排序,较为简单

#include<iostream>
#include<vector>
using namespace std;

//1,插入排序
void insertSort(vector<int>&a){	
	for (int i = 1; i < a.size(); i++) {//插入排序,处理第i个数据
		for (int j = i - 1; j >=0; j--) {//对于第i个数据,向前插入
			if (a[j] > a[j+1]) {
				int temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
	}
}

//2,希尔排序
void Xier(vector<int>&a){ 
	int n = a.size();
	for (int d = n / 2; d > 0; d = d / 2){//更改步长
		for (int i = 0; i <d; i++){//处理每一组
			for (int j = i+d; j < n; j = j + d){//处理该组的每一个数据,从每一组的第二个数数据开始处理
				for (int k = j - d; k >= 0; k = k -d){
					if (a[k+d] < a[k]){
						int temp = a[k+d];
						a[k+d] = a[k];
						a[k] = temp;
					}
				}
			}
		}
	}
}

//3,简单选择排序
void simpleSelect(vector<int>& a) {
	for (int i = 0; i <a.size() ; i++){
		int min = a[i];
		for (int j = i; j < a.size(); j++) {
			if (a[j] < min) {
				int temp = a[j];
				a[j] = a[i];
				a[i] = temp;
			}
		}
	}
}

//4,冒泡排序
void bubble(vector<int>& a) {
	for (int i = 0; i < a.size(); i++) {//得到第i+1大的数据
		for (int j = 1; j < a.size() - i; j++){
			if (a[j] < a[j-1]){//和临近元素比较
				int temp = a[j-1];
				a[j-1] = a[j];
				a[j] = temp;
			}
		}
	}
}

//5,快速排序
int Partition(vector<int>&a, int low, int high)
{
	int pivot = a[low];//第一个元素作为枢轴
	while (low < high) {//用low,high搜索枢轴的最终位置
		while (low < high && a[high] >= pivot) --high;
		a[low] = a[high];//比枢轴小的元素移动到左边
		while (low < high && a[low] <= pivot) ++low;
		a[high] = a[low];//比枢轴大的元素移动到右端
	}
	a[low] = pivot;//枢轴元素存放到最终位置
	return low;//返回存放枢轴的最终位置
}
void quickSort(vector<int> &a,int low,int high) {
	if (low < high) {//递归跳出条件
		int pivotpos = Partition(a, low, high);//划分
		quickSort(a, low, pivotpos - 1);//划分左子表
		quickSort(a, pivotpos + 1, high);//划分右子表
	}
}

//6,堆排序,注意数组第一个元素不存元素,即数组长度为n+1,元素个数为n,a[1]--a[n]存储了n个元素
void HeadAdjust(vector<int>& a, int k, int n);
void BuildMaxHeap(vector<int>& a){//建立大根堆
	int n = a.size()-1;
	for (int i = n / 2; i > 0; i--)
		HeadAdjust(a, i, n);
}
void HeadAdjust(vector<int>& a, int k, int n) {//将以k为根的结点调整为小根堆,n代表数组a的元素个数
	a[0] = a[k];
	for (int i = 2 * k; i <= n; i = 2 * i) {
		if (i < n && a[i+1] > a[i]) i++;//找到较大的儿子
		if (a[0] >= a[i])break;
		else {
			a[k] = a[i];//如果较小的儿子比父更小,将小儿子放双亲位置,再调整以小儿子原先位置为根的树
			k = i;
		}
	}
	a[k] = a[0];
}
void HeapSort(vector<int>&a) {
	int n = a.size() - 1;
	BuildMaxHeap(a);
	for (int i = n; i > 1; i--) {
		//1)堆顶和堆底元素互换
		int temp = a[1];
		a[1] = a[i];
		a[i] = temp;
		HeadAdjust(a, 1, i - 1);
	}
}

//7,归并排序
void Merge(vector<int>&arr, int low, int mid, int high) {
	//low为第1有序区的第1个元素,i指向第1个元素, mid为第1有序区的最后1个元素
	int i = low, j = mid + 1, k = 0; //mid+1为第2有序区第1个元素,j指向第1个元素


	int* temp = new int[high - low + 1]; //temp数组暂存合并的有序序列,辅助数组
	if (!temp) { //内存分配失败
		cout << "error";
		return;
	}
	while (i <= mid && j <= high) {
		if (arr[i] <= arr[j]) //较小的先存入temp中
			temp[k++] = arr[i++];
		else
			temp[k++] = arr[j++];
	}
	while (i <= mid)//若比较完之后,第一个有序区仍有剩余,则直接复制到t数组中
		temp[k++] = arr[i++];
	while (j <= high)//同上
		temp[k++] = arr[j++];
	for (i = low, k = 0; i <= high; i++, k++)//将排好序的存回arr中low到high这区间
		arr[i] = temp[k];
	delete[]temp;//删除指针,由于指向的是数组,必须用delete []
}

//用递归应用二路归并函数实现排序——分治法
void MergeSort(vector<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);
	}
}

void output(vector<int> a)
{
	for (int i = 0; i < a.size(); i++)
	{
		cout << a[i] << ' ';
	}
	cout << endl;
}
// 4 6 1 4 9 24 43 47 7 43
int main()
{
	vector<int> in;
	for (int i = 0; i < 10; i++)
	{
		int k;
		cin >> k;
		in.push_back(k);
	}
	//1,插入排序
	insertSort(in);
	cout << "插入排序" << endl;
	output(in);
	//2,希尔排序
	Xier(in);
	cout << "希尔排序" << endl;
	output(in);
	3,简单选择排序
	simpleSelect(in);
	cout << "简单选择排序" << endl;
	output(in);
	//4,冒泡排序
	bubble(in);
	cout << "冒泡排序" << endl;
	output(in);
	//5,快速排序
	quickSort(in, 0, 9);
	cout << "快速排序" << endl;
	output(in);
	//6,归并排序
	MergeSort(in, 0, 9);
	cout << "归并排序" << endl;
	output(in);
	//7,堆排序
	HeapSort(in);
	cout << "堆排序,注意这里是建立了大根堆,堆排序以后顺序输出成了递增序列,只处理的是a[1]到a[9]" << endl;
	output(in);
}

补充:基数排序
情景:判断时间早晚。时间格式——时:分:秒
思路:可以看出时间格式的权重顺序应该是秒,分,时。先设置一个60容量的秒队列,将要排序的元素放到对应的位中;然后再依次收集;再将收集到的元素放到60容量的分队列中。再依次收集;最后将收集到的元素依次放到24容量的小时队列中,再依次收集得到顺序时间序列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值