简单排序
冒泡排序
void BubleSort(vector<int> &a)
{
size_t t= a.size();
for (int i = 0; i < t;i++)
for (int j = i + 1; j < t; j++)
{
if (a[i]>a[j])
swap(a[i], a[j]);
}
}
选择排序
void SelectSort(vector<int> &a)
{
size_t t = a.size();
for (int i = 0; i < t; i++)
{
int min = i; //默认当前值为最小值
for (int j = i + 1; j < t; j++)
if (a[min]>a[j])
{
min = j; //找到最小值的下标
}
if (min != i)
swap(a[i], a[min]); //最小值小标若更新后,交换这俩值
}
}
插入排序
void InsetSort(vector<int> &a)
{
size_t t = a.size();
for (int i = 1; i < t; i++)
{
int temp = a[i];
int j = i - 1;
for (; j >= 0&&a[j] > temp; j--) //判断j>0在前
a[j + 1] = a[j]; //往后移一位
a[j + 1] = temp;
}
}
快速排序
int partition(vector<int> &a,int l,int r)
{
int s = a[l];
int i = l, j = r;
while (i < j) //3个while
{
while (a[j]>=s&&i<j)
j--;
a[i] = a[j]; //白话的算法这里还要i+1,其实在夏暖的while中也实现了+1,只不过多了一次判断。我这样写简单一点。
while (a[i] < s&&i < j)
i++;
a[j] = a[i];
}
a[i] = s;
return i;
}
void QuickSort_(vector<int> &a, int l, int r)
{
if (l < r) //不是while
{
int pivot = partition(a, l, r);
QuickSort(a, l, pivot - 1);
QuickSort(a, pivot + 1, r);
}
}
整合版本:
void QuickSort(vector<int> &a,int l,int r)
{
if (l < r) //不是while
{
int s = a[l];
int i = l, j = r;
while (i < j)
{
while (a[j] >= s&&i<j)
j--;
a[i] = a[j];
while (a[i] < s&&i < j)
i++;
a[j] = a[i];
}
a[i] = s;
QuickSort(a, l, i - 1);
QuickSort(a, i + 1, r);
}
}
归并排序
void Merge(vector<int> &a, vector<int> &help,int start,int mid,int end) //把两个数组合并,左:a从start到mid;右:a从mid+1到end。 help是辅助数组
{
int i = start, j = mid+1;
int k = i;
while (i <= mid&&j <= end)
{
if (a[i] < a[j])
{
help[k++] = a[i++];
}
else
{
help[k++] = a[j++];
}
}
while (i <= mid)
{
help[k++] = a[i++];
}
while (j <= end)
{
help[k++] = a[j++];
}
for (int i = start; i <= end; i++) //最后把辅助数组的结果copy到原数组a
a[i] = help[i];
}
void MergeSort(vector<int> &a, vector<int> &help, int start, int end) //先分 后治
{
if (start != end)
{
int mid = (start + end) / 2;
MergeSort(a, help, start, mid); //左边有序
MergeSort(a, help, mid+1, end); //右边有序
Merge(a, help, start, mid, end); //归并
}
}
希尔排序
前面的插入排序是步长为1的特殊希尔排序。
void ShellSort(vector<int> &a)
{
size_t t = a.size();
int step = t / 2;
do
{
for (int i = step; i < t; i ++)
{
int temp = a[i];
int j = i - step;
for (; j >= 0 && a[j] > temp; j-=step) //判断j>0在前
a[j + step] = a[j];
a[j + step] = temp;
}
step /= 2;
}
while (step != 1);
}
堆排序
两步:
1. 先把一个数组建成一个大顶堆:
- 先确定非叶子节点,其实就是数组小标小于数组长度一般的元素。
- 如果当前节点小于他左右孩子结点中的一个,就和最大的孩子节点呼唤,如果没有就break;然后替换后再继续和下一个孩子节点比较。
2. 把堆顶元素和末尾呼唤,然后在调整堆顶元素。
void HeapAdjust(vector<int>& a, int start,int end)
{
int temp = a[start]; //start表示起始的父节点
int j;
for (j = 2 * start + 1; j <=end; j *= 2+1 ) j是start的孩子
{
if (j <end&&a[j] < a[j + 1])
j++;
if (temp>a[j])
break;
swap(a[start], a[j]); //如果满足小于子节点的条件就互换
start = j; //更新start节点(父节点)
}
}
void HeapSort(vector<int> &a)
{
size_t t = a.size();
int i =t / 2 - 1,j=t-1;
for (; i >= 0; i--)
HeapAdjust(a, i,t);
for (; j >= 0; j--)
{
swap(a[j], a[0]); //交换顶尾元素
HeapAdjust(a, 0, j-1); //注意最后一个参数,把范围限制到减去一
}
}