【原创】【温故而知新】排序算法复习

上一篇博客也谈到之前和同学聊天希尔排序都忘了,今天准备复习一下常用的几种排序算法。

 

首先是面试时比较常见的快速排序,快速排序是一种不稳定排序,快速排序的时间复杂度,在最好情况下是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)

 

第一次总结自己看到的排序算法,程序都是自己敲出来的,如有更好的建议,欢迎指正,共同学习。 

 

  1 /*
  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 } 

 

转载请说明出处,谢谢。 

posted @ 2013-04-30 09:31  karlthas  阅读(323)  评论(0编辑  收藏  举报