您的位置:首页 > 理论基础 > 数据结构算法

<数据结构>各种排序算法的实现与总结(一)

2014-03-27 20:50 369 查看
前段时间,由于有些事情的耽误,还有就是自己有点懒,所以很久没有写博客了,今天打算给大家带来数据结构中的常见问题——排序,同时这也是面试中经常被问到的部分,因此今天决定对各种排序算法进行自我梳理一遍,以此巩固自己的基础。

排序算法常见的有:冒泡排序,选择排序,直接插入排序,希尔排序,归并排序,快速排序,堆排序,基数排序这八种排序算法,主要从时间复杂度、空间复杂度、稳定性、是否与初始的次序有关等方面来评价该排序算法的优劣。

以上四点判断,其实只要真正明白了其算法思想,按照其流程走,不难分析出其中的缘由。网上分析其思想原理的资料太多,我在此就不在赘述了。直接给出C++代码实现,以供大家参考,大家有什么建议和意见,可以直接留言或私信。

"sort_algorithms.h":

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
//冒泡排序
void bubble_sort(int *, int n );

//选择排序
void choose_sort(int *, int n);

//插入排序
void insert_sort(int *, int n);

//希尔排序
void  shell_sort(int *, int n);

//归并排序
void merge_sort(int *, int begin, int end, int *);
void merge_array(int *,int begin, int mid, int end, int *);
void MergeSort(int *, int n);

//快速排序
void quick_sort(int *, int begin, int end);
void QuickSort(int *, int n);

//显示输出数组
void display(int *arr, int n);

//随机产生1-n的整数
long random(long n);


"sort_algorithms.cpp":

#include"sort_algorithms.h"

//冒泡排序
void bubble_sort(int  *arr, int n)
{
if( NULL == arr ||n < 1)
return;
int temp;
//因为冒泡排序的效率和数组初始化的次序有关,用来判断后面的是否已经排好序,以便直接退出,提供效率
bool isOver = true;
for(int i = 0; i < n - 1; ++i)
{
isOver = true;
for(int j = 0; j < n - 1 - i; ++j)
{
if(arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isOver = false;
}
}
if(isOver)
break;
}

display(arr, n);
}

//选择排序
void choose_sort(int * arr, int n)
{
if( NULL == arr ||n < 1)
return;
int max, index, temp;
for(int i = 0; i < n; ++i)
{
max = arr[0];
index = 0;
for(int j = 0; j < n - i; ++j)
{
if(arr[j] > max)
{
index = j;
max = arr[j];
}
}
temp = arr[n - i - 1];
arr[n - i - 1] = arr[index];
arr[index] = temp;
}

display(arr, n);
}

