算法 排序算法实现c++

1.冒泡排序

//比较相邻的元素。如果第一个比第二个大,就交换它们两个;
//对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
//针对所有的元素重复以上的步骤,除了最后一个;
//重复步骤1~3,直到排序完成。
void PopSort(vector<int>& src) {
	for (int i = 0; i < src.size() - 1; i++) {
		for (int j = 0; j < src.size() - 1; j++) {
			if (src[j] > src[j + 1]) {
				swap(src[j], src[j + 1]);
			}
		}
	}
}

2.快速排序

//找到一个pivot 比它小的放左边 大的放右边
void QuickSort(int left, int right, vector<int>& src) {
	if (left > right)
		return;
	int i = left;
	int j = right;
	int pivot = src[i];
	while (i < j) {
		if (src[j] >= pivot && i < j) {
			j--;
		}
		if (src[i] <= pivot && i < j) {
			i++;
		}
		if (i < j) {
			swap(src[i], src[j]);
		}
	}
	src[left] = src[i];
	src[i] = pivot;
	QuickSort(left, i - 1, src);
	QuickSort(i + 1, right, src);
}

3.简单插入排序

//从第一个元素开始,该元素可以认为已经被排序;
//取出下一个元素,在已经排序的元素序列中从后向前扫描;
//如果该元素(已排序)大于新元素,将该元素移到下一位置;
//重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
//将新元素插入到该位置后;
//重复步骤2~5。
void InsertSort(vector<int>& src) {
	for (int i = 1; i < src.size(); i++) {
		int j = i - 1;
		int current = src[i];
		while (j >= 0 && src[j] > current) {
			swap(src[j], src[j + 1]);
			j--;
		}
		//src[j + 1] = current;
	}
}

4.希尔排序


//希尔排序是基于插入排序的一种算法, 在此算法基础之上增加了一个新的特性,提高了效率。
//通过增量使得待排的数组部分有序 然后通过插入排序思想 排序
void ShellSort(vector<int>& src) {
	int length = src.size();
	int j;
	int i;
	int incVal;
	for (incVal = (length / 2); incVal > 0; incVal = (incVal / 2)) {
		//for(int i)
		for (i = incVal; i < length; i++) {
			int num = src[i];
			 j = i - incVal;
			for (; j >= 0 && src[j] > num; j -= incVal) {
				src[j + incVal] = src[j];
			}
			src[j + incVal] = num;
		}
	}
}

5.简单选择排序

//初始状态:无序区为R[1..n],有序区为空;
//第i趟排序(i = 1, 2, 3…n - 1)开始时,当前有序区和无序区分别为R[1..i - 1]和R(i..n)。该趟排序从当前无序区中 - 选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i + 1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
//n - 1趟结束,数组有序化了。
void SelectSort(vector<int>& src) {
	int index = 0, temp;
	for (int i = 0; i < src.size() - 1; i++) {
		index = i;
		for (int j = i + 1; j < src.size(); j++)
		{
			if (src[index] > src[j]) {
				index = j;
			}
		}
		swap(src[i], src[index]);
	}
}

6.堆排序

//建立大根堆或者小根堆 再将首位 移到最后 从0 ....n-1之间建立堆 重复就可获得有序

void AdjustHeap(vector<int>& src, int i, int length) {
	int temp = src[i];
	int t;
	for (;	2 * i + 1 < length; i = t) {
		t = 2 * i + 1;//这里使用了树的性质 即孩子和双亲在数组下标中对应关系
		cout << "t :" << t  << "i " << i << " temp " << temp << endl;
		if (t != length - 1 && src[t] < src[t + 1]) {
			t++;
		}
		if (src[t] > temp) {
			src[i] = src[t];
		}
		else {
			break;
		}
	}


}

void HeapSort(vector<int>& src, int len) {
	for (int i = len / 2 - 1; i >= 0; i--) {
		cout << i << "     " << len << endl;
		AdjustHeap(src, i, len);
	}
	for (int j = len - 1; j > 0; j--) {
		swap(src[0], src[j]);
		AdjustHeap(src, 0, j);
	}
}

7.二路归并排序

//归并排序采用分治法
//将问题分为小问题 递归解决
void MergeSort(vector<int>& src, int left, int mid, int right, vector<int>& temp) {
	int i = left, j = mid + 1;
	int m = mid, n = right;
	int k = 0;

	while (i <= m && j <= n)
	{
		if (src[i] <= src[j])
			temp[k++] = src[i++];
		else
			temp[k++] = src[j++];
	}

	while (i <= m)
		temp[k++] = src[i++];

	while (j <= n)
		temp[k++] = src[j++];

	for (i = 0; i < k; i++)
		src[left + i] = temp[i];
}

void Split(vector<int>& src, int left, int right, vector<int>& temp) {
	if (left < right) {
		int mid = (right - left) / 2 + left;
		Split(src, left, mid, temp);
		Split(src, mid + 1, right, temp);
		MergeSort(src, left, mid, right, temp);
	}
}

void SplitSort(vector<int>& src, int size) {
	vector<int> temp(size + 1, 0);

	Split(src, 0, size, temp);

}

8.计数排序

void CountSort(vector<int>& src, int size) {
	vector<int> count(size, 0);
	for (int i = 0; i < src.size(); i++) {
		count[src[i]]++;
	}
	src.clear();
	for (int i = 0; i < count.size(); i++) {
		while (count[i]--) {
			src.push_back(i);
		}
	}
}

9.桶排序

//有点计数排序的意思
#define BUCKET_NUM    10
void BucketSort(vector<int>& src) {
	vector<vector<int>> bucket(10, vector<int>());
	for (int i = 0; i < src.size(); i++) {
		int index = src[i] / BUCKET_NUM;
		bucket[index].push_back(src[i]);
		if (bucket[index].size() > 1) {
			sort(bucket[index].begin(), bucket[index].end());//这里应该能优化  最后一个再重新排序 不然插入一次排一次太慢了   最后统一排序 但现在就先这样
		}
	}
	src.clear();
	for (int i = 0; i < BUCKET_NUM; i++) {
		for (int j = 0; j < bucket[i].size(); j++) {
			src.push_back(bucket[i][j]);
		}
	}
}

10.基数排序

//菜鸟教程写法 改
int maxbit(vector<int> data, int n) //辅助函数,求数据的最大位数
{
	int maxData = data[0];   
	for (int i = 1; i < n; ++i)
	{
		if (maxData < data[i])
			maxData = data[i];
	}
	int d = 1;
	int p = 10;
	while (maxData >= p)
	{
		maxData /= 10;
		++d;
	}
	return d;
}

void radixsort(vector<int>& data, int n) //基数排序
{
	int d = maxbit(data, n);
	vector<int> tmp(n, 0);
	vector<int> count(10, 0); //计数器
	int i, j, k;
	int radix = 1;
	for (i = 1; i <= d; i++) //进行d次排序
	{
		for (j = 0; j < 10; j++)
			count[j] = 0; //每次分配前清空计数器
		for (j = 0; j < n; j++)
		{
			k = (data[j] / radix) % 10; //统计每个桶中的记录数
			count[k]++;
		}
		for (j = 1; j < 10; j++)
			count[j] = count[j - 1] + count[j]; //count中数组的值就是位置
		for (j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中   从后往前影响小一点
		{
			k = (data[j] / radix) % 10;
			tmp[count[k] - 1] = data[j];
			count[k]--;
		}
		for (j = 0; j < n; j++) //将临时数组的内容复制到data中
			data[j] = tmp[j];
		radix = radix * 10;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值