8.排序

Posted 走遍天涯心随你起落

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8.排序相关的知识,希望对你有一定的参考价值。

8.排序

8.1排序概述

排序分为内部排序和外部排序

 

 

8.2冒泡排序法

基本思想

对待排序记录关键字从后往前(逆序)进行多遍扫描,当发现相邻两个关键字的次序与排序要求的规则不符时,就将这两个记录进行交换。这样,关键字较小的记录将逐渐从后面向前面移动,就象气泡在水中向上浮一样,所以该算法也称为气泡排序法。

 

 

算法实现

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <conio.h>
 4 
 5 void BubbleSort(int a[], int n)  //冒泡排序
 6 {
 7     int i, j, t;
 8     for (i = 0; i<n - 1; i++)
 9     {
10         for (j = n - 1; j>i; j--)
11         {
12             if (a[j - 1]>a[j])
13             {
14                 t = a[j - 1];
15                 a[j - 1] = a[j];
16                 a[j] = t;
17             }
18         }
19         printf("第%2d遍:", i + 1);
20         for (j = 0; j<n; j++)
21             printf("%d ", a[j]);
22         printf("\\n");
23     }
24 }
25 void BubbleSort1(int a[], int n) //改进冒泡排序
26 {
27     int i, j, t, flag = 0;        //flag用来标记是否发生交换
28     for (i = 0; i<n - 1; i++)
29     {
30         for (j = n - 1; j>i; j--)
31         {
32             if (a[j - 1]>a[j])//交换数据 
33             {
34                 t = a[j - 1];
35                 a[j - 1] = a[j];
36                 a[j] = t;
37                 flag = 1;
38             }
39         }
40         printf("第%2d遍:", i + 1);
41         for (j = 0; j<n; j++)
42             printf("%d ", a[j]);
43         printf("\\n");
44         if (flag == 0)    //没发生交换,直接跳出循环
45             break;
46         else
47             flag = 0;
48     }
49 }
50 int main()
51 {
52     int i;
53     int a[6] = {69,65,90,37,92,6};
54     printf("原数据:");
55     for (i = 0; i<6; i++)
56         printf("%d ", a[i]);
57     printf("\\n");
58 
59     BubbleSort(a, 6);
60     printf("冒泡排序后:\\n");
61     for (i = 0; i<6; i++)
62         printf("%d ", a[i]);
63     printf("\\n");
64 
65     getch();
66     return 0;
67 }

 

 

 

附:

用产生的随机数排序

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 #include <conio.h>
 4 #include <time.h>
 5 #define ARRAYLEN 6
 6 int CreateData(int arr[], int n, int min, int max) //创建一个随机数组,a保存生成的数据,n为数组元素的数量 
 7 {
 8     int i, j, flag;
 9     srand(time(NULL));
10     if ((max - min + 1)<n) 
11         return 0; //最大数与最小数之差小于产生数组的数量,生成数据不成功 
12     for (i = 0; i<n; i++)
13     {
14         do
15         {
16             arr[i] = (max - min + 1)*rand() / (RAND_MAX + 1) + min; //生成数不能相同
17             flag = 0;
18             for (j = 0; j<i; j++)
19             {
20                 if (arr[i] == arr[j]) //相同重新生成
21                     flag = 1;
22             }
23         } while (flag);
24     }
25     return 1;
26 }
27 
28 void BubbleSort(int a[], int n)  //冒泡排序
29 {
30     int i, j, t;
31     for (i = 0; i<n - 1; i++)
32     {
33         for (j = n - 1; j>i; j--)
34         {
35             if (a[j - 1]>a[j])
36             {
37                 t = a[j - 1];
38                 a[j - 1] = a[j];
39                 a[j] = t;
40             }
41         }
42         printf("第%2d遍:", i + 1);
43         for (j = 0; j<n; j++)
44             printf("%d ", a[j]);
45         printf("\\n");
46     }
47 }
48 void BubbleSort1(int a[], int n) //改进冒泡排序
49 {
50     int i, j, t, flag = 0;        //flag用来标记是否发生交换
51     for (i = 0; i<n - 1; i++)
52     {
53         for (j = n - 1; j>i; j--)
54         {
55             if (a[j - 1]>a[j])//交换数据 
56             {
57                 t = a[j - 1];
58                 a[j - 1] = a[j];
59                 a[j] = t;
60                 flag = 1;
61             }
62         }
63         printf("第%2d遍:", i + 1);
64         for (j = 0; j<n; j++)
65             printf("%d ", a[j]);
66         printf("\\n");
67         if (flag == 0)    //没发生交换,直接跳出循环
68             break;
69         else
70             flag = 0;
71     }
72 }
73 int main()
74 {
75     int i, a[ARRAYLEN];
76     for (i = 0; i<ARRAYLEN; i++)
77         a[i] = 0;
78 
79     if (!CreateData(a, ARRAYLEN, 1, 100))
80     {
81         printf("生成随机数不成功!\\n");
82         getch();
83         return 1;
84     }
85 
86     printf("原数据:");
87     for (i = 0; i<ARRAYLEN; i++)
88         printf("%d ", a[i]);
89     printf("\\n");
90 
91     BubbleSort1(a, ARRAYLEN);
92     printf("排序后:");
93     for (i = 0; i<ARRAYLEN; i++)
94         printf("%d ", a[i]);
95     printf("\\n");
96 
97     getch();
98     return 0;
99 }

 

 

