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注入(代码片段