插入排序 升序
void InsertSort(int arr[], int sz)
{
assert(arr);
for (int i = 1; i < sz; i++){
for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--){
Swap(&arr[j], &arr[j - 1]);
}
}
}
该排序时间复杂度为O(N²) 空间复杂度为O(1)
希尔排序 升序
void ShellSort(int arr[], int sz)
{
int gap = sz;
while (gap > 1){
gap = gap / 3;
for (int i = gap; i < sz; i += gap){
for (int j = i; j>0 && arr[j] < arr[j - 1]; j -= gap){
Swap(&arr[j], &arr[j - gap]);
}
}
}
}
该处gap选择的是三等分 将arr数组分为三份
该排序时间复杂度近似于O(N∧1.3) 空间复杂度为O(1)
选择排序 升序
void SelectSort(int arr[], int sz)
{
for (int i = 0; i < sz; i++){
int tmp = i;
for (int j = i; j < sz; j++){
if (arr[tmp]>arr[j]){
tmp = j;
}
}
Swap(&arr[i], &arr[tmp]);
}
}
该排序空间复杂度为O(N²) 空间复杂度为O(1)
堆排序 升序
void AdjustDown(int arr[], int i, int sz)
{
int child = i * 2 + 1;
int parent = i;
while (child < sz){
if (child + 1 < sz && arr[child + 1] > arr[child]){
child++;
}
if (arr[child] > arr[parent]){
Swap(&arr[child], &arr[parent]);
parent = child;
child = parent * 2 + 1;
}
}
}
void HeapSort(int arr[], int sz)
{
int i = (sz - 2) / 2;
for (; i >= 0; i--){
AdjustDown(arr, i, sz);
}
for (int j = 0; j < sz; j++){
Swap(&arr[0], &arr[sz - 1]);
sz--;
AdjustDown(arr, 1, sz);
}
}
升序建大堆 降序建小堆
先建一个大堆 建好后数组第一个元素也就是arr[0]是最大的 与最后一个元素进行交换 sz-- 再进行向下调整
该排序时间复杂度为O(N * lg N) 空间复杂度为O(1)
冒泡排序 升序
void BubbleSort(int arr[], int sz)
{
for (int i = 0; i < sz; i++){
for (int j = 0; j < sz - i - 1; j++){
if (arr[j]>arr[j + 1]){
Swap(&arr[j], &arr[j + 1]);
}
}
}
}
该排序空间复杂度为O(N²) 空间复杂度为O(1)
快速排序 升序
void QuickSort(int arr[], int left, int right)
{
if (left >= right){
return;
}
int i = left;
int j = right;
int key = arr[left];
while (i < j)
{
while (i < j && key <= arr[j]){
j--;
}
arr[i] = arr[j];
while (i < j && key >= arr[i]){
i++;
}
arr[j] = arr[i];
}
arr[i] = key;
QuickSort(arr, left, i - 1);
QuickSort(arr, i + 1, right);
}
该排序时间复杂度为O(N * lg N) 空间复杂度为O(lg N)
归并排序 升序
void MergeSort(int arr[], int left, int right, int tmp[])
{
if (left >= right){
return;
}
int mid = left + ((right - left) >> 1);
MergeSort(arr, left, mid, tmp);
MergeSort(arr, mid + 1, right, tmp);
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = left;
while (begin1 <= end1 && begin2 <= end2){
if (arr[begin1] > arr[begin2]){
tmp[index++] = arr[begin2++];
}
else{
tmp[index++] = arr[begin1++];
}
}
while (begin1 <= end1){
tmp[index++] = arr[begin1++];
}
while (begin2 <= end2){
tmp[index++] = arr[begin2++];
}
for (int i = left; i <= right; i++){
arr[i] = tmp[i];
}
}
该排序时间复杂度为O(N * lg N) 空间复杂度为O(N)
类别 | 排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | 分类 |
插入排序 | 插入排序 | O(N²) | O(1) | 稳定 | 内排序 |
Shell排序 | O(N∧1.3) | O(1) | 不稳定 | 内排序 | |
选择排序 | 选择排序 | O(N²) | O(1) | 不稳定 | 内排序 |
堆排序 | O(N * lg N) | O(1) | 不稳定 | 内排序 | |
交换排序 | 冒泡排序 | O(N²) | O(1) | 稳定 | 内排序 |
快速排序 | O(N * lg N) | O(lg N) | 不稳定 | 内排序 | |
归并排序 | 归并排序 | O(N * lg N) | O(N) | 稳定 | 外排序 |
内排序指数据/元素存放在内存中进行排序
外排序指数据/元素存放在磁盘中进行排序