8.3快速排序法

基本思想:

快速排序使用分治策略来把待排序数据序列分为两个子序列,具体步骤为:

(1)从数列中挑出一个元素,称该元素为“基准”。

(2)扫描一遍数列,将所有比“基准”小的元素排在基准前面,所有比“基准”大的元素排在基准后面。

(3)通过递归,将各子序列划分为更小的序列,直到把小于基准值元素的子数列和大于基准值元素的子数列排序。

 

 

算法实现:

 1 #include <stdio.h>
 2 #include <conio.h>
 3 #define ARRAYLEN 8
 4 int Division(int a[], int left, int right) //分割 
 5 {
 6     int base = a[left];    //基准元素
 7     while (left<right)
 8     {
 9         while (left<right && a[right]>base)
10             --right;     //从右向左找第一个比基准小的元素
11         a[left] = a[right];
12         while (left<right && a[left]<base)
13             ++left;      //从左向右找第一个比基准大的元素
14         a[right] = a[left];
15     }
16     a[left] = base;
17     return left;
18 }
19 void QuickSort(int a[], int left, int right)
20 {
21     int i, j;
22     if (left<right)
23     {
24         i = Division(a, left, right);   //分割
25         QuickSort(a, left, i - 1);      //将两部分分别排序
26         QuickSort(a, i + 1, right);
27     }
28 }
29 int main()
30 {
31     int i, a[ARRAYLEN] = {69,65,90,37,92,6,28,54};
32     printf("原数据:");
33     for (i = 0; i<ARRAYLEN; i++)
34         printf("%d ", a[i]);
35     printf("\\n");
36 
37     QuickSort(a, 0, ARRAYLEN - 1);
38     printf("排序后:");
39     for (i = 0; i<ARRAYLEN; i++)
40         printf("%d ", a[i]);
41     printf("\\n");
42 
43     getch();
44     return 0;
45 }

 

 

8.4选择排序法

思想:

     选择排序(Selection Sort)的基本思想:对n个记录进行扫描,选择最小的记录,将其输出,接着在剩下的n-1个记录中扫描,选择最小的记录将其输出,……不断重复这个过程,直到只剩一个记录为止。

 

 

算法实现:

 1 #include <stdio.h>
 2 #include <conio.h>
 3 #define ARRAYLEN 8
 4 void SelectSort(int a[], int n)
 5 {
 6     int i, j, t, k;
 7     for (i = 0; i<n - 1; i++)
 8     {
 9         k = i;
10         for (j = i; j<n; j++){
11             if (a[k]>a[j])
12                 k = j;
13         }
14         t = a[i];
15         a[i] = a[k];
16         a[k] = t;
17     }
18 }
19 int main()
20 {
21     int i, a[ARRAYLEN] = {69,65,90,37,92,6,28,54};
22     printf("原数据:");
23     for (i = 0; i<ARRAYLEN; i++)
24         printf("%d ", a[i]);
25     printf("\\n");
26 
27     SelectSort(a,ARRAYLEN);
28     printf("排序后:");
29     for (i = 0; i<ARRAYLEN; i++)
30         printf("%d ", a[i]);
31     printf("\\n");
32 
33     getch();
34     return 0;
35 }

 

 

