冒泡
复杂度O(n^2)
标准写法
void BubbleSort(vector<int> &a)
{
int n = a.size();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n-i-1; j++)
{
if (a[j] > a[j+1])
{
a[j] ^= a[j+1];
a[j+1] ^= a[j];
a[j] ^= a[j+1];
}
}
}
}
改进
用flag标记当前是否已经有序
void BubbleSort(vector<int> &a)
{
int n = a.size();
bool flag=true;
for (int i = 0; i < n&&flag; i++)
{
flag = false;
for (int j = 0; j < n-i-1; j++)
{
if (a[j] > a[j+1])
{
a[j] ^= a[j+1];
a[j+1] ^= a[j];
a[j] ^= a[j+1];
flag = true;
}
}
}
}
简单写法,效率不高
void BubbleSort(vector<int> &a)
{
int n = a.size();
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (a[i] > a[j])
{
a[i] ^= a[j];
a[j] ^= a[i];
a[i] ^= a[j];
}
}
}
}
简单选择排序
复杂度O(n^2),性能略优于冒泡,交换操作少
void SimpleSort(vector<int> &a)
{
int n = a.size(),min;
for (int i = 0; i < n; i++)
{
min = i;
for (int j = i+1; j < n; j++)
{
if (a[min] > a[j])
min = j;
}
if (i!=min)
{
a[i] ^= a[min];
a[min] ^= a[i];
a[i] ^= a[min];
}
}
}
直接插入排序
复杂度O(n^2),性能优于冒泡和简单选择排序
思想跟理手上的扑克牌一样,将每一个数插入到已经排好序的记录中
void InsertionSort(vector<int> &a)
{
int n = a.size(),j,temp;
for (int i = 1; i < n; i++)
{
if (a[i] < a[i - 1])
{
temp = a[i];
j = i;
while (j > 0 && a[j-1]>temp)
{
a[j] = a[j-1];
j--;
}
a[j] = temp;
}
}
}
快速排序
复杂度O(nlogn)
int helper(vector<int> &a, int low, int high)
{
int i = low, j = high, x = a[low];
while (i < j)
{
while (i < j&&a[j] > x)
j--;
if (i < j)
a[i++] = a[j];
while (i < j&&a[i] < x)
i++;
if (i < j)
a[j--] = a[i];
}
a[i] = x;
return i;
}
void sort(vector<int> &a, int low, int high)
{
if (low < high)
{
int i=helper(a, low, high);
sort(a, low, i - 1);
sort(a, i + 1, high);
}
}
void QuickSort(vector<int> &a)
{
sort(a, 0, a.size() - 1);
}
修改sort方法减少递归次数
void sort(vector<int> &a, int low, int high)
{
while (low < high)
{
int i=helper(a, low, high);
sort(a, low, i - 1);
low = i + 1;
}
}
归并排序
复杂度O(nlogn),但因为用了递归,所以比较占内存,但是效率高且稳定
void merge(vector<int> &a, int low, int mid, int high)
{
int i = low, j = mid + 1, n = high - low + 1, k = 0;
vector<int> v(n);
while (i <= mid&&j <= high)
v[k++] = a[i] < a[j] ? a[i++] : a[j++];
while (i <= mid)
v[k++] = a[i++];
while (j <= high)
v[k++] = a[j++];
for (i = low; i <= high; i++)
a[i] = v[i - low];
}
void sort(vector<int> &a, int low, int high)
{
if (low < high)
{
int mid = low + (high - low) / 2;
sort(a, low, mid);
sort(a, mid + 1, high);
merge(a, low, mid, high);
}
}
void MergeSort(vector<int> &a)
{
sort(a, 0, a.size() - 1);
}
非递归版本
思路是先两两归并(0 1)(2 3)(4 5)...然后再每四个归并(0 1 2 3)(4 5 6 7),即间隔k=1 2 4...个归并
其中merge子函数和递归版本一样
void merge(vector<int> &a, int low, int mid, int high)
{
int i = low, j = mid + 1, n = high - low + 1, k = 0;
vector<int> v(n);
while (i <= mid&&j <= high)
v[k++] = a[i] < a[j] ? a[i++] : a[j++];
while (i <= mid)
v[k++] = a[i++];
while (j <= high)
v[k++] = a[j++];
for (i = low; i <= high; i++)
a[i] = v[i - low];
}
void MergeSort(vector<int> &a)
{
int n = a.size(),low,mid,high,k=1;
while (k < n)
{
low = 0;
while (low + k < n)
{
mid = low + k - 1;
high = mid + k > n - 1 ? n - 1 : mid + k;
merge(a, low, mid, high);
low = high + 1;
}
k *= 2;
}
}