1.快速排序
平均时间复杂度O(nlogn),空间复杂度O(nlogn),不稳定。
base基准数,left指针,right指针。
#include<iostream>
#include<string>
using namespace std;
void QuickSort(int* h, int left, int right) {
if (h == NULL)
return;
if (left >= right)
return;
int key = h[left];//key存储base基准数
int i = left; int j = right;
while (i < j) {
while (h[j] >= key && i < j)--j;//指针j移动,从后往前找一个比base小的数,找到跳出循环,与h[i]交换
if (i < j) h[i] = h[j];
while (h[i] < key && i < j)++i;//指针i移动,从前往后找一个比base大的数,找到跳出循环,与h[j]交换
if (i < j)h[j] = h[i];
}
h[i] = key;
QuickSort(h, left, i - 1);//递归左边
QuickSort(h, j + 1, right);//递归右边
}
int main() {
int h[] = { 3,5,6,12,76,34,58,30,400,27 };
QuickSort(h,0,9);
for (int i = 0; i < 10; i++) {
cout << h[i]<<" ";
}
return 0;
}
2. 冒泡排序
平均时间复杂度O(n2),空间复杂度O(1),稳定。
在扫描过程中,两两比较相邻记录,若出现反序则交换。重复操作直到n-1遍扫描后,排序完成。
第一遍排序后,最大的已到队尾,下一遍无需再考虑它,故j<len-1-i;其他遍类似。双重循环中 i 是次数,j 是具体下标。
#include<iostream>
#include<string>
using namespace std;
void BubbleSort(int *h,size_t len) {
if (h == NULL)
return;
if (len <= 1)
return;
for (int i = 0; i < len - 1; ++i) {
for (int j = 0; j < len - 1 - i; ++j) {//例:第一遍排序后,最大的已到队尾,下一遍无需再考虑它,故j<len-1-i
if (h[j] > h[j + 1])
swap(h[j], h[j + 1]);
}
}
return;
}
int main() {
int h[] = { 3,5,6,12,76,34,58,30,400,27 };
BubbleSort(h, 10);
for (int i = 0; i < 10; i++) {
cout << h[i]<<" ";
}
return 0;
}
3.选择排序
平均时间复杂度O(n2),空间复杂度O(1),不稳定。
初始时,在序列中找到最小的元素,放到序列的起始位置作为已排序序列,然后再从剩余未排序元素中继续寻找最小的元素,放到已排序序列的末尾,以此类推,直到所有元素完成排序。
双重循环中,i 是次数,j 是将剩余元素继续排序。
#include<iostream>
#include<string>
using namespace std;
void SelectionSort(int* h, size_t len) {
if (h == NULL)
return;
if (len <= 1)
return;
int minindex, i, j;
for (i = 0; i < len - 1; ++i) {
minindex = i;//默认第一个元素最小,在未排序的序列中寻找最小元素:若出现更小的元素其下标j赋值给minindex
for (j = i + 1; j < len; ++j) {
if (h[j] < h[minindex])
minindex = j;
}
swap(h[i], h[minindex]);//注意:是将最小值与h[i]交换,不是与h[j]交换
}
}
int main() {
int h[] = { 3,5,6,12,76,34,58,30,400,27 };
SelectionSort(h, 10);
for (int i = 0; i < 10; i++) {
cout << h[i]<<" ";
}
return 0;
}
4.插入排序
平均时间复杂度O(n2),空间复杂度O(1),稳定。
对于一个数组A[0,n]的排序问题,假设认为数组在A[0,n-1]排序问题已经解决,考虑A[n]的值,从右向左(从后向前)扫描有序数组A[0,n-1]直到第一个小于等于A[n]的元素,将A[n]插入到这个元素的后面。
直接插入排序对于基本有序的数组,会体现出良好的性能,这一特性使它有了进一步优化的可能(希尔排序)。
#include<iostream>
#include<string>
using namespace std;
void InsertSort(int* h, size_t len) {
if (h == NULL)
return;
if (len <= 1)
return;
int i, j;//i是次数,即是排好的个数
for (i = 1; i < len; ++i) {//i从1开始:默认第一个已经排好,从第二个开始插入
for (j = i; j > 0; --j) {//从后向前寻找比较,若比它大,则两两交换,若小于等于它,跳出此循环
if (h[j] < h[j - 1])
swap(h[j], h[j - 1]);
else
break;
}
}
}
int main() {
int h[] = { 3,5,6,12,76,34,58,30,400,27 };
InsertSort(h, 10);
for (int i = 0; i < 10; i++) {
cout << h[i]<<" ";
}
return 0;
}