十大排序算法(之前我都不知道有这么多)
写这个主要是为了纪录,方便自己再来复习,代码都跑过,可以放心拿来用。讲解就算了,我也不班门弄斧了。
用一下午时间自己敲的
sort()用的是什么排序呢?答案是:插入排序和快速排序,简单理解如果待排序数量小与限定值用插入排序,大于限定值用快速排序。
1. 冒泡
void Bubble_Sort(vector<int> test) //最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
{
for (int i = 0; i < test.size(); i++)
{
bool is = false;//优化
for (int j = 0; j < test.size()-1 - i; j++)
{
if (test[j + 1] < test[j])
{
is = true;
int temp = test[j + 1];
test[j + 1] = test[j];
test[j] = temp;
}
}
if (is == false) break;//检验
}
for (auto it : test) cout << it << ends; cout << endl;
}
2.选择
void Selection_Sort(vector<int> test)//最佳情况:T(n) = O(n2) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
{
for (int i = 0; i < test.size(); i++)
{
int minnum = i;
for (int j=i+1;j<test.size();j++)
{
if (test[j]<test[minnum])
{
minnum = j;
}
}
if (i != minnum)
{
int temp = test[i];
test[i] = test[minnum];
test[minnum] = temp;
}
}
for (auto it : test) cout << it << ends; cout << endl;
}
3.插入
void Insertion_Sort(vector<int >test)//最佳情况:T(n) = O(n) 最坏情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
{
for (int i = 0; i < test.size()-1; i++)
{
int cur = test[i + 1];
int pre = i;
while (pre >= 0 && cur <test[pre])
{
test[pre + 1] = test[pre];
pre--;
}
test[pre + 1] = cur;
}
for (auto it : test) cout << it << ends; cout << endl;
}
4.希尔(其实就是插入排序的升级版)
void Shell_Sort(vector<int> test)//最佳情况:T(n) = O(nlog2 n) 最坏情况:T(n) = O(nlog2 n) 平均情况:T(n) = O(nlog2n)
{
int step = test.size() / 2;
while (step > 0)
{
for (int i = 0; i < test.size()-step; i++)
{
int cur = test[i+step];
int pre = i;
while (pre >= 0 && cur < test[pre])
{
test[pre + step] = test[pre];
pre -= step;
}
test[pre + step] = cur;
}
step /= 2;
}
for (auto it : test) cout << it << ends; cout << endl;
}
5.归并
void merge(vector<int> &test, int L,int Mid, int R)
{
vector<int> temp(R-L+1);
int i = L,j=Mid+1,k=0;
while (i <= Mid && j <= R)
{
temp[k++] = test[i] < test[j] ? test[i++] : test[j++];
}
while (i <= Mid)
{
temp[k++] = test[i++];
}
while (j <= R)
{
temp[k++] = test[j++];
}
for (int i = 0; i < R-L+1; i++)
{
test[L+i] = temp[i];
}
}
void Merge_Sort(vector<int> &test,int L,int R)//最佳情况:T(n) = O(n) 最差情况:T(n) = O(nlogn) 平均情况:T(n) = O(nlogn)
{
if (test.size() < 2) return;
if (L < R)
{
int Mid = (L + R) / 2;
Merge_Sort(test,L,Mid);
Merge_Sort(test,Mid+1,R);
merge(test,L,Mid,R);
}
}
6.快排
void Quick_Sort(vector<int> &test,int L,int R)//最佳情况:T(n) = O(nlogn) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(nlogn)
{
if (L >= R) return;
int i = L,j=R;
int base = test[i];
while (i < j)
{
while (test[j] > base && i<j) j--;
while (test[i] <= base && i<j ) i++;//注意是小于等于 左边第一个为base,起始test[i]==base;
if (i < j)
{
int temp = test[i];
test[i] = test[j];
test[j] = temp;
}
}
test[L] = test[i];
test[i] = base;
Quick_Sort(test, L, i-1);
Quick_Sort(test, i+1,R);
}
7. 堆排
void build_adjust(vector<int> &test, int root, int len)
{
int maxp = root;
int lchild=2*root+1;
if (lchild < len&&test[lchild] > test[maxp]) maxp = lchild;
int rchild = 2 * root + 2;
if (rchild < len&&test[rchild] > test[maxp]) maxp = rchild;
if (maxp != root)
{
swap( test[root],test[maxp] );
build_adjust(test, maxp, len);
}
}
void Heap_Sort(vector<int> test,int len)//最佳情况:T(n) = O(nlogn) 最差情况:T(n) = O(nlogn) 平均情况:T(n) = O(nlogn)
{
for (int i = len / 2 - 1; i >= 0; --i)//最后的根节点
{
build_adjust(test,i,len);//建堆
}//得到大顶堆
for (int i = len - 1; i > 0; i--)
{
swap(test[0], test[i]);//提取取最大的
build_adjust(test,0,i);//剩下的调整成大顶堆
}
for (auto it : test) cout << it << ends;
}
还有基数 计数 桶 三个排序 改天敲
改天==2020/3/22(啥时候能开学。。。。。)
前面7种排序算是比较经典和常见的,下面这三个说实话之前并不知道叫这个名字,但用过类似的方法。
8.计数(对于为整数的,集中在小范围内的,重复率越高越好的数据,堪称神器)
void Counting_Sort(vector<int> test)//最佳情况:T(n) = O(n+k) 最差情况:T(n) = O(n+k) 平均情况:T(n) = O(n+k)
{
int min = 0, max = 0, base = 0;
for (auto it : test)
{
if (it < min) min = it;
if (it > max) max = it;
}
base = 0 - min;
vector<int> temp(max - min + 1, 0);
for (auto it : test)
{
temp[it + base]++;
}
int index = 0;
for (int i = 0; i < temp.size(); i++)
{
while (temp[i] > 0)
{
test[index++] = i-base;
temp[i]--;
}
}
for (auto it : test)cout << it << ends;
}
后面的我觉得不太常用。