嵌入式Linux知识第四章——算法

目录

4.1 排序算法

4.1.1各种排序算法的时间空间复杂度、稳定性⭐⭐⭐⭐⭐

4.1.2各种排序算法什么时候有最好情况、最坏情况(尤其是快排) ⭐⭐⭐⭐

4.1.3冒泡排序⭐⭐⭐⭐

4.1.4选择排序⭐⭐⭐⭐

4.1.5插入排序⭐⭐⭐⭐

4.1.6希尔排序⭐⭐⭐⭐

4.1.7归并排序⭐⭐⭐⭐

4.1.8快速排序⭐⭐⭐⭐⭐

4.1.9快排的partition函数与归并的Merge函数⭐⭐⭐

4.2 STL库相关

4.2.1 vector list异同⭐⭐⭐⭐⭐

4.2.2 vector内存是怎么增长的vector的底层实现⭐⭐⭐⭐

4.2.3 vector和deque的比较⭐⭐⭐⭐

4.2.4为什么stl里面有sort函数list里面还要再定义一个sort⭐⭐⭐

4.2.5 STL底层数据结构实现⭐⭐⭐⭐

4.2.6利用迭代器删除元素会发生什么?⭐⭐⭐⭐

4.2.7 map是如何实现的,查找效率是多少⭐⭐⭐⭐⭐

4.2.8几种模板插入的时间复杂度 ⭐⭐⭐⭐⭐


4.1 排序算法

  • 4.1.1各种排序算法的时间空间复杂度、稳定性⭐⭐⭐⭐⭐

  • 4.1.2各种排序算法什么时候有最好情况、最坏情况(尤其是快排) ⭐⭐⭐⭐

  • 4.1.3冒泡排序⭐⭐⭐⭐

 1. // 冒泡排序 相邻2个元素 相互比较,直到最后 然后重新开始。

 2. void BubbleSort(int a[], int len) {

 3.     int tmp;

 4.     int exchange = 1;

 5.     for (int i = 0; (i < len - 1) && (exchange > 0); i++) {

 6.         exchange = 0;

 7.         for (int j = 0; j < len - 1 - i; j++) {

 8.             if (a[j] > a[j + 1]) {

 9.                 tmp = a[j];

10.                 a[j] = a[j + 1];

11.                 a[j + 1] = tmp;

12.                 exchange = 1;

13.             }

14.         }

15.     }

16. }

17.  

  • 4.1.4选择排序⭐⭐⭐⭐

 1. //选择排序

 2. //稳定性最好的排序之一,时间复杂度为On2 规模越小越好,不占用额外空间 

 3. //在未排序中找最小的,放到起始位置,然后再找最小放到第二位置

 4. void SelectSort(int a[], int len) {

 5.     for (int i = 0; i < len; i++) {

 6.         int minindex = i;

 7.         for (int j = i + 1; j < len; j++) {

 8.             if (a[minindex] > a[j]) {   

 9.                 minindex = j;

10.             }

11.         }

12.         swap(a[i],a[minindex]);

13.     }

14. }

15.  

  • 4.1.5插入排序⭐⭐⭐⭐

 1. //插入排序

 2. //拿出一个数和前面的数进行比较,遇到不比它大的数字,插入其中

 3. void InsertSort(int a[],int len) {

 4.     int tmp;

 5.     for (int i = 0; i < len; i++) {

 6.         tmp = a[i];

 7.         int  k = i; // 记录插入的位置

 8.         for (int j = i-1; (j >= 0) && (a[j] > tmp); j--) {

 9.             a[j + 1] = a[j];

10.             k = j;

11.         }

12.         a[k] = tmp;

13.     }

14. }

15.  

  • 4.1.6希尔排序⭐⭐⭐⭐

 1. //希尔排序

 2. //解决 最大值在第一位 需要移动n-1个位置

 3. void  ShellSort(int a[], int n) {

 4.     int gap = n;

 5.     int tmp;

 6.     while (gap > 1) {

 7.         gap = gap / 3 + 1;

 8.         for (int i = gap; i < n; i += gap) {

 9.             int k = i;

10.             tmp = a[i];

11.             for (int j = i -gap; (j >= 0) && (a[j] > tmp); j -= gap) {

12.                 a[j + 1] = a[j];

13.                 k = j;

14.             }

15.             a[k] = tmp;

16.         }

17.     }

18. }

19.  

  • 4.1.7归并排序⭐⭐⭐⭐

 1. //归并排序

 2. //即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表。

 3. //把长度为n的输入序列分成两个长度为n/2的子序列;对这两个子序列分别采用归并排序;将两个排序好的子序列合并成一个最终的排序序列。

 4.  

 5. //首先假设2个数组是有序的,按照有序序列进行合并,组成有序序列

 6. void merge(int a[],int low ,int mid,int high, int tmp[]) {

 7.     int i = low;       //左子数组开始的位置

 8.     int j = mid + 1;   //右子数组开始的位置

 9.     int t = 0;         //临时空间指针

10.     //首先 判断要合并的数组的起始位置的大小,然后将数组复制到tmp数组存储。

11.     // 比较2个数组的每个元素 然后按照大小顺序进行排序。

12.     while (i <= mid && j <= high) {

13.           if (a[i] < a[j]) {

14.                     tmp[t++] = a[i++];

15.           }

16.           else

17.                     tmp[t++] = a[j++];

18.     }

19.     //参考https://www.bilibili.com/video/BV1Pt4y197VZ?from=search&seid=6438701192248743313

20.     //如果右半区就一个元素,上述放好位置后,左半区的元素直接放就好

21.     //将左边剩余元素填充进temp

22.     while (i <= mid) {

23.         tmp[t++] = a[i++];

24.     }

25.     //将右边子数组剩余部分填充到temp

26.     while (j <= high) {

27.         tmp[t++] = a[j++];

28.     } 

29.     //将融合后的数据拷贝到原来的数据对应的子空间中

30.     t = 0;

31.     while (low <= high) {

32.         a[low++] = tmp[t++];

33.     }

34. }

