排序法总结

来源:互联网 发布:windows xp还原系统 编辑:程序博客网 时间:2024/05/04 08:54

排序法总结,属个人整理、总结。有不妥之处望指出,讨论。

一路向南 2013年9月13日 16:16:07  初稿

1. merge 归并排序

时间复杂度 θ(nlgn)。

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
思路为: 先将一组数列分为  2组-> 4组->8组 .......    最后为复杂度为θ(1)的单个数组最后返回组合。
其图解为:

/************************************************************************//*归并排序                          一路向南  2013年9月13日 16:21:15*//************************************************************************/#include<iostream>#include<time.h>#include<assert.h>#include<windows.h>#define NUM_SORT 10000using namespace std;template <class T>void MergeSort(T * array, int begin, int end){assert(begin <end);T *temp_array = new T[end -begin+1];memset(temp_array, 0, (end - begin+1)*sizeof(T));MergeSortIn(array,temp_array, begin, end);delete []temp_array;}template<class T>void MergeSortIn(T*array,T*temp_array, int begin , int end){if (begin< end){int mid = (end +begin)/2;MergeSortIn(array, temp_array, begin, mid);  // 分割   并归MergeSortIn(array, temp_array, mid +1, end);Merge(array, temp_array, begin, mid, end);}else{return;}}template<class T>void Merge(T* array, T* temp_array, int begin, int mid, int end){int high =mid+1;int temp_loc =begin;int low =begin;while (low<= mid && high <=end){if (array[low] < array[high]){temp_array[temp_loc++] = array[low++];}else{temp_array[temp_loc++] = array[high++]; // mid ---- end}}while (low <=mid){temp_array[temp_loc++] =array[low ++];}while (high <=end){temp_array[temp_loc++] = array[high++];}for (int i=begin; i<=end; ++i){array[i] = temp_array[i];}}int main(){int num_array[NUM_SORT];srand(time(NULL)); // 设定种子// 产生随机数cout<<"#######################before sorted######################"<<endl;for (int i=0; i< NUM_SORT; ++i){num_array[i] = rand()%NUM_SORT;//cout<<num_array[i]<<"\t";}cout<<endl;DWORD start =GetTickCount();MergeSort(num_array, 0, NUM_SORT-1);start = GetTickCount() -start;cout<<"#######################after sorted######################"<<endl;for (int i=0; i< NUM_SORT; ++i){//cout<<num_array[i]<<"\t";}cout<<endl<<"#############################################\n";cout<<NUM_SORT<<"  num   cost: "<<start<<"ms"<<endl;}

#define NUM_SORT 100000 个数据排序所用时间:速度较快


2 插入法排序
百度百科:输入一个元素,检查数组列表中的每个元素,将其插入到一个已经排好序的数列中的适当位置,使数列依然有序,当最后一个元素放入合适位置时,该数组排序完毕。//例1:输入一个数,插入一个各元素已经按照升序排列的数组中,插入后使数组中元素仍然是按照升序排列的。思想:把欲插入的数与数组中各数逐个比较, 当找到第一个比插入数大的元素i时,该元素之前即为插入位置。然后从数组最后一个元素开始到该元素为止,逐个后移一个单元。最后把插入数赋予元素a[i]即可。如果被插入数比所有的元素值都小则插入最前位置。

/************************************************************************//*插入法排序                      一路向南  2013年9月13日 16:31:24*//************************************************************************/#include<iostream>#include<windows.h>#include<time.h>#include<assert.h>using namespace std;#define NUM_SORT 100000 template <class T>inline void MySwap(T& a, T& b){a ^= b;b ^= a;a ^= b;}template <class T>void InsertSort(T *array, int begin , int end){assert(begin< end);int loc = begin+1;int k =0;while (loc <=end){k=loc;while (array[k - 1]> array[ k ] && ( k > begin)){MySwap(array[ k - 1 ], array[ k ]);--k;}++loc;}}int main(){int array[NUM_SORT];srand(time(NULL));   //设置种子//赋值cout<<"################## before sorting #####################\n";for (int i=0; i< NUM_SORT; ++i){array[i] = rand()%NUM_SORT;//cout<<array[i]<<"\t";}cout<<endl;DWORD start =GetTickCount();InsertSort(array, 0, NUM_SORT-1);start = GetTickCount() -start;cout<<"################## after sorting #####################\n";for (int i=0; i<NUM_SORT; ++i){//cout<<array[i]<<"\t";}cout<<endl;cout<<NUM_SORT<<"  num   cost: "<<start<<"ms"<<endl;}

#define NUM_SORT 100000 个数据排序所用时间:很慢


3 快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序时间复杂度下界为O(nlogn),最坏情况为O(n^2)。 点击图片链接动画演示:


/************************************************************************//*快速排序一路向南  2013年9月14日 11:23:20*//************************************************************************/#include<iostream>#include<time.h>#include<windows.h>using namespace std;#define NUM_SORT 100000template <class T>inline void MySwap( T& a, T& b){if (a ==b){return;}a^=b;b^=a;a^=b;}template<class T>int Partition(T* array,int begin , int end){int i = begin, p=begin;int x =array[i];for (int j =i+1; j<=end; ++j){if (x > array[j]){++i;MySwap(array[i], array[j]);}}MySwap(array[p], array[i]);return i;}template <class T>void QuikSort(T* array, int begin, int end){if (begin >=end){return;}int loc = Partition(array, begin, end);QuikSort(array, begin, loc-1);QuikSort(array, loc+1, end);}int main(){int array[NUM_SORT];srand(time(NULL));cout<<"################## before sorting #####################\n";for (int i=0; i< NUM_SORT; ++i){array[i] = rand()%NUM_SORT;//cout<<array[i]<<"\t";}cout<<endl;DWORD start =GetTickCount();QuikSort(array, 0, NUM_SORT-1);start = GetTickCount() -start;cout<<"################## after sorting #####################\n";for (int i=0; i<NUM_SORT; ++i){//cout<<array[i]<<"\t";}cout<<endl<<endl;cout<<NUM_SORT<<"  num   cost: "<<start<<"ms"<<endl;}

#define NUM_SORT 100000 个数据排序所用时间:较快

4 冒泡法排序
冒泡排序算法的运作如下:
(1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
(3)针对所有的元素重复以上的步骤,除了最后一个。
(4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

/************************************************************************//*  冒泡法排序一路向南  2013年9月14日 16:29:58 *//************************************************************************/#include<iostream>#include<windows.h>#include<time.h>using namespace std;#define NUM_SORT 100000template<class T>inline void MySwap(T& a, T& b){a ^=b;b ^=a;a ^=b;}template<class T>void OrderSort(T* array, int begin, int end){for (int i=0; i<=end; ++i){for (int j=i+1; j<=end; ++j){if (array[i] >array[j]){MySwap(array[i], array[j]);}}}}int main(){int array[NUM_SORT];srand(time(NULL));cout<<"################## before sorting #####################\n";for (int i=0; i< NUM_SORT; ++i){array[i] = rand()%NUM_SORT;//cout<<array[i]<<"\t";}cout<<endl;DWORD start =GetTickCount();OrderSort(array, 0, NUM_SORT-1);start = GetTickCount() -start;cout<<"################## after sorting #####################\n";for (int i=0; i<NUM_SORT; ++i){//cout<<array[i]<<"\t";}cout<<endl<<endl;cout<<NUM_SORT<<"  num   cost: "<<start<<"ms"<<endl;}

#define NUM_SORT 100000 个数据排序所用时间:很慢











原创粉丝点击