数据量极大时用什么排序方法比较好
2013-04-13 17:52
211 查看
参考:点击打开链接
点击打开链接
点击打开链接
最近有一个88047579个double型数据的排序,采用的快速排序,但总是时不时的出问题:
以及
后来影响到数据量没那么大,本来可以正确执行的,也连带着出现这个错误。
在帖子点击打开链接中,说是堆栈溢出错误,要检查是否有死循环,以及提到可以修改堆栈大小,用动态数组。我都尝试了,但依然没有解决。
偶然间今天看到有人说是因为快速排序法递归调用次数太多,也会出现该问题。因此想到应该换一种适合极大数据量的排序方法。
点击打开链接上很多人对排序方法进行了比较。现总结一下。
1.在帖子点击打开链接中,有人提到:
当N很小时,快速排序慢,归并排序快
当N很大时,并且有序程度高时,快速排序最快
当N很大时,并且有序程序低时,堆排序最快
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
若要求排序稳定,则可选用归并排序。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定的,所以改进后的归并排序仍是稳定的。
但是:由于快速排序不稳定,因此数据量极大时不如选用堆排序。
2.在帖子点击打开链接中,大多数人的结论都是堆排序比较好。
堆排序占花费是时间主要是在建堆的时候。所以在数据量方面来说,如果数据量越大,堆排序的优势就越明显。
大多数商用软件都采用快排,因为它在一般情况下是排序最快的算法。
然而,快排绝不能用于需要特定响应时间的系统,除非这个系统能承受O(n^2)的时间复杂度。
如果你预先估计可能会碰到这种最坏情况,那么
如果n比较小,改用插入排序——由于代码简单,它的时间复杂度的常数项比较少
如果n比较大,改用堆排序——你应该用堆排序,因为它能保证O(nlogn)的时间复杂度.
//堆排序
//测试堆排序
3.同时也指明了快速排序递归调用次数太多时会出现栈溢出,并给出了非递归版的快速排序法。
//快速排序
//测试快速排序
//递归调用次数太多 栈溢出!
//非递归版 --迭代
点击打开链接
点击打开链接
最近有一个88047579个double型数据的排序,采用的快速排序,但总是时不时的出问题:
Unhandled exception in XX.exe: 0xc00000FD; Stack Overflow
以及
Unhandled exception in XX.exe: 0xc00000FD; access violation
后来影响到数据量没那么大,本来可以正确执行的,也连带着出现这个错误。在帖子点击打开链接中,说是堆栈溢出错误,要检查是否有死循环,以及提到可以修改堆栈大小,用动态数组。我都尝试了,但依然没有解决。
偶然间今天看到有人说是因为快速排序法递归调用次数太多,也会出现该问题。因此想到应该换一种适合极大数据量的排序方法。
点击打开链接上很多人对排序方法进行了比较。现总结一下。
1.在帖子点击打开链接中,有人提到:
当N很小时,快速排序慢,归并排序快
当N很大时,并且有序程度高时,快速排序最快
当N很大时,并且有序程序低时,堆排序最快
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
若要求排序稳定,则可选用归并排序。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定的,所以改进后的归并排序仍是稳定的。
但是:由于快速排序不稳定,因此数据量极大时不如选用堆排序。
2.在帖子点击打开链接中,大多数人的结论都是堆排序比较好。
堆排序占花费是时间主要是在建堆的时候。所以在数据量方面来说,如果数据量越大,堆排序的优势就越明显。
大多数商用软件都采用快排,因为它在一般情况下是排序最快的算法。
然而,快排绝不能用于需要特定响应时间的系统,除非这个系统能承受O(n^2)的时间复杂度。
如果你预先估计可能会碰到这种最坏情况,那么
如果n比较小,改用插入排序——由于代码简单,它的时间复杂度的常数项比较少
如果n比较大,改用堆排序——你应该用堆排序,因为它能保证O(nlogn)的时间复杂度.
//堆排序
void BuildMaxHeap(int *,int ); void MaxHeapify(int *,int,int); void heap_sort(int *,int ,int );
void swap(int *a, int m,int n) { int temp=a[m]; a[m]=a ; a =temp; }
//测试堆排序
for( i=0; i<size; i++) { array0[i]=array_b[i]; } i=heap_sort(array0,0,size-1); cout<<"Heap Sort Running Time:"<<i<<endl; fout<<"Heap Sort Running Time:"<<i<<endl;
void heap_sort(int *a,int start,int end) { int i; int length=end-start; int hsize=length; BuildMaxHeap(a,hsize); for( i=length; i>1; i--) { swap(a,1,i); hsize--; MaxHeapify(a,1,hsize); } }
void BuildMaxHeap(int *a,int size) { int i; for( i=size/2; i>0; i--) { MaxHeapify(a,i,size); } }
void MaxHeapify(int *a,int i,int size) { int l,r,largest; l=2*i; r=2*i+1; if(l<=size &&a[l]>a[i]) largest=l; else largest=i; if(r<=size && a[r]>a[largest]) largest=r; if(largest!= i) { swap(a,i,largest); MaxHeapify(a,largest,size); } }
3.同时也指明了快速排序递归调用次数太多时会出现栈溢出,并给出了非递归版的快速排序法。
//快速排序
int partition(int *, int ,int ); void quick_sort(int *, int ,int); void quick_sort_rec(int *, int ,int);
//测试快速排序
for( i=0; i<size; i++) { array0[i]=array_b[i]; } i=run_sort(quick_sort_rec,array0,0,size-1); cout<<"Quick Sort Running Time:"<<i<<endl; fout<<"Quick Sort Running Time:"<<i<<endl;
int partition(int *a,int low,int high) { int i,j; int key=a[high]; i=low-1; j=low; for( ; j<high; j++) { if(a[j]<=key) { i++; swap(a,i,j); } } swap(a,i+1,high); return i+1; }
//递归调用次数太多 栈溢出!
void quick_sort_rec(int *a,int low,int high) { int mid; if(low<high) { mid=partition(a,low,high); quick_sort_rec(a,low,mid-1); quick_sort_rec(a,mid+1,high); } }
//非递归版 --迭代
void quick_sort(int *base,int start,int end) { const int stacksize=1000; int *stack=new int[stacksize]; int top=0; stack[top++]=start; stack[top++]=end-start+1; while(top!=0) { //cout<<top<<endl; top--; int r=stack[top]; top--; int p=stack[top]; if(p>=r) continue; int m=partition(base,p,r); //push the left stack[top++]=p; stack[top++]=m-1; //push the right stack[top++]=m+1; stack[top++]=r; } }
相关文章推荐
- 在oracle里面,如果有100条记录,排序后取出 第 10 行 到 第 20 行,用什么方法比较好?
- NSArray中数据排序方法
- 数据排序的几种方法(c语言实现)
- 电脑上的回收站误清空文件的数据用什么方法才能恢复
- 使用Collections.sort()方法扩展list集合中的数据并对其进行排序
- mysql的中文数据按拼音排序的2个方法
- Android中对ListView、RecycleView里面的数据进行排序方法总结
- 用 Python 排序数据的多种方法
- C#对DataTable里数据排序的方法
- json格式数据的添加,删除及排序方法
- 对一个二维数组中的数据排序,方法如下: 将整个数组中值最小的元素所在行调整为数组第一行, 将除第一行外的行中最小元素所在行调整为第2行, 将除第1,2行外的行中最小值元素所在行调整为第3行,以此类推
- Java:集合,对列表(List)中的数据(整型、字符串、日期等)进行排序(正序、倒序)的方法;字符串按照整型排序的方法
- java编程实现对10个整型数据元素输出最小的两个数,java自带的Arrays.sort排序方法,小--->大
- JS学习笔记(3)--json格式数据的添加,删除及排序方法
- Java实现数据排序(冒泡、选择、插入、快速排序)---方法持续更新中
- JavaScript实现下拉列表框数据增加、删除、上下排序的方法
- 实体对象数据根据百度地图地理位置排序解决方法
- 大数据排序、查找方法
- 怎么恢复移动硬盘中毒了数据呢丨用什么方法恢复比较方便准确呢丨
- hibernate批量数据插入优化 ------用Hibernate插入1万条数据,怎么做,有什么好的优化方法吗