13:50:24 2019-09-14
继续把未看完的看完
排序算法
定理:任意$N$个不同元素组成的序列平均具有$N(N-1)/4$个逆序对
定理:任何仅以交换相邻两元素来排序的算法,其平均时间复杂度为$Ω(N^2)$
这样子 冒泡排序 插入排序 的最坏情况都是 N^2
要使排序算法变高效 得使用间隔元素来交换 在一次排序中 交换多个逆序对的元素
希尔排序
定义增量序列$D_M>D_{M-1}>...>D_1=1$
$对每个D_k进行“D_k-间隔”排序(k=M,M-1,...1)$
$注意:“D_k-间隔"有序的序列,在执行”D_{k-1}间隔“排序后,仍然是“D_k-间隔"有序的$
如果增量元素不互质,则小增量可能根本不起作用
比如 $N=N/2$ 最坏情况 时候 $T=\theta(N^{2})$
那么就会有其他的增量序列:
Hibbard增量序列 $D_k=2^k-1$ --相邻元素互质 最坏情况$T=\theta(N^{3/2})$
猜想 Hibbard增量的 平均复杂度 $T_{avg}=O(N^{5/4})$
Sedgewick增量序列 $ \{1,5,19,41,109,.....\}$
$9*4^i-9*2^i或4^i-3*2^i+1$猜想$T_{avg}=O(N^{7/6}) T_{worst}=O(N^{4/3})$
冒泡排序 插入排序 希尔排序 选择排序 堆排序 归并排序(ps:其中堆排序写的是憨憨版本 之后会添上精明版本)

