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;
}
}