<数据结构>各种排序算法的实现与总结(一)
2014-03-27 20:50
369 查看
前段时间,由于有些事情的耽误,还有就是自己有点懒,所以很久没有写博客了,今天打算给大家带来数据结构中的常见问题——排序,同时这也是面试中经常被问到的部分,因此今天决定对各种排序算法进行自我梳理一遍,以此巩固自己的基础。
排序算法常见的有:冒泡排序,选择排序,直接插入排序,希尔排序,归并排序,快速排序,堆排序,基数排序这八种排序算法,主要从时间复杂度、空间复杂度、稳定性、是否与初始的次序有关等方面来评价该排序算法的优劣。
以上四点判断,其实只要真正明白了其算法思想,按照其流程走,不难分析出其中的缘由。网上分析其思想原理的资料太多,我在此就不在赘述了。直接给出C++代码实现,以供大家参考,大家有什么建议和意见,可以直接留言或私信。
"sort_algorithms.h":
"sort_algorithms.cpp":
"test.cpp":
以下两次运行随机产生100000个1-1000000的整数的排序结果:
下面是运行第二次的结果:
针对希尔排序、归并排序、快速排序,我还运行了一次随机产生一亿个一到十亿间的数字进行排序,其他3个排序效率太低,运行时间太长,所以注释掉了,结果如下:
从以上的结果可以看出,从时间角度看,快速排序确实是评价最优的。时间复杂度为0(n*n)在处理大量数据的排序中确实很难满足需求,时间成本太高。下面给出一个在百度百科上找到的总结性的图表:
关于堆排序和基础排序尚未给出具体实现的代码,日后有时间再行补充。
写此博客,重在与大家分享,共同学习,相互提高,如有疑问或建议,请留言。
排序算法常见的有:冒泡排序,选择排序,直接插入排序,希尔排序,归并排序,快速排序,堆排序,基数排序这八种排序算法,主要从时间复杂度、空间复杂度、稳定性、是否与初始的次序有关等方面来评价该排序算法的优劣。
以上四点判断,其实只要真正明白了其算法思想,按照其流程走,不难分析出其中的缘由。网上分析其思想原理的资料太多,我在此就不在赘述了。直接给出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)在处理大量数据的排序中确实很难满足需求,时间成本太高。下面给出一个在百度百科上找到的总结性的图表:
关于堆排序和基础排序尚未给出具体实现的代码,日后有时间再行补充。
写此博客,重在与大家分享,共同学习,相互提高,如有疑问或建议,请留言。
相关文章推荐
- <数据结构>顺序列表的C语言实现
- <数据结构>二叉树的递归、非递归以及层次遍历算法C语言实现
- 排序算法终结总结<Java实现>
- <数据结构> 第二章 线性表之循环链表的代码粗实现
- <数据结构> 第一章绪论总结
- 排序算法终结总结<Java实现>
- <数据结构>单链表的C语言实现
- <数据结构>顺序栈的C语言实现
- 各种排序算法及其java程序实现 &lt;转&gt;
- 各种排序算法及其java程序实现 <转>
- <数据结构>链栈的C语言实现
- <数据结构>单链表元素按插入方法排序实现
- <数据结构>栈的应用一:括号匹配检测
- <二叉树 前中后 层序 非递归遍历 c语言实现>
- asp.net/c# 用<input type="file" />实现文件上传,multipart/form-data
- 各种排序算法的java实现及时间、空间复杂度、稳定程度总结
- <深入理解C指针>学习笔记和总结 第二章 认识C指针
- <杂谈1002>HTML作为GUI前段,Java/NDK作为业务后端开发方式总结
- <数据结构> 第三章 栈和队列 思维导图
- 各种排序算法及其实现总结