1.插入排序:以第二個數據開始,插入到數據前已排序好的數據序列中,並使其依舊有序。
實現過程:
算法的代碼實現:
//函數功能:直接插入排序,把數據從小到大排序
//arr 表示數組 len 表示長度
時間複雜度O(n^2) 空間複雜度O(1) 穩定 如果待排序列本就有序,時間複雜度爲O(n)
#include<stdio.h>
int insertsort(int *arr, int len)
{
int i = 0; int j = 0;
int tmp;
for (i = 0; i < len -1; i++)
{
for (j = i+1; j > 0; j--)
{
if (arr[j]>arr[j-1])
{
break;
}
else
{
tmp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = tmp;
}
}
}
return 0;
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
insertsort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
2.希爾排序(一個改進的插入排序):先把大數據集合劃分成若干個小組,然後對每一個小組分別進行插入排序。此時,插入排序所作用的數據量比較小(每一個小組)插入的效率比較高。
第一趟:增量爲4 第二趟:增量爲2
第三趟:增量爲1
複雜度分析:
排序方法 | 時間複雜度 | 空間複雜度 | 穩定性 | 複雜性 | ||
平均情況 | 最壞情況 | 最好情況 | ||||
希爾排序 | O(n^1.3~n^1.5) | O(n^2) |
O(n) |
O(1) | 不穩定 |
較複雜 |
算法代碼實現:
//希爾排序
//時間複雜度O(n^1.3 - n^1.5) 空間複雜度O(1) 不穩定
#include<stdio.h>
void shellsort(int a[], int n)
{
int i, j, d;
for (d = n / 2; d>0; d /= 2)
{
for (i = d; i<n; ++i)
{
int tmp = a[i];
for (j = i; j >= d&&a[j - d]>tmp; j -= d)
a[j] = a[j - d];
a[j] = tmp;
}
}
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
shellsort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
3.選擇排序:從頭至尾掃描序列,找出最小的一個元素,和第一個元素進行交換,接着從剩下的元素中繼續這種選擇和交換的方式,最終得到一個有序序列。
原始序列:{2,5,6,8,12,7,16,11}
1)進行選擇排序時分成有序和無序兩個序列,最開始都是無序序列 {2,5,6,8,12,7,16,11}
2)從無序序列中找出最小的元素2,將2同無序序列第一個元素交換,此時產生僅含一個元素的有序序列,無序序列減一(此時可以看到,無序序列中2本來就在第一個元素中,所以無需進行交換)
{2} {5,6,8,12,7,16,11}
3)從無序序列中取出最小的元素5,將5同無序序列第一個元素交換,此時產生僅兩個元素的有序序列,無序序列減一(同上)
{2,5} {6,8,12,7,16,11}
4)從無序序列中取出最小的元素6,將6同無序序列第一個元素交換,此時產生含三個元素的有序序列,無序序列減一
{2,5,6} {8,12,7,16,11}
5)同上 {2,5,6,7} {12,8,16,11}
6)從無序序列中取出最小的元素6,將6同無序序列第一個元素交換,此時產生含三個元素的有序序列,無序序列減一
{2,5,6,7,8} {12,11,16}
{2,5,6,7,8,11} {12,16}
7)最後一個元素肯定是最大元素,無序排序直接生產一個有序的序列
結果:{2,5,6,7,8,11,12,16}
算法代碼實現:
//時間複雜度O(n^2) 空間複雜度O(1) 不穩定
#include<stdio.h>
void selectsort(int *arr, int len)
{
int tmp, index;
for (int i = 0; i < len-1; i++)//每次循環數組,找出最小的元素,放在前面,前面的即爲排序好的
{
index = i;//假設最小元素的下標
for (int j = i + 1; j < len; j++)
{
if (arr[j] < arr[index])//將上面假設的最小元素與數組比較,交換出最小的元素的下標
{
//index = j;//進行交換
tmp = arr[index];
arr[index] = arr[j];
arr[j] = tmp;
}
if (i != index)////若數組中真的有比假設的元素還小,就交換
{
tmp = arr[i];
arr[i] = arr[index];
arr[index] = tmp;
}
}
}
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
selectsort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
4.冒泡排序:
算法實現:第一次首先將第0和第1位進行比較,並且將結果大的數字向後移動,也就是進行交換,然後將第二位和第三位進行比較,依次兩兩進行往後推移,最後得到排序,最後一位就是最大的數字。如下圖:
算法代碼實現:
//時間複雜度 O(n^2) 空間複雜度O(1) 穩定
#include<stdio.h>
void bubblesort(int *arr, int len)
{
int tmp;
for (int i = 0; i < len-1; i++)
{
for (int j = i+1; j < len; j++)
{
if (arr[i] > arr[j])
{
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
int main()
{
int arr[] = { 2, 5, 6, 8, 12, 7, 16, 11 };
int len = sizeof(arr) / sizeof(int);
bubblesort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}