//插入排序,与初始化次序有关
void insert_sort(int * arr, int n)
{
if( NULL == arr ||n < 1)
return;
int temp;
for(int i = 1; i < n; ++i)
{
temp = arr[i];
int j;
for(j = i - 1; j >= 0&& arr[j] > temp; --j)
{
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}
display(arr, n);
}

//希尔排序
void  shell_sort(int *arr, int n)
{
int d, i, j, temp;
for(d = n/2; d >= 1; d = d/2)
{
for(i = d; i < n; ++i)
{
temp = arr[i];
for(j = i - d; j >= 0&&arr[j] > temp; j = j - d)
{
arr[j + d] = arr[j];
}
arr[j + d] = temp;
}
}
display(arr,n);
}

//归并排序
void merge_sort(int * arr, int begin, int end, int * temp)
{
if(begin < end)
{
int mid = (begin + end )/2;
merge_sort(arr,begin,mid,temp);
merge_sort(arr,mid + 1,end,temp);
merge_array(arr,begin,mid,end,temp);
}
}

//二路归并左右有序的数组
void merge_array(int *arr,int begin, int mid, int end, int *temp)
{
int i = begin, j = mid + 1, m = mid, n = end, k = 0;
while(i <= m &&j <= n)
{
if(arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
}
}
while(i < m)
temp[k++] = arr[i++];
while(j < n)
temp[k++] = arr[j++];

for(i = 0; i < k; ++i)
arr[begin + i] = temp[i];
}

void MergeSort(int *arr, int n)
{
int *p = new int
;
if (NULL == p)
return;
merge_sort(arr, 0, n - 1, p);
display(arr,n);
delete[] p;
}

//快速排序
void quick_sort(int *arr, int begin, int end)
{
if(begin < end)
{
int i = begin, j = end;
int temp = arr[i];
while(i < j)
{
while(i < j&&arr[j--] > temp)
;
arr[i] = arr[j];

while(i < j&&arr[++i] < temp)
;
arr[j] = arr[i];
}
arr[i] = temp;
quick_sort(arr,begin,i - 1);
quick_sort(arr,i +1,end);
}

}
void QuickSort(int *arr, int n)
{
quick_sort(arr, 0, n - 1);
display(arr, n);
}

//显示输出数组
void display(int *arr, int n)
{
//for(int i = 0; i < n; ++i)
//{
//	cout<<arr[i]<<"      ";
//}
cout<<endl;
}

//随机产生1到n 的整数
long random(long n)
{
return (long)(n*rand()/(RAND_MAX+1.0)) + 1;
}


"test.cpp":

#include"sort_algorithms.h"

int main()
{
int num = 100000;
int * arr = new int[num];

for(int i = 0; i < num; ++i)
arr[i] = random(10*num);

clock_t start,end;
start=clock();
cout<<"冒泡排序:"<<endl;
bubble_sort(arr,num);
end=clock();
cout<<num<<"个数排序花了: "<<end - start<<" 毫秒"<<endl;
cout<<"======================================================"<<endl;

for(int i = 0; i < num; ++i)
arr[i] = random(10*num);

start=clock();
cout<<"选择排序:"<<endl;
choose_sort(arr,num);
end=clock();
cout<<num<<"个数排序花了: "<<end - start<<" 毫秒"<<endl;
cout<<"======================================================"<<endl;

for(int i = 0; i < num; ++i)
arr[i] = random(10*num);

start=clock();
cout<<"插入排序:"<<endl;
insert_sort(arr,num);
end=clock();
cout<<num<<"个数排序花了: "<<end - start<<" 毫秒"<<endl;
cout<<"======================================================"<<endl;

for(int i = 0; i < num; ++i)
arr[i] = random(10*num);

start=clock();
cout<<"希尔排序:"<<endl;
shell_sort(arr,num);
end=clock();
cout<<num<<"个数排序花了: "<<end - start<<" 毫秒"<<endl;
cout<<"======================================================"<<endl;

for(int i = 0; i < num; ++i)
arr[i] = random(10*num);

start=clock();
cout<<"归并排序:"<<endl;
MergeSort(arr,num);
end=clock();
cout<<num<<"个数排序花了: "<<end - start<<" 毫秒"<<endl;
cout<<"======================================================"<<endl;

for(int i = 0; i < num; ++i)
arr[i] = random(10*num);

start=clock();
cout<<"快速排序:"<<endl;
QuickSort(arr,num);
end=clock();
cout<<num<<"个数排序花了: "<<end - start<<" 毫秒"<<endl;
cout<<"======================================================"<<endl;

delete arr;
return 0;
}


以下两次运行随机产生100000个1-1000000的整数的排序结果:



下面是运行第二次的结果:



针对希尔排序、归并排序、快速排序,我还运行了一次随机产生一亿个一到十亿间的数字进行排序,其他3个排序效率太低,运行时间太长,所以注释掉了,结果如下:



从以上的结果可以看出,从时间角度看,快速排序确实是评价最优的。时间复杂度为0(n*n)在处理大量数据的排序中确实很难满足需求,时间成本太高。下面给出一个在百度百科上找到的总结性的图表:



关于堆排序和基础排序尚未给出具体实现的代码,日后有时间再行补充。

写此博客,重在与大家分享,共同学习,相互提高,如有疑问或建议,请留言。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: