嵌入式培训学习历程第二十九天

                  排序与查找

  1.冒泡排序 : 若有n个元素,第一个元素和第2个元素比较, 若为逆序,则交换,然后比较第2个和第3个元素,依次类推,直到第n - 1和n 进行过比较为止, 这称为第一躺冒泡,结果使最大的元素被安置到了最后一个元素的位置上,然后进行第二躺冒泡,参与比较的元素个数为n-1, 依次类推, 冒泡躺数位K(1 <= k < n)

 1 int maopao_sort(int a[], int len)
 2 {
 3     int i = 0, j = 0;
 4     int itemp = 0;
 5 
 6     for(i = 0; i != len - 1; i ++)
 7     {
 8         for(j = 0; j != len - 1 - i; j ++)
 9         {
10             if(a[j] > a[j + 1]) {
11                 itemp = a[j];
12                 a[j] = a[j + 1];
13                 a[j + 1] = itemp;
14             }
15         }
16     }
17 
18     return 0;
19 }
冒泡排序

  2.选择排序 : 每一躺在n - i + 1(i = 1, 2 ..., n - 1)个元素中选取最小的元素作为有序序列中第i个元素

 19 int choose_sort(int a[], int len)
 20 {
 21     int i = 0, j = 0, k = 0;
 22     int itemp = 0;
 23 #if 0
 24     for(i = 0; i != len; i ++)
 25     {
 26         for(j = i + 1; j != len; j ++)
 27         {
 28             if(a[i] > a[j]) {
 29                 itemp = a[i]; 
 30                 a[i] = a[j];
 31                 a[j] = itemp;
 32             }
 33         }
 34     }
 35 #else
 36     for(i = 0; i != len; i ++)
 37     {   
 38         k = i;
 39         for(j = i + 1; j != len; j ++)
 40         {   
 41             if(a[k] > a[j]) {
 42                 k = j;
 43             }
 44         }
 45 
 46         if(k != i) {
 47             itemp = a[i];
 48             a[i] = a[k];
 49             a[k] = itemp;
 50         }
 51     }
 52 #endif
 53 
 54     return 1;
 55 }
选择排序的两种方法

  3.插入排序 : 在已排序的n个元素中插入一个新的元素, 得到有序的n + 1个元素, 当只有一个元素时,默认是排好序的

 88 int insert_sort(int a[], int len)
 89 {
 90     int i = 0, j = 0;
 91     int itemp = 0;
 92 
 93     for(i = 0; i != len - 1; i ++)
 94     {
 95         itemp = a[i + 1];
 96         for(j = i; itemp < a[j] && j >= 0; j --)
 97         {
 98             a[j + 1] = a[j];
 99         }
100         a[j + 1] = itemp;
101     }
102 
103     return 0;
104 }
插入排序

  4.归并排序 : 将两个或两个以上的有序表组合成一个新的有序表

 1 void merger_sort_achieve(int a[], int begin, int end, int m)
 2 {
 3     int i = 0, j = 0, k = 0;
 4     int b[end + 1];
 5 
 6     for(i = begin; i != end + 1; i ++)
 7     {
 8         b[i] = a[i];
 9     }
10 
11     i = begin;
12     j = m + 1;
13     k = begin;
14 
15     while(i <= m && j <= end)
16     {
17         if(b[i] > b[j]) {
18             a[k ++] = b[j ++];
19         }
20         else {
21             a[k ++] = b[i ++];
22         }
23 
24         while(i <= m)
25         {
26             a[k ++] = b[i ++];
27         }
28         while(j <= m)
29         {
30             a[k ++] = b[j ++];
31         }
32     }
33 
34 }
35 
36 int merger_sort(int a[], int begin, int end)
37 {
38     int m = 0;
39 
40     if(begin >= end) {
41         return 1;
42     }
43 
44     m = (begin + end) / 2;
45     merger_sort(a, begin, m);
46     merger_sort(a, m + 1, end);
47     merger_sort_achieve(a, begin, end, m);
48 
49     return 0;
50 }
归并排序

  5.快速排序 : 选取1个分割元素,通过一趟排序,将待排序元素分成独立的两部分,其中一部分元素均比另一部分的元素小,以所选分割元素为份界点, 则可分别对这两部分元素继续进行排序(可递归实现), 以达到整个序列有序

 29 void exercise_sort(int a[], int begin, int end)
 30 {
 31     int cut = 0;
 32 
 33     if(begin >= end) {
 34         return ;
 35     }
 36 
 37     cut = cut_number(a, begin, end);
 38     exercise_sort(a, begin, cut - 1);
 39     exercise_sort(a, cut + 1, end);
 40 
 41 }
 42 
 43 int cut_number(int a[], int begin, int end)
 44 {
 45     int i = 0, j = 0;
 46 
 47     for(i = begin + 1, j = begin; i <= end; i ++)
 48     {
 49         if(a[begin] > a[i]) {
 50             swap(&a[i], &a[++ j]);
 51         }
 52     }
 53     swap(&a[begin], &a[j]);
 54 
 55     return j;
 56 }
 57 
 58 void swap(int *a, int *b)
 59 {
 60     int itemp = 0;
 61     itemp = *a;
 62     *a = *b;
 63     *b = itemp;
 64 
 65     return ;
 66 }
快速排序

                 排序选择

  1.若n较小(如n <= 50), 可采用插入或选择排序。

    当记录规模较小时, 插入排序较好, 否则因为选择移动的元素数少于插入,应选直接选择排序为宜。

  2.若文件初始状态基本有序,则应选用直接插入, 冒泡或随机的快速排序为宜

  3.若n较大, 则应采用时间复杂度为0(nlgn)的排序方法: 快速排序或归并排序

      快速排序是目前基于比较的内部排序中被认为是最好的方法, 当待排序的关键字是随机分布时, 快速排序的平均时间最短

  4.若要求排序稳定, 则可选用归并排序

                  排序性能分析

  稳定性 : 如果存在多个具有相同排序码的元素, 经过排序后,这些元素的相对次序仍然保持不变,则这种排序算法称为稳定的

  排序稳定的 : 插入排序,冒泡排序,归并排序。

  排序不稳定的 : 选择排序, 快速排序

  时间复杂度 : 

      n^2 (慢的):冒泡排序, 选择排序, 插入排序

      nlgn(快的) :归并排序, 快速排序

                    二分查找

  1. 使用条件 : 只有在有序表中查找元素才可使用

  2. 折半查找 : 序列已经从小到大排好序了, 每次取中间元素和待查找的元素比较,如果中间的元素比待查找的元素小,就说明“如果待查找的元素存在,一定位于序列的后半部分”, 这样可以把搜索范围缩小到后半部分,然后再次使用这种算法迭代。这种“每次把搜索范围缩小一半”的思想称为折半查找  

                    位图思想

  1.使用条件:

        输入数据限制在相对较小的范围内,

        数据没有重复,,

        且除了单一整数外,么有任何其他关联数据

  2.例子 : 比如集合{1, 2, 3, 5, 8, 13}

      可以使用两个字节的16位记录

      位图表示为 : 

          0 1 1 1 0 1 0 0    1 0 0 0 0 1 0 0

  3.排序思想

        n / 32 与 n % 32

        计算n对应位图的位置

        置1 : set(int a[], int n)

        清0 :  clean(int a[], int n)

        查找:int bitmap_search(int a[], int n)  

      英语 : achieve(实现)  insert(插入)  merger(归并)  cutting elemet(切割元素)  record(记录)

原文地址:https://www.cnblogs.com/cxw825873709/p/3278429.html