递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int fibonaci(int i)
{
if(i == 0)
{
return 0;
}
if(i == 1)
{
return 1;
}
return fibonaci(i-1) + fibonaci(i-2);
}

int main()
{
int i;
for (i = 0; i < 10; i++)
{
printf("%d\t\n", fibonaci(i));
}
return 0;
}

排序

https://visualgo.net/zh/

冒泡

重复地走访过要排序的数列,一次比较两个元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
void bubble_sort(int arr[], int len) {
int i, j, temp;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = (int) sizeof(arr) / sizeof(*arr);
bubble_sort(arr, len);
int i;
for (i = 0; i < len; i++)
printf("%d ", arr[i]);
return 0;
}

选择

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void selection_sort(int a[], int len) 
{
int i,j,temp;

for (i = 0 ; i < len - 1 ; i++)
{
int min = i; // 记录最小值,第一个元素默认最小
for (j = i + 1; j < len; j++) // 访问未排序的元素
{
if (a[j] < a[min]) // 找到目前最小值
{
min = j; // 记录最小值
}
}
if(min != i)
{
temp=a[min]; // 交换两个变量
a[min]=a[i];
a[i]=temp;
}
/* swap(&a[min], &a[i]); */ // 使用自定义函数交換
}
}

/*
void swap(int *a,int *b) // 交换两个变量
{
int temp = *a;
*a = *b;
*b = temp;
}
*/

插入

对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

1
2
3
4
5
6
7
8
9
void insertion_sort(int arr[], int len){
int i,j,temp;
for (i=1;i<len;i++){
temp = arr[i];
for (j=i;j>0 && arr[j-1]>temp;j--)
arr[j] = arr[j-1];
arr[j] = temp;
}
}

希尔排序

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录”基本有序”时,再对全体记录进行依次直接插入排序。

演示

https://zhuanlan.zhihu.com/p/122472667

数组由{7, 3, 1, 9, 5, 4, 2, 8, 6} 这9个无序元素组成。

第一次:gap = 9/2 = 4 动画:


第二次:gap = 4/2 = 2 动画:

第三次:gap = 2/2 = 1 动画:

相当于把数据分为gap组,对每组进行完整的插入排序
如第二次中:{5,3,1,8,6,4,2,9,7}
分为

1
2
{5 , 1 , 6 , 2 , 7}  
{ 3 , 8 , 4 , 9}

对这两组分别进行插入排序得到第三次排序的初始结果

代码

1
2
3
4
5
6
7
8
9
10
11
void shell_sort(int arr[], int len) {
        int gap, i, j;
        int temp;
        for (gap = len >> 1; gap > 0; gap >>= 1)//向右移移位==整除2
                for (i = gap; i < len; i++) {
                        temp = arr[i];
                        for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)//插入排序
                                arr[j + gap] = arr[j];
                        arr[j + gap] = temp;
                }
}

归并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int min(int x, int y) {
return x < y ? x : y;
}
void merge_sort(int arr[], int len) {
int* a = arr;
int* b = (int*) malloc(len * sizeof(int));
int seg, start;
for (seg = 1; seg < len; seg += seg) {//外层循环用于控制归并的步长,每次循环 seg 的值会翻倍,直到大于等于数组长度 len。
for (start = 0; start < len; start += seg + seg) {//内层循环用于在当前步长下对数组进行归并操作,每次循环按照步长 seg 来划分子数组进行合并。
int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2)
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
while (start1 < end1)
b[k++] = a[start1++];
while (start2 < end2)
b[k++] = a[start2++];
}
int* temp = a;
a = b;
b = temp;
}
if (a != arr) {
int i;
for (i = 0; i < len; i++)
b[i] = a[i];
b = a;
}
free(b);
}