连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)

1,起泡排序(bubble sort),大致有三种算法

  • 基本版,全扫描。
  • 提前终止版,如果发现前区里没有发生交换,就说明前区已经有序了,直接终止了。但是有个效率低下的地方,就是右边界hi是每次循环向前移动一个单元
  • 跳跃版,在提前终止版的基础上,解决右边界hi移动效率低下的问题。解决思路:每次循环后,记录下最后一次的交换位置A,然后让hi=交换位置A,所以hi就可以跳跃移动多个单元了。

基本版代码实现

//冒泡排序(基本版 效率低下)
template<typename T>
void Vector<T>::bubbleSortA(Rank lo, Rank hi){
while(lo < hi - 1){
for(int i = lo; i < hi - 1; ++i){
if(_elem[i] > _elem[i+1]){
std::swap(_elem[i], _elem[i+1]);
}
}
hi--;//头不变,不断收缩尾部
}
}

提前终止版代码实现

//冒泡排序(提前终止版 效率比基础版高)
template<typename T>
void Vector<T>::bubbleSortB(Rank lo, Rank hi){
while(!bubbleB(lo, hi--));
}
template<typename T>
bool Vector<T>::bubbleB(Rank lo, Rank hi){
bool sorted = true;//假设整体有序
for(int i = lo; i < hi - 1; ++i){
if(_elem[i] > _elem[i+1]){
sorted = false;
std::swap(_elem[i], _elem[i+1]);
}
}
return sorted;
}

跳跃版代码实现

//冒泡排序(跳跃版,跳跃移动边界hi 效率最高)
template<typename T>
void Vector<T>::bubbleSortC(Rank lo, Rank hi){
do{
hi = bubbleC(lo, hi);
}while(lo < hi);
}
template<typename T>
Rank Vector<T>::bubbleC(Rank lo, Rank hi){
Rank last = lo;
for(int i = lo; i < hi - 1; ++i){
if(_elem[i] > _elem[i+1]){
last = i + 1;
std::swap(_elem[i], _elem[i+1]);
}
}
return last;
}

2,归并排序(merge sort)

利用递归里的减而知之的策略。把数组分为两段,然后分别排序,最后合并在一起。

template <typename T> //向量归并排序
void Vector<T>::mergeSort ( Rank lo, Rank hi ) { //0 <= lo < hi <= size
if ( hi - lo < 2 ) return; //单元素区间自然有序,否则...
int mi = ( lo + hi ) / 2; //以中点为界
mergeSort ( lo, mi ); //分别排序
mergeSort ( mi, hi ); //分别排序
merge ( lo, mi, hi ); //归并
}
template <typename T> //有序向量(区间)的归并
void Vector<T>::merge ( Rank lo, Rank mi, Rank hi ){ //各自有序的子向量[lo, mi)和[mi, hi)
T* A = _elem + lo; //合并后的向量A[0, hi - lo) = _elem[lo, hi)
int lb = mi - lo; T* B = new T[lb]; //前子向量B[0, lb) = _elem[lo, mi)
for ( Rank i = 0; i < lb; i++ ) B[i] = A[i]; //复制前子向量
int lc = hi - mi; T* C = _elem + mi; //后子向量C[0, lc) = _elem[mi, hi)
for ( Rank i = 0, j = 0, k = 0; j < lb; ) //归并:反复从B和C首元素中取出更小者
A[i++] = ( lc <= k || B[j] <= C[k] ) ? B[j++] : C[k++]; //将其归入A中
delete [] B; //释放临时空间B
}

3,两种排序算法的比较

归并排序的效率高

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