35. void Msort(int a[], int low, int high, int tmp[]) {

36.     if (low < high) {

37.         int mid = (low + high) / 2;

38.         //递归划分左半区

39.         Msort(a,low,mid,tmp);

40.         //递归划分右半区

41.         Msort(a,mid + 1,high,tmp);

42.         //合并左右半区

43.         merge(a,low,mid,high,tmp);

44.     }

45. }

46.  

  • 4.1.8快速排序⭐⭐⭐⭐⭐

 1. //快速排序

 2. //选出一个数作为基准,使得数组左边的小于基准,右边的大于基准

 3. //递归划分

 4.  

 5. //划分函数

 6. int partion(int a[], int low, int high) {

 7.     //选择第一个元素作为标准

 8.     int index = a[low];

 9.     //推动左右指针向中间移动,

10.     while (low < high) {

11.         //如果右边的数比标准大,不用移动,否则交换到左边

12.         while ((low < high) && a[high] >= index) {

13.             high--;

14.         }

15.         while ((low < high) && a[low] <= index) {

16.             low++;

17.         }

18.         swap(a[low],a[high]);

19.     }

20.  

21. }

22.  

23. void Qsort(int a[], int low,int high) {

24.     if (low < high) {

25.         int index = partion(a,low,high);

26.         //递归划分

27.         Qsort(a,low,index - 1);

28.         Qsort(a,index,high);

29.     }

30. }

31.  

排序算法

平均时间复杂度

最好情况

最坏情况

空间复杂度

排序方式

稳定性

冒泡排序

O(n²)

O(n)

O(n²)

O(1)

In--place

稳定

选择排序

O(n²)

O(n²)

O(n²)

O(1)

In--place

不稳定

插入排序

O(n²)

O(n²)

O(n²)

O(1)

In--place

稳定

希尔排序

O(nlog n)

O(nlog² n)

O(nlog² n)

O(1)

In--place

不稳定

归并排序

O(nlog n)

O(nlog n)

O(nlog n)

O(n)

Out--place

稳定

堆排序

O(nlog n)

O(nlog n)

O(nlog n)

O(1)

In--place

不稳定

快速排序

O(nlog n)

O(nlog n)

O(n²)

O(log n)

In--place

不稳定

名称

数据对象

稳定性

时间复杂度

额外空间复杂度

描述

平均

最坏

冒泡排序

数组

O(n²)

O(1)

从无序区通过交换找出最大元素放到有序区

选择排序

数组

×

O(n²)

O(1)

在无序区里找一个最小的元素跟在有序区的后面,对数组比较多换的少

链表

插入排序

数组、链表

O(n²)

O(1)

把无序区的第一个元素插入到有序区的合适的位置,对数组比较的少,换的多

堆排序

数组

×

O(nlogn)

O(1)

从堆顶把根卸出来放在有序区之前,再恢复堆

归并排序

数组

O(nlog²n)

O(1)

把数据分为两段,从两端中逐个选择最小的元素移入新数据段的末尾,可从上到下或从下到上运行

链表

O(nlogn)

O(n)+O(logn)

如果不是从下到上

O(1)

快速排序

数组

×

O(nlogn)

O(n²)

O(logn)

在区间中随机选取一个元素作为基准,将小于基准的元素放在基准之前,大于基准的元素放在基准之后,再分别对小数区和大数区进行排序

希尔排序

数组

×

O(nlog²n)

O(n²)

O(1)

每一轮按照事先决定的间隔进行插入排序,间隔会依次缩小,最后一次一定要是1。

  • 4.1.9快排的partition函数与归并的Merge函数⭐⭐⭐

  • 4.2 STL库相关

  • 4.2.1 vector list异同⭐⭐⭐⭐⭐

  • 4.2.2 vector内存是怎么增长的vector的底层实现⭐⭐⭐⭐

  • 4.2.3 vector和deque的比较⭐⭐⭐⭐

  • 4.2.4为什么stl里面有sort函数list里面还要再定义一个sort⭐⭐⭐

  • 4.2.5 STL底层数据结构实现⭐⭐⭐⭐

  • 4.2.6利用迭代器删除元素会发生什么?⭐⭐⭐⭐

  • 4.2.7 map是如何实现的,查找效率是多少⭐⭐⭐⭐⭐

  • 4.2.8几种模板插入的时间复杂度 ⭐⭐⭐⭐⭐

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值