8.5堆排序法

基本思想:

堆是一个完全二叉树,树中每个结点对应于原始数据的一个记录,并且每个结点应满足以下条件:非叶结点的数据大于或等于其左、右孩子结点的数据(若是按从大到小的顺序排序,则要求非叶结点的数据小于或等于其左、右孩子结点的数据)。

 

由堆的定义可看出,其根结点为最大值,堆排序就是利用这一特点进行的。堆排序过程包括两个阶段:

(1)将无序的数据构成堆(即用无序数据生成满足堆定义的完全二叉树)。

(2)利用堆排序(即用上一步生成的堆输出有序的数据)。

 

例:对69、65、90、37、92、6、28、54堆排序

 

 

 

 

算法实现:

 1 #include <stdio.h>
 2 #include <conio.h>
 3 #define ARRAYLEN 8
 4 void HeapAdjust(int a[], int s, int n)//构成堆
 5 {
 6     int j, t;
 7     while (2 * s <n) //第s个结点有右子树 
 8     {
 9         j = 2 * s ;
10         if ((j + 1)<n)
11         {
12             if (a[j]<a[j + 1])//右左子树小于右子树,则需要比较右子树
13                 j++; //序号增加1,指向右子树 
14         }
15         if (a[s]<a[j])//比较s与j为序号的数据
16         {
17             t = a[s];  //交换数据 
18             a[s] = a[j];
19             a[j] = t;
20             s = j;//堆被破坏,需要重新调整
21         }
22         else //比较左右孩子均大则堆未破坏,不再需要调整
23             break;
24     }
25 }
26 void HeapSort(int a[], int n)//堆排序
27 {
28     int t, i;
29     int j;
30     for (i = n/2-1 ; i >= 0; i--)    //将a[0,n-1]建成大根堆
31         HeapAdjust(a, i, n);
32     for (i = n - 1; i>0; i--)
33     {
34         t = a[0];//与第i个记录交换
35         a[0] = a[i];
36         a[i] = t;
37         HeapAdjust(a, 0, i);        //将a[0]至a[i]重新调整为堆
38     }
39 }
40 int main()
41 {
42     int i, a[ARRAYLEN] = {69,65,90,37,92,6,28,54};
43     printf("原数据:");
44     for (i = 0; i<ARRAYLEN; i++)
45         printf("%d ", a[i]);
46     printf("\\n");
47 
48     HeapSort(a,ARRAYLEN);
49     printf("排序后:");
50     for (i = 0; i<ARRAYLEN; i++)
51         printf("%d ", a[i]);
52     printf("\\n");
53 
54     getch();
55     return 0;
56 }

 

 

 

8.6插入排序法

基本思想:

插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后移动,为最新元素提供插入空间。

 

 

算法实现:

 1 #include <stdio.h>
 2 #include <conio.h>
 3 #define ARRAYLEN 8
 4 void InsertSort(int a[], int n)//直接插入排序 
 5 {
 6     int i, j, t;
 7     for (i = 1; i<n; i++)
 8     {
 9         t = a[i];     //取出一个未排序的数据 
10         for (j = i - 1; j >= 0 && t<a[j]; --j)     //在排序序列中查找位置 
11             a[j + 1] = a[j]; //向后移动数据 
12         a[j + 1] = t; //插入数据到序列 
13     }
14 }
15 int main()
16 {
17     int i, a[ARRAYLEN] = {69,65,90,37,92,6,28,54};
18     printf("原数据:");
19     for (i = 0; i<ARRAYLEN; i++)
20         printf("%d ", a[i]);
21     printf("\\n");
22 
23     InsertSo

以上是关于8.排序的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

7种基本排序算法的Java实现

Xcode 8 Autocomplete Broken - 仅显示有限的用户代码片段 - 知道为啥吗?

ES7-Es8 js代码片段

有没有办法将2个非常相似的代码片段组合成一个函数并重复?