连续线性空间排序 起泡排序(bubble sort),归并排序(merge sort)的更多相关文章

  1. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  2. 排序算法二:归并排序(Merge sort)

    归并排序(Merge sort)用到了分治思想,即分-治-合三步,算法平均时间复杂度是O(nlgn). (一)算法实现 private void merge_sort(int[] array, int ...

  3. 归并排序(merge sort)

    M erge sort is based on the divide-and-conquer paradigm. Its worst-case running time has a lower ord ...

  4. Insertion Sort and Merge Sort

    Insertion Sort(插入排序) 思路:for 循环遍历数组中的每一个数 用while将每次遍历到的数于左侧的数进行对比,将小的排到左边 void InsertionSort(int*A, i ...

  5. 【Sort】Merge Sort归并排序

    归并排序运行时间O(N log N),但是由于需要线性附加内存,所以很少用于主存排序. 算法核心在于以下三条语句,分治递归,分别对左半边和右半边的数组进行排序,然后把左右半边的数组一一进行比较放入数组 ...

  6. 归并排序——Merge Sort

    基本思想:参考 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法的一个非常典型的应用.首先考虑下如何将2个有序数列合并.这个非常简单,只要从比较2个数列的第一个数,谁小就先取谁,取了 ...

  7. 归并排序Merge sort(转)

    原理,把原始数组分成若干子数组,对每一个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组 举例 无序数组[6 2 4 1 5 9] 先看一下每个步骤下的状态, ...

  8. 归并排序Merge Sort

    //C语言实现 void mergeSort(int array[],int first, int last) { if (first < last)//拆分数列中元素只剩下两个的时候,不再拆分 ...

  9. Insertion Sort 与 Merge Sort的性能比较(Java)

    public static void main(String[] args) { Scanner input = new Scanner(System.in); int n = input.nextI ...

随机推荐

  1. arcgis api 4.x for js 自定义 Draw 绘制手绘面以及手绘线,只针对二维视图(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 4.x for js:esri 官网 api,里面详细的介绍 arcgis api 4.x 各个类 ...

  2. swift字符串截取实例

    截取字符串 let deviceStr = deviceInfoLabel.attributedText?.string var device  = "" if let len : ...

  3. 微信小程序——仿jqueryValidate表单验证插件WxValidate的二次封装(一)

    在做web开发时,表单验证插件我们前端用的是jqueryValidate,由于个人主要精力是在后台JAVA开发上,为了让插件与后台更好的结合和使用,通过JAVA的自定义组件将表单全部重新写了一边,同时 ...

  4. [20191119]探究ipcs命令输出.txt

    [20191119]探究ipcs命令输出.txt $ man ipcsIPCS(8)                    Linux Programmer's Manual              ...

  5. 当您解开后您从 Internet 上下载的压缩的文件时,文件的修改日期更改为您提取它的日期

    用鼠标右键单击该压缩的文件,然后单击属性. 单击常规选项卡,请单击取消阻止,然后单击确定. 从压缩文件中提取文件.

  6. 对java的几点个人浅浅的认知

    特点   简单地说,Java 具有如下特点:简单的.面向对象.平台无关.多线程.分布式.安全. 高性能.可靠的.解释型.自动垃圾回收等特点. 主要面向internet的语言 Java比其他任何一门语言 ...

  7. 如何在Markdown格式下插入动图/gif

    上传GIF动图与上传普通图片是一样的,都需要以下在markdown语法中 ![]() 的小括号内填写图片的地址.问题在于如何获取本地gif的地址呢? 核心的东西就是要把这个gif动图传上网络,这样图片 ...

  8. C++ class外的 >> 重载,输入流,重载示例。不应该定义类内的>>重载

    #include <iostream> // overloading "operator >> " outside class // >> 应该 ...

  9. php获取url中的参数

    // 获取url参数值function is_set_param($param){ $current_url = $_SERVER["QUERY_STRING"]; $arr = ...

  10. Http Header的Transfer-Encoding

    Transfer-Encoding,是一个 HTTP 头部字段,字面意思是「传输编码」.实际上,HTTP 协议中还有另外一个头部与编码有关:Content-Encoding(内容编码).Content ...