排序法总结,属个人整理、总结。有不妥之处望指出,讨论。
一路向南 2013年9月13日 16:16:07 初稿
1. merge 归并排序
时间复杂度 θ(nlgn)。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为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 10000
using 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 100000
template <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)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
(1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
(3)针对所有的元素重复以上的步骤,除了最后一个。
(4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
/************************************************************************/
/* 冒泡法排序
一路向南 2013年9月14日 16:29:58 */
/************************************************************************/
#include<iostream>
#include<windows.h>
#include<time.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 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 个数据排序所用时间:很慢