3 #include <stdio.h>
4 #include <time.h>
5 void Swap(int &a, int &b)
6 {
7 int t = a;
8 a = b;
9 b = t;
10 }
11
12
13 //选择排序:交换移动次数少,O(n2)
14 void SelectSort(int a[],int n)//或者int *a
15 {
16 printf("选择排序\n");
17 for (size_t i = 0; i < n - 1; i++)
18 {
19 int minInt = a[i];
20 int index = i;
21 for (size_t j = i + 1; j < n; j++) //j从i+1开始
22 {
23 if (a[j] < minInt)
24 {
25 minInt = a[j];
26 index = j;
27 }
28 }
29 Swap(a[i], a[index]); // //这里一开始错写成了Swap(a[i], minInt);这就不是数组里面的交换了.所以要用个index.
30 for (int k = 0; k < n; k++)
31 {
32 printf("%d ", a[k]);
33 }
34 printf("\n");
35 }
36 }
37
38 //插入排序:
39 void InsertSort(int a[], int n) //按照宝典编的.(有交换的机制)
40 {
41 printf("插入排序\n");
42 int i, j;
43 for (i = 1; i < n; i++)
44 {
45 int temp = a[i];
46
47 //(1)写法1
48 /*
49 // for (j = i-1; j >= 0; j--) //因为temp的前一个不一定是它应该去的位置,所以要和前面的多个进行比较(所以j >= 0; j--)
50 // {
51 // if (temp < a[j])
52 // {
53 // a[j + 1] = a[j];
54 // }
55 // else
56 // {
57 // break; //当temp不小于紧贴的前一个a[j]时,就代表它不用调整位置,因为前面的顺序都是调整好的.
58 // } //这里的break是必须的,否则j会一直自减.
59 // }
60 // a[j + 1] = temp; //因为for循环j--.即使没有执行循环体,但是j = i-1是一定执行过了.所以无论执行循环体,都能妥善处理.
61 */
62
63
64 //(2)写法2(较简便)
65 for (j = i - 1; j >= 0 && temp < a[j]; j--)
66 {
67 a[j + 1] = a[j]; //大于temp的要往后挪,留出插入的空间.
68 }
69 a[j + 1] = temp; 因为for循环j--.即使没有执行循环体,但是j = i-1是一定执行过了.所以无论执行循环体,都能妥善处理.可以拿排好的顺序验证.
70 }
71 }
72
73 //冒泡排序
74 void BubbleSort(int a[], int n)
75 {
76 printf("冒泡排序\n");
77 int i, j;
78
79 /*
80 // (1)下沉形式
81 for (i = 0; i < n-1; i++) //i控制需要沉下去几个,沉下去n-1个就能确定最后的顺序.
82 {
83 for (j = 0; j < n - 1 - i; j++) //j代表矩阵内需要比较几次
84 {
85 if (a[j] > a[j+1])
86 {
87 Swap(a[j], a[j + 1]);
88 }
89 }
90 }
91 */
92
93 //(2)冒泡形式
94 for (i = 0; i < n - 1; i++)
95 {
96 for (j = n - 1; j > i ; j--)
97 {
98 if (a[j] < a[j - 1])
99 {
100 Swap(a[j], a[j - 1]);
101 }
102 }
103 }
104 }
105
106 //希尔排序
107 void ShellSort(int a[], int n)
108 {
109 printf("希尔排序\n");
110 int i, j, h; //h:增量
111 int temp;
112 for (h = n / 2; h > 0; h /= 2)
113 {
114 for (i = h; i < n; i += h)
115 {
116 temp = a[i];
117 for (j = i - h; j >= 0; j -= h) //j包括0. j -= h:一次跳h,找有没有比temp大的,往后挪,给temp让位.
118 {
119 if (temp < a[j])
120 {
121 a[j + h] = a[j];
122 }
123 else
124 break; //也可以写成插入排序的(2)
125 }
126 a[j + h] = temp;
127 }
128 }
129 }
130
131
132 //堆排序(采用Weiss的代码)
133 #define LeftChild(i) (2 * (i) + 1)
134 void PercDown(int a[], int i, int n)
135 {
136 int child;
137 int temp;
138 for (temp = a[i]; LeftChild(i) < n; i = child)
139 {
140 child = LeftChild(i);
141 if (child != n - 1 && a[child + 1] > a[child])
142 {
143 child++;
144 }
145 if (temp < a[child])
146 {
147 a[i] = a[child];
148 }
149 else
150 {
151 break;
152 }
153 }
154 a[i] = temp; //此处的i是child赋值过来的
155 }
156
157 void HeapSort(int a[], int n)
158 {
159 printf("堆排序\n");
160 int i;
161 for ( i = n / 2; i >= 0; i--) //对父结点有(i < = n/2) 这里结点序号从0开始和数组下标一致.
162 {
163 PercDown(a, i, n); // 创建大顶堆,自下而上,自右向左(思想可以参见<大话数据结构的第400页>)
164 }
165 for (i = n-1; i > 0; i--)//i > 0因为没有必要和自身交换
166 {
167 Swap(a[0], a[i]);
168 PercDown(a, 0, i); //以结点0创建大顶堆(包括所有有效的结点),因为只是把1和最后的记录交换,而其他结点都不变.其实上面的PercDown(a, i, n)是先下面创建,然后上面创建,大顶堆的元素数量越来越多.
169 }
170 }
171
172
173
174
175
176 int main()
177 {
178 int a[] = { 5,4,9,8,7,6,0,1,3,2 };
179 int len = sizeof(a) / sizeof(a[0]);// 也可以写作:int len = sizeof(a) / sizeof(int);182 //SelectSort(a, len);
183 //InsertSort(a, len);
184 //BubbleSort(a, len);
185 //ShellSort(a, len);
186 HeapSort(a, len);
187 clockEnd = clock();
188 for (int i = 0; i < len; i++)
189 {
190 printf("%d\n", a[i]);
191 }
193 return 0;
194 }
常见的排序操作代码(c++)
最新推荐文章于 2023-07-27 22:41:25 发布