【原创】【温故而知新】排序算法复习
上一篇博客也谈到之前和同学聊天希尔排序都忘了,今天准备复习一下常用的几种排序算法。
首先是面试时比较常见的快速排序,快速排序是一种不稳定排序,快速排序的时间复杂度,在最好情况下是O(nlogn),最坏的情况下是O(n2),这是在排序序列已经有序的情况下。
快速排序是基于分治法的排序,其主程序中采用了递归调用的思想。
排序在一次划分(即划分递归界限)的算法中,先选择一个中位数(可以选序列随机一个元素),循环的先从序列后面往前找到第一个小于中位数的元素,与中位数交换,再从前面往后找到第一个大于中位数的元素,与中位数交换,直所有的元素都被访问了一遍,一次划分算法完成。
第二个最常见,也是最最基本的排序算法叫做冒泡排序,提到这个排序,那可真是毁誉参半,誉的是大多数人在面试时情急之下几乎都会想到这个排序,哈哈;毁的是这个排序算法有着超低的时间复杂度O(n2),最差平均的情况下都是O(n2),,最好的情况下为O(n)(还阔以哦!)。另外,冒泡排序是稳定的排序算法。
这个算法的基本思想是先从数组的第一个元素开始,依次与数组的后面元素相比较,如果前一个元素大于后一个元素,则交换两个元素的位置,这个为下沉的冒泡排序,往上的冒泡排序同理。一共比较n-1次
第三个排序算法,选择排序,选择排序是一种不稳定的排序算法,其基本思想是每次从数组中选一个最小的元素出来,与数组的第一个元素,第二个元素。。。交换,一看这种思想就是时间复杂度很高的。。于是选择排序最差、平均时间复杂度均为O(n2),没有最好,因为这个排序算法本身就是效率非常低的,因为你不知道哪个是最小的元素,每次都需要比较。由于需要交换元素,选择排序是一种不稳定的排序。
第四个排序算法为希尔排序,希尔排序的基本思想是先取一个小于n的整数d1作为第一个增量,文件的全部记录分为d1 个组,所有的距离为d1的倍数的记录归为1类,在各组进行直接插入排序,然后去第二个增量d2,d2<d1,重复上述的分组和排序,直到所取的增量dt = 1,希尔排序的方法其实是一种分组插入方法。希尔排序是一种不稳定的排序,其时间复杂度为O(nlogn)
第五个排序为直接插入排序,基本思想是每次将一个待排序的记录按其关键字大小插入到前面已排好序的子数组中的适当位置,直到全部记录插入完成为止。直接插入排序是一种稳定的排序,时间复杂度最差和平均都是O(n^2),最好的情况是O(n).
直接插入排序的主程序如下:
第六个排序为归并排序,常用的有二路归并,归并排序将若干个已排序的子文件合并成一个有序的文件,比如A[low...m] && A[m+1...high] copy to Temp[];then copy Temp to A[low...high].归并排序的时间复杂度,最好最坏和平均情况下都是O(nlogn),需要特别注意的是归并排序有O(N)的空间开销,归并排序是一种稳定的排序。
第七个排序为基数排序,基数排序是典型的LSD排序,其基本思想是从低位到高位对数据进行箱排序,在d次箱排序中,所需的箱子数是基数rd(可能的取值个数),对数字进行排序时,如果整数的范围没有指明时,需要查找数组最大的元素有多少位,以便确定需要进行几次分配和收集,还需要知道每一位是什么。
需要如下几个函数:
1.find_max,找到序列中最大的数
2.digit_number,计算最大的数有几位
3.kth_digit,找到number第k位的数字
基数排序的时间复杂度为O(dn),d为常数,空间复杂度为O(n),它是一种稳定的排序算法。
第八个排序算法为堆排序:
贴一个别人的教程,我感觉自己讲不明白
地址:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
堆排序的时间复杂度,三种情况下都是O(nlogn)
第一次总结自己看到的排序算法,程序都是自己敲出来的,如有更好的建议,欢迎指正,共同学习。
2 排序算法汇总:2013.4.29 sort.h
3 算法清单:
4 1.bubble-sort[stable]√
5 2.insert-sort[stable]√
6 3.selection-sort[unstable]√
7 4.quick-sort[unstable]√
8 5.shell-sort[unstable]√
9 6.merge-sort[unstable]√descend
10 7.heap-sort[unstable]√descend
11 8.radix-sort[stable]√
12
13 Filed By Karlthas.
14 */
15 #include<math.h>
16 using namespace std;
17 //===========================================================
18 //bubble-sort
19 template<typename T>
20 void bubble_sort(T a[],int n)
21 {
22 int i,j;
23 T temp;
24 for(i = 0;i < n;i++)
25 {
26 for(j = 0;j < n-i-1;j++)
27 {
28 if(a[j] > a[j+1])
29 {
30 temp = a[j];
31 a[j] = a[j+1];
32 a[j+1] = temp;
33 }
34 }
35 }
36 }
37 //============================================================
38 //insert-sort
39 template<typename T>
40 void insert_sort(T a[],int n)
41 {
42 int i,j;
43 T temp;
44 for(i=1;i<n;i++)
45 {
46 temp = a[i];
47 for( j = i-1; j>=0 && temp < a[j] ;j--)
48 {
49 a[j+1] = a[j];
50 }
51 a[j+1] = temp;
52 }
53 }
54 //=============================================================
55 //selection-sort
56 template<typename T>
57 void selection_sort(T a[],int n)
58 {
59 int i , j ,k = 0,loc;
60 T temp , min = a[0];
61 for(i = 0;i<n;i++)
62 {
63 min = a[i];
64 loc = i;
65 for(j = i;j<n;j++)
66 {
67 if(a[j] < min)
68 {
69 min = a[j];
70 loc = j;
71 }
72 }
73 temp = a[k];
74 a[k] = a[loc];
75 a[loc] = temp;
76 k++;
77 }
78 }
79 //===============================================================
80 // quick-sort
81 /*
82 template<typename T>
83 void quick_sort(T a[],int low,int high)
84 {
85 int i,j;
86 T pivot;
87 if(low < high)
88 {
89 pivot = a[low];
90 i = low;
91 j = high;
92 while(i < j)
93 {
94 while(i<j && a[j]>=pivot)j--;
95 if(i<j)a[i++]=a[j];
96 while(i<j && a[i]<=pivot)i++;
97 if(i<j)a[j--]=a[i];
98 }
99 a[i] = pivot;
100 quick_sort(a,low,i-1);
101 quick_sort(a,i+1,high);
102 }
103 }
104 */
105 template<typename T>
106 int partition(T a[],int low,int high)
107 {
108 int mid;
109 T temp = a[low];
110 while(low < high )
111 {
112 while(low < high && a[high] >= a[low])
113 high --;
114
115 if(low < high)a[low++] = a[high];
116
117 while(low < high && a[low] <= a[high])
118 low++;
119
120 if(low < high)a[high--] = a[low];
121 }
122 a[low] = temp;
123 return low;
124 }
125 template<typename T>
126 void quick_sort(T a[],int low,int high)
127 {
128 int mid;
129 if(low<high)
130 {
131 mid = partition(a,low,high);
132 quick_sort(a,low,mid-1);
133 quick_sort(a,mid+1,high);
134 }
135 }
136 //=================================================================
137 //shell-sort
138 template<typename T>
139 void shell_sort(T a[],int len)
140 {
141 int d = len / 2;
142 int i;
143 T temp;
144 while(d > 1)
145 {
146 d = (d + 1 )/ 2;
147 for(i = 0;i < len -d;i++)
148 {
149 if (a[i+d] < a[i])
150 {
151 temp = a[i+d];
152 a[i+d] = a[i];
153 a[i] = temp;
154 }
155 }
156 }
157 }
158 //===============================================================
159 //merge-sort
160 template<typename T>
161 void merge(T a[],T tmp[],int L_pos,int R_pos,int R_end)
162 {
163 int i,Tmp_pos = L_pos,L_end = R_pos-1;
164 while(L_pos <= L_end && R_pos <= R_end)
165 {
166 if(a[L_pos] <= a[R_pos])
167 tmp[Tmp_pos++] = a[L_pos++];
168 else
169 tmp[Tmp_pos++] = a[R_pos++];
170 }
171 while(L_pos <= L_end)
172 tmp[Tmp_pos++] = a[L_pos++];
173 while(R_pos <= R_end)
174 tmp[Tmp_pos++] = a[R_pos++];
175 for(i = 0;i< R_end - L_pos + 1 ; i++,R_end--)
176 a[R_end] = tmp[R_end];
177 }
178 template<typename T>
179 void m_sort(T a[],T tmp,int low,int high)
180 {
181 if(low >= high)return;
182 int mid = (low+high)/2;
183 m_sort(a,tmp,low,mid);
184 m_sort(a,tmp,mid+1,high);
185 merge(a,tmp,low,mid+1,high);
186 }
187 template<typename T>
188 void merge_sort(T a[],int len)
189 {
190 int *tmp = NULL;
191 tmp = new int[len];
192 if(tmp!=NULL)
193 {
194 m_sort(a,tmp,0,len-1);
195 delete [] tmp;
196 }
197 }
198 //==============================================================
199 //heap-sort
200 //question : how to build a ascending array
201 template<typename T>
202 void fixdown(T a[],int i,int n)
203 {
204 int j;
205 T temp = a[i];
206 j = 2*i+1;
207 while(j<n)
208 {
209 if(j+1<n && a[j+1] < a[j])
210 j++;
211 if(a[j] >= temp)break;
212 a[i] = a[j];
213 i = j;
214 j = 2*i+1;
215 }
216 a[i] = temp;
217 }
218 template<typename T>
219 void make_heap(T a[],int n)
220 {
221 int i,j;
222 T temp;
223 for(i = n/2-1;i>= 0;i--)
224 {
225 fixdown(a,i,n);
226 }
227 }
228 template<typename T>
229 void heap_sort(T a[],int n)
230 {
231 int i = 0;
232 T temp;
233 make_heap(a,n);
234 for(i = n-1;i>=1;i--)
235 {
236 temp = a[i];
237 a[i] = a[0];
238 a[0] = temp;
239 fixdown(a,0,i);
240 }
241 }
242 //========================================================
243 //radix-sort
244 int find_max(int a[],int len)
245 {
246 int max = a[0];
247 for(int i = 1;i<len;i++)
248 {
249 if(a[i]>max)max = a[i];
250 }
251 return max;
252 }
253 int digit_num(int num)
254 {
255 int digit = 0;
256 do
257 {
258 num /= 10;
259 digit++;
260 }while(num!=0);
261 return digit;
262 }
263 int kth_digit(int number,int K)
264 {
265 number /= pow(10,K);
266 return number % 10;
267 }
268 void radix_sort(int a[],int len)
269 {
270 int *temp[10];//指针数组,每一个指针表示一个箱子
271 int count[10] = {0,0,0,0,0,0,0,0,0,0};//用于存储每个箱子表示多少个元素
272 int max = find_max(a,len);
273 int maxDigit = digit_num(max);
274 int i,j,k;
275 for(i=0;i<10;i++)
276 {
277 temp[i] = new int[len];//让每个箱子能够装下len个元素(在这里是int类型)
278 memset(temp[i],0,sizeof(int)*len);//初始化为0
279 }
280 for(i=0;i<maxDigit;i++)
281 {
282 memset(count,0,sizeof(int)*10);//每次装箱之前把count清空
283 for(j=0;j<len;j++)
284 {
285 int xx = kth_digit(a[j],i);//将数据安装位数放入到暂存数组中
286 temp[xx][count[xx]] = a[j];
287 count[xx]++;//箱子计数递增
288 }
289 int index = 0;
290 for(j=0;j<10;j++)//将数据从暂存数组中取回,放入原始数组中
291 {
292 for(k=0;k<count[j];k++)//把箱子里所有的元素都取回到原始数组中
293 {
294 a[index++]=temp[j][k];
295 }
296 }
297 }
298 }
转载请说明出处,谢谢。