高速排序 归并排序的非递归版本号 备忘

首先,归并排序,分治。递归解决小的范围。再合并两个有序的小范围数组,便得到整个有序的数组。

这是非常适合用递归来写的。至于非递归。便是从小到大。各个击破,从而使得整个数组有序。代码例如以下:

void merge(vector<int> &A, int left, int mid, int right)
{
  int i=left,j=mid+1;
  vector<int> tmp(right-left+1,0);
  int k=0;
  while(i<=mid&&j<=right)
  {
    if(A[i] < A[j]) tmp[k++]=A[i++];
    else tmp[k++]=A[j++];
  }
  while(i<=mid)tmp[k++]=A[i++];
  while(j<=right)tmp[k++]=A[j++];
  //write to A
  for(int i=0;i<right-left+1;++i)
  {
    A[left+i]=tmp[i];
  }
}
void mergeSort(vector<int> &A)
{
    const int n=A.size();
    int step=1;
    int left=0,right,mid;
    while(step< n)
    {
      left=0;
      while(left+step<n)
      {
        mid=left+step-1;
        right=mid+step;
        if(right>=n) right=n-1;
        merge(A,left,mid,right);
        left=right+1;
      }
      step *= 2;
    }
}

对于高速排序的非递归版本号,因为高速排序的每一步都是依据一个pivot将数组分为两个部分,一部分大于pivot,一部分小于pivot,也就是每一步都确定了pivot终于在有序数组中的位置,那么这就非常自然地能够对两个部分各自使用递归就可以,对于非递归。则使用栈来实现。栈中记录的是每一个子数组的范围就可以,于是,代码为:

int partition(vector<int> &A, int left, int right)
{
  int pivot=A[right];
  int i=left;
  for(int k=left;k<right;++k)
  {
    if (A[k] < pivot) swap(A[i++],A[k]);
  }
  swap(A[i],A[right]);
  return i;
}

void quickSort(vector<int> &A)
{
    stack<pair<int,int> > s;
    const int n = A.size();
    if(n <2 ) return;
    int left=0,right=n-1;
    s.push(make_pair(left, right));
    while(!s.empty())
    {
      auto cur=s.top();s.pop();
      left=cur.first;right=cur.second;
      if(left>=right)continue;
      int mid=partition(A,left,right);
      s.push(make_pair(left, mid-1));
      s.push(make_pair(mid+1, right));
    }
}

写习惯了这两种排序的递归版本号,此处的非递归版本号确实不是那么自然而然的,可是仅仅要记住递归的版本号一定能够使用栈来模拟递归的过程,那么我们相同能够实现非递归的版本号,此文就是一份备忘吧。

时间: 2024-11-09 05:07:32

高速排序 归并排序的非递归版本号 备忘的相关文章

快速排序 归并排序的非递归版本 备忘

首先,归并排序,分治,递归解决小的范围,再合并两个有序的小范围数组,便得到整个有序的数组. 这是很适合用递归来写的,至于非递归,便是从小到大,各个击破,从而使得整个数组有序.代码如下: void merge(vector<int> &A, int left, int mid, int right) { int i=left,j=mid+1; vector<int> tmp(right-left+1,0); int k=0; while(i<=mid&&

【Java】 归并排序的非递归实现

归并排序可以采用递归方法(见:归并排序),但递归方法会消耗深度位O(longn)的栈空间,使用归并排序时,应该尽量使用非递归方法.本文实现了java版的非递归归并排序. 更多:数据结构与算法合集 思路分析 递归排序的核心是merge(int[] arr, int start, int mid, int end)函数,讲[start~mid-1]和[mid~end]部分的数据合并,递归代码是使用递归得到mid,一步步分解数组. 非递归时,我们直接定义要合并的小数组长度从1开始,在较小的长度数组都合

【书上讲解】归并排序的非递归写法

描述 [题解] 让区间的长度L为1,2,4,...2^(n-1) 然后对每个位置i开始的长度为L的区间归并有序,用归并排序的方法就好,然后i跳转到i+L 复杂度仍然是log2(n)*n级别的,注意写的时候的一些细节. 比如一定要让最后L>=n的情况进行过一次,不然无法保证整个序列是有序的 [代码] /* 归并排序非递归写法 */ #include <cstdio> const int N = 1e5; int a[N+10],b[N+10]; int n; //把a这个数组在l1..r2

预排序遍历树算法(非递归无限极分类算法)

多层数据结构估计所有的web开发者估计都不会陌生,各种软件的分类都是基于多层结构来设计的. 下面是一个典型的多层数据结构示意图: 相关创建数据语句:CREATE TABLE category(category_id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(20) NOT NULL,parent INT DEFAULT NULL); INSERT INTO categoryVALUES(1,'ELECTRONICS',NULL),(2,'TELEVI

高速排序算法

高速排序算法 作者 July  二零一一年一月四日------------------------------------------ 写之前,先说点题外话.每写一篇文章,我都会遵循下面几点原则:一.保持版面的尽量清晰,力保排版良好.二.力争所写的东西,清晰易懂,图文并茂三.尽最大可能确保所写的东西精准,有实用价值. 由于,我认为,你既然要把你的文章,发布出来,那么你就一定要为你的读者负责.不然,就不要发表出来.一切,为读者服务. ok,闲不多说.接下来,咱们立马进入本文章的主题,排序算法.众所

排序之选择排序、堆排序、归并排序、高速排序

本学习笔记内容部分来自网易云课堂浙江大学数据结构视频,及海子的博客:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html以及~大器晚成~的博客http://www.cnblogs.com/luchen927/archive/2012/02/29/2368070.html 1.选择排序 基本思想:在一个长度为N的无序数组中.在第一趟遍历N个数据,找出当中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出当中

非递归排序

转载:http://blog.csdn.net/feixiaoxing/article/details/6844826 作为一个100万的数据,如果使用普通的查找方法,那么每一个数据查找平均下来就要几十万次,那么二分法的查找呢,20多次就可以搞定.这中间的差别是非常明显的.既然排序有这么好的效果,那么这篇博客中,我们就对排序算做一个总结. 按照我个人的理解,排序可以分为两种: 一种是非递归排序,它主要按照非递归的方法对数据进行排序,也就是说主要数据的移位和循环来完成: 另外一种就是递归方法,我们

javascript实现非递归--归并排序

另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并排序,思路如下: * 至底而上的思路,二和一,四和一,最后是一半一半和整. * 循环从左到右依次执行,为了节省空间,我节省了右序列,将原数列的一部分作为右小序列,这一部分不会被覆盖. * 作者:吴伟欣 * */ function mergeSearch(arr) { var len = arr.le

归并排序-非递归应用

/** function:     合并2个有序数组,有效到大     input:     数组first pData[begin..mid]     数组second pData[mid+1..end]     output:pData[begin...end]          需要空间:o(n) **/ void merge(int *pData,int begin,int mid,int end) {     int pTemp[8]={0};     int first =begin