1 #define _CRT_SECURE_NO_WARNINGS
2 #include<stdio.h>
3 #include<malloc.h>
4 void Print(int A[], int N)
5 {
6 for (int i = 0; i < N; i++)
7 printf("%d ", A[i]);
8 printf("\n");
9 }
10 //排序算法
11
12 //冒泡排序 //最好 O(N) 最坏 O(N^2) 算法稳定
13 void Swap(int A[], int i, int j)
14 {
15 int temp = A[i];
16 A[i] = A[j];
17 A[j] = temp;
18 }
19 void Bubble_Sort(int A[], int N)
20 {
21 for (int i = 0; i < N; i++)
22 {
23 int IsSwap = 0;
24 for (int j = 0; j < N - i-1; j++)
25 {
26 if (A[j] > A[j + 1])
27 {
28 IsSwap = 1;
29 Swap(A, j, j + 1);
30 }
31 }
32 if (!IsSwap)
33 break;
34 }
35 }
36
37 //插入排序 //最好O(N) 最坏 O(N^2) 算法稳定
38 void Insert(int A[], int j, int i)
39 {
40 int temp = A[i];
41 for (; i > j; i--)
42 A[i] = A[i - 1];
43 A[j] = temp;
44 }
45 void Insert_Sort(int A[], int N)
46 {
47 /*for (int i = 0; i < N-1; i++)
48 {
49 int m = i + 1;
50 int j = i;
51 while (j >= 0 && A[j] > A[m])
52 j--;
53 Insert(A, j+1, m);
54 }*/
55 /*for (int i = 1; i < N; i++)
56 {
57 int temp = A[i];
58 int j;
59 for (j = i - 1; j >= 0 && A[j] > temp; j--)
60 A[j + 1] = A[j];
61 A[j + 1] = temp;
62 }*/
63 for (int p = 1; p < N; p++)
64 {
65 int temp = A[p];
66 int i;
67 for (i = p; i > 0 && A[i - 1] > temp; i--)
68 A[i] = A[i - 1];
69 A[i] = temp;
70 }
71 }
72
73 //希尔排序 //最坏情况 //改进插入排序
74 void Shell_Sort(int A[], int N)
75 {
76 /*for (int D = N / 2; D > 0; D /= 2)
77 {
78 for (int p = D; p < N; p++)
79 {
80 int temp = A[p];
81 int i;
82 for (i = p; i >= D && A[i - D] > temp; i -= D)
83 A[i] = A[i - D];
84 A[i] = temp;
85 }
86 }*/
87 // 利用Sedgewick增量序列
88 int Si;
89 int Sedgewick[] = { 929,505,209,109,41,19,5,1,0 };
90 for (Si = 0; Sedgewick[Si] >=N; Si++) //初始的增量Sedgewick[Si]不能超过待排序序列长度
91 ;
92 for (int D = Sedgewick[Si]; D>0;D=Sedgewick[++Si])
93 {
94 for (int p = D; p < N; p++)
95 {
96 int temp = A[p];
97 int i;
98 for (i = p; i >= D && A[i - D] > temp; i -= D)
99 A[i] = A[i - D];
100 A[i] = temp;
101 }
102 }
103 }
104
105 //选择排序
106 void Selection_Sort(int A[], int N)
107 {
108 for (int i = 0; i < N; i++)
109 {
110 int MinPosition = i;
111 int Min = A[i];
112 int j;
113 for (j = i + 1; j < N; j++)
114 {
115 if (A[j] < Min)
116 {
117 MinPosition = j;
118 Min = A[j];
119 }
120 }
121 Swap(A, i, MinPosition);
122 }
123 }
124
125 //堆排序 //选择排序的一种改进
126 //改进了寻找最小元的算法 利用最小堆来实现
127 typedef struct HeapStruct* MinHeap;
128 struct HeapStruct
129 {
130 int* Elements;
131 int Size;
132 int Capacity;
133 };
134 MinHeap Create(int MaxSize)
135 {
136 MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
137 H->Elements = (int*)malloc(sizeof(int) * (MaxSize + 1));
138 H->Capacity = MaxSize;
139 H->Size = 0;
140 H->Elements[0] = -10001;
141 return H;
142 }
143 MinHeap H = Create(20);
144 //建立最小堆
145 void PrecDown(MinHeap H, int i) //下滤
146 {
147 int Parent, Child;
148 int Tmp = H->Elements[i];
149 for (Parent = i; Parent * 2 <= H->Size; Parent = Child)
150 {
151 Child = Parent * 2;
152 if ((Child != H->Size) && (H->Elements[Child] > H->Elements[Child + 1]))
153 Child++;
154 if (Tmp <= H->Elements[Child])break;
155 else
156 H->Elements[Parent] = H->Elements[Child];
157 }
158 H->Elements[Parent] = Tmp;
159 }
160 void BuildMinHeap(MinHeap H)
161 {
162 int i;
163 for (i = H->Size / 2; i > 0; i--)
164 PrecDown(H, i);
165 }
166 int DeleteMin(MinHeap H)
167 {
168 int Parent, Child;
169 int MinItem, temp;
170 MinItem = H->Elements[1];
171 temp = H->Elements[H->Size--];
172 for (Parent = 1; Parent * 2 <= H->Size; Parent = Child)
173 {
174 Child = Parent * 2;
175 if (Child != H->Size && H->Elements[Child] > H->Elements[Child + 1])
176 Child++;
177 if (H->Elements[Child] >= temp)break;
178 else
179 H->Elements[Parent] = H->Elements[Child];
180 }
181 H->Elements[Parent] = temp;
182 return MinItem;
183 }
184 void Heap_Sort(int A[], int N)
185 {
186 //算法一 利用最小堆
187 /*int Tmp[10] = { 0 };
188 for (int i = 0; i < 10; i++)
189 Tmp[i] = DeleteMin(H);
190 for (int i = 0; i < 10; i++)
191 A[i] = Tmp[i];*/
192 /*for (int i = 0; i < 10; i++)
193 A[i] = DeleteMin(H);*/
194
195 //算法二 利用最大堆后 再调整
196 }
197
198 //归并排序
199 void Merge(int A[],int lo,int mi,int hi)
200 {
201 //两个有序序列的合并
202 int* B = (int*)malloc(sizeof(int) * (mi - lo));
203 for (int i = 0; i < mi - lo;)B[i++] = A[lo + i];
204 int i, j, k;
205 i = lo;
206 j = 0;
207 k = mi;
208 /*while (j<mi-lo||k<hi)
209 {
210 if((j<mi-lo)&&(k>=hi||B[j]<=A[k]))A[i++]=B[j++];
211 if ((k < hi) && (j >= mi-lo|| B[j] > A[k]))A[i++] = A[k++];
212 }*/
213 //化简版
214 while (j<mi-lo)
215 {
216 if (k >= hi || B[j] <= A[k])A[i++] = B[j++];
217 if (k<hi && B[j]>A[k])A[i++] = A[k++];
218 }
219 /*邓公版本*/
220 /*int* A1= A + lo;
221 int* B = (int*)malloc(sizeof(int) * (mi - lo));
222 for (int i = 0; i < mi - lo; B[i] = A1[i++]);
223 int* C = A + mi;
224 int i, j, k;*/
225 /*for (i = j = k = 0; j < mi - lo || k < hi-mi;)
226 {
227 if (j < mi - lo&&((k >= hi - mi)||B[j] <=C[k]))A1[i++] = B[j++];
228 if (k < hi - mi && (j >= mi - lo || B[j] > C[k]))A1[i++] = C[k++];
229 }*/
230 //简化
231 /*for (i = j = k = 0; j < mi - lo;)
232 {
233 if (k >= hi - mi || B[j] <= C[k])A1[i++] = B[j++];
234 if (k < hi - mi && (j >= mi - lo || B[j] > C[k]))A1[i++] = C[k++];
235 }*/
236 }
237 void MergeSort(int A[],int lo,int hi)
238 {
239 if (lo == hi - 1)
240 return;
241 int mi = (lo + hi) >> 1;
242 MergeSort(A,lo, mi);
243 MergeSort(A, mi, hi);
244 Merge(A,lo, mi, hi);
245 }
246 int main()
247 {
248 int A[10];
249 for (int i = 0; i < 10; i++)
250 scanf("%d", &A[i]);
251 //Bubble_Sort(A, 10);
252 //Insert_Sort(A, 10);
253 //Shell_Sort(A, 10);
254 //Selection_Sort(A, 10);
255 //堆排序
256 /*for (int i = 1; i <= 10; i++)
257 H->Elements[++H->Size] = A[i - 1];
258 BuildMinHeap(H); //构建最小堆
259 Heap_Sort(A, 10);*/
260 MergeSort(A,0,10);
261 Print(A, 10);
262 return 0;
263 }
