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

来源:互联网 发布:javascript作用域链 编辑:程序博客网 时间:2024/05/12 10:31

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

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

            以上四点判断,其实只要真正明白了其算法思想,按照其流程走,不难分析出其中的缘由。网上分析其思想原理的资料太多,我在此就不在赘述了。直接给出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[n];  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)在处理大量数据的排序中确实很难满足需求,时间成本太高。下面给出一个在百度百科上找到的总结性的图表:



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

写此博客,重在与大家分享,共同学习,相互提高,如有疑问或建议,请留言。



0 0
原创粉丝点击