冒泡排序:
每次将序列中最大的数交换到最后一个。
C++代码:
void Exchange(int &a, int &b) {
int tmp = a;
a = b;
b = tmp;
}
void BubbleSort(int *a, int length) {//冒泡排序、稳定
for (int i = 0; i < length; i++) {
for (int j = 0; j < length - i - 1; j++) {
if (a[j] > a[j + 1]) {
Exchange(a[j], a[j + 1]);
}
}
}
}
冒泡排序是稳定排序、原地排序(空间复杂度为O(1)的排序),时间复杂度为O(n^2)。
选择排序:
选择最大的元素,与序列最后一个交换
void SelectionSort(int* a, int length) {//选择排序、不稳定
int max = a[0];
int pos;
for (int i = 0; i < length; i++) {
for (int j = 0; j < length - i; j++) {
if (a[j] > max) {
max = a[j];//找最大值
pos = j;//最大值的位置
}
}
Exchange(a[length - i - 1], a[pos]);//把最大的放在最后一位
max = a[0];
pos = 0;
}
}
选择排序是不稳定排序、空间复杂度为O(1),时间复杂度为O(n^2)。
插入排序:
选定前n个元素作为有序序列,将第n+1个元素插入到序列中的正确位置,从n=1开始。
void InsertSort(int* a, int length) {
for (int i = 1; i < length; i++) {
int tmp = a[i];
int j = i - 1;
while (j >= 0 && a[j] > tmp) {
a[j + 1] = a[j];
}
a[j + 1] = tmp;
}
}
插入排序的空间复杂度为O(1),时间复杂度为O(n^2)。
快速排序:
选定一个基准数(一般是序列第一个元素),两个位置指针:i从前到后,j从后到前,在保证i<j的前提下,j移动j元素到小于基准值的位置时停止移动,当i移动到i元素大于基准值的位置时停止移动。对i元素和j元素进行交换,当i=j时,此时的i位置即为基准数最终的位置,基准数与i元素进行交换,由于是j先移动,所以i位置的元素一定小于基准值,交换后,基准值前的元素都小于基准值,基准值后的元素都大于基准值。再将基准值前的序列和基准值后的序列进行快排、递归直到序列为1时停止。
void QuickSort(int* a, int length, int begin, int end) {//快速排序、不稳定
if (begin >= end)return;
int i = begin;
int j = end;
int tmp = a[i];
while (i != j) {
while (a[j] >= tmp && i < j)j--;
while (a[i] <= tmp && i < j)i++;
if (i < j) Exchange(a[i], a[j]);
}
Exchange(a[begin], a[i]);
QuickSort(a, length, begin, i - 1);
QuickSort(a, length, j + 1, end);
}
快速排序是一种优化的冒泡排序,冒泡排序将最大的值放在正确的位置,快速排序将任意一个元素放在正确的位置,其核心思想都是交换。算法空间复杂度为O(logn),平均时间复杂度为O(nlogn)。
归并排序(二路):
先将序列划分到长度为1,在进行归并,归并时的结果放到辅助数组reg中。
void MergeSortRecursive(int* a, int* reg, int begin, int end) {//归并排序、稳定
if (begin > end)return;
int len = end - begin;
int mid = (len >> 1) + begin;//除以2
int begin1 = begin;
int end1 = mid;
int begin2 = mid + 1;
int end2 = end;
MergeSortRecursive(a, reg, begin1, end1);
MergeSortRecursive(a, reg, begin2, end2);//递归法
int k = begin1;
while (begin1 <= end1 && begin2 <= end2) {
reg[k++] = a[begin1] < a[begin2] ? a[begin1++] : a[begin2++];
}
while (begin1 <= end1) {
reg[k++] = a[begin1++];
}
while (begin2 <= end2) {
reg[k++] = a[begin2++];
}
for (k = begin; k <= end; k++) {//将reg回注到a
a[k] = reg[k];
}
}
归并排序是稳定排序,空间复杂度为O(n),平均时间复杂度为O(nlogn)。
希尔排序:
将序列下标按一定的距离分组,对每组进行插入排序,距离减小为1时再进行排序后的序列是有序序列。
void ShellSort(int* a, int length) {
for (int gap = length << 1; gap > 0; gap <<= 1) {
for (int i = gap; i < length; i++) {
int j = i - gap;
int tmp = a[i];
while (j >= 0 && a[j] > tmp) {
a[j + gap] = a[j];
j -= gap;
}
a[j + gap] = tmp;
}
}
}
希尔排序空间复杂度为O(1),平均时间复杂度为O(nlogn)。