常见排序算法(归并排序-曾经的笔记)
2011-03-31 02:47
387 查看
四、归并排序
思想:将两个或两个以上的有序表组合成一个新的有序表。
两路归并的迭代算法:
1个元素的表总是有序的。所以对n个元素的待排序列,每个元素可看成1个有序子表。对子表两两合并生成 个子表,所得子表除最后一个子表长度可能为1外,其余子表长度均为2。再进行两两合并,直到生成n个元素按关键码有序的表。
【效率分析】
需要一个与表等长的辅助元素数组空间,所以空间复杂度为O(n)。
对n个元素的表,将这n个元素看作叶结点,若将两两归并生成的子表看作它们的父结点,则归并过程对应由叶向根生成一棵二叉树的过程。所以归并趟数约等于二叉树的高度-1,即log2n,每趟归并需移动记录n次,故时间复杂度为O(nlog2n)。
下面是两路归并的递归算法:(元素复制过多了,有时间再修改)
五、非比较排序
1.计数排序
思想:对每一个输入元素x,确定出小于x的元素个素。有了这一信息,就可以把x直接放到它在最终输出数组中的位置上。计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数。当k=O(n)时,计数排序的运行时间为⊙(n)。计数排序可用作基数排序的子过程。
2.基数排序
基数排序是一种借助于多关键码排序的思想,是将单关键码按基数分成“多关键码”进行排序的方法。
3.桶排序
思想:把区间[0,1)划分成n个相同大小的子区间(或称桶),然后,将n个输入数分布到各个桶中去,因为输入数均匀分布在[0,1)上,所以,一般不会有很多数落在一个桶中的情况出现。最后,需对各个桶中的数进行排序,按序输出即可。
思想:将两个或两个以上的有序表组合成一个新的有序表。
两路归并的迭代算法:
1个元素的表总是有序的。所以对n个元素的待排序列,每个元素可看成1个有序子表。对子表两两合并生成 个子表,所得子表除最后一个子表长度可能为1外,其余子表长度均为2。再进行两两合并,直到生成n个元素按关键码有序的表。
【效率分析】
需要一个与表等长的辅助元素数组空间,所以空间复杂度为O(n)。
对n个元素的表,将这n个元素看作叶结点,若将两两归并生成的子表看作它们的父结点,则归并过程对应由叶向根生成一棵二叉树的过程。所以归并趟数约等于二叉树的高度-1,即log2n,每趟归并需移动记录n次,故时间复杂度为O(nlog2n)。
template <class _It, class _ItMem, typename _Cmp> inline void Merge2(_It first, _It mid, _It last, _ItMem mem, _Cmp& cmp) { // 合并排序算法中的实现合并的子程序 _It tmp_mid = mid; while( (first<tmp_mid) && (mid<last)) { if( cmp(*first, *mid) ) { *mem++ = *first++; } else { *mem++ = *mid++; } } while (first<tmp_mid) { *mem++ = *first++; } while (mid<last) { *mem++ = *mid++; } } template <class _Ty, class _It, typename _Cmp> void MergeSort2(_It first, _It last, _Ty& tmp, _Cmp& cmp) throw() { //对 [first, last) 进行合并排序 非递归版本 _Ty* pBackup = new _Ty[last - first]; int length = last - first; bool bToMem = true; for(int len=1; len<length; len*=2) { if (bToMem) { for(int mid=len; mid+len<=length; mid+=2*len) { Merge2(first+mid-len, first+mid, first+mid+len, pBackup+mid-len, cmp); } if(mid-len<length) { Merge2(first+mid-len, first+(mid<length ? mid:length), first+length, pBackup+mid-len, cmp); } } else { for(int mid=len; mid+len<=length; mid+=2*len) { Merge2(pBackup+mid-len, pBackup+mid, pBackup+mid+len, first+mid-len, cmp); } if(mid-len<length) { Merge2(pBackup+mid-len, pBackup+(mid<length ? mid:length), pBackup+length, first+mid-len, cmp); } } bToMem = !bToMem; } if ( !bToMem ) { for (int i=0; i<length; i++) { *(first+i) = *(pBackup+i); } } }
下面是两路归并的递归算法:(元素复制过多了,有时间再修改)
template <class _Ty, class _It, typename _Cmp> inline void Merge(_It first, _It mid, _It last, _Ty* const mem, _Cmp& cmp) { // 合并排序算法中的实现合并的子程序 int iLLength = mid - first; int iRLength = last - mid; _Ty* const L = mem; _Ty* const R = mem + iLLength; for(int i=0; i<iLLength; i++) { L[i] = *(first+i); } for(int j=0; j<iRLength; j++) { R[j] = *(mid+j); } i = j = 0; for(_It k=first; k<last; k++) { if((i<iLLength) && (j<iRLength) && ( cmp(L[i], R[j])) || (j == iRLength)) { *k = L[i]; i++; } else if(j<iRLength) { *k = R[j]; j++; } } } template <class _Ty, class _It, typename _Cmp> inline void _MergeSort(_It first, _It last, _Ty* const mem, _Cmp& cmp) {//对 [first, last) 进行合并排序 不申请内存 if(first < last-1) { _It mid = first + (last-first)/2; _MergeSort(first, mid, mem, cmp); _MergeSort(mid, last, mem, cmp); Merge(first, mid, last, mem, cmp); } } template <class _Ty, class _It, typename _Cmp> void MergeSort(_It first, _It last, _Ty& tmp, _Cmp& cmp) throw() {//对 [first, last) 进行合并排序 if(first < last-1) { _It mid = first + (last-first)/2; _Ty* mem = new _Ty[last - first]; _MergeSort(first, mid, mem, cmp); _MergeSort(mid, last, mem, cmp); Merge(first, mid, last, mem, cmp); delete mem; } }
五、非比较排序
1.计数排序
思想:对每一个输入元素x,确定出小于x的元素个素。有了这一信息,就可以把x直接放到它在最终输出数组中的位置上。计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数。当k=O(n)时,计数排序的运行时间为⊙(n)。计数排序可用作基数排序的子过程。
2.基数排序
基数排序是一种借助于多关键码排序的思想,是将单关键码按基数分成“多关键码”进行排序的方法。
3.桶排序
思想:把区间[0,1)划分成n个相同大小的子区间(或称桶),然后,将n个输入数分布到各个桶中去,因为输入数均匀分布在[0,1)上,所以,一般不会有很多数落在一个桶中的情况出现。最后,需对各个桶中的数进行排序,按序输出即可。
相关文章推荐
- 常见排序算法(插入排序-曾经的笔记)
- 常见排序算法(交换排序-曾经的笔记)
- 常见排序算法(选择排序-曾经的笔记)
- 几种常见的排序算法,选择排序,冒泡排序,希尔排序,堆排序,快速排序,归并排序,基数排序的比较
- 常见的五类排序算法图解和实现(归并类:二路归并排序)
- 常见排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)
- 常见排序算法:归并排序
- 算法笔记--八个常见排序算法总结
- 算法笔记--八个常见排序算法总结
- 常见的五类排序算法图解和实现(归并类:二路归并排序)
- 知识点11:常见的排序算法–归并排序
- [算法笔记]八种常见排序算法
- 常见的三种排序算法(堆排、快排、归并排序)的比较总结
- 【常见排序算法】以最简单的方式理解归并排序
- 经典排序算法学习笔记六——归并排序
- 几种常见的排序算法(插入排序,希尔排序,归并排序和快速排序)——希尔排序
- 常见的排序算法(四)( 归并排序,计数排序 , 基数排序)
- 常见的排序算法(四)( 归并排序,计数排序 , 基数排序)
- 常见排序算法导读(9)[归并排序]
- [学习笔记]Java排序算法之归并排序