归并排序-非递归应用

/** 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;
    int second =mid+1;
    int iTemp=begin;//iTemp开始位置不能每次都零开始,begin
    
    while(first<=mid && second<=end)
    {
        if(pData[first]<=pData[second])
        {
            pTemp[iTemp++]=pData[first++];
        }else
        {
              pTemp[iTemp++]=pData[second++];
        }
    }
    
    //待排序数组 还没有剩余
    while(first<=mid && second>end)
    {
          pTemp[iTemp++]=pData[first++];
    }
    
    while(second<=end && first>mid)
    {
       pTemp[iTemp++]=pData[second++]; 
    }
    
    for(int i=begin;i<=end;i++)
    {
        pData[i]=pTemp[i];
    }
   // delete []pTemp; 
    
}
/***
   function:非递归形式  
   统计i后门位置,比i小的个数,加入[0--i] 统计完毕之后,我是不计较后门是有些无需的
   前提:自己没有统计完毕千万不打乱
   1 
    如何做到间隔step访问 观察规律 
    根据step查分成n组 
    step=1
    [0,1], [2,3] ,[4,5][6,7] begin 
    
    step=2;
    [40,80] [20,60]                       begin 0 mid=1 end  3 
    
     [40,80] [20,60] ,[41,81] [21,61]    begin 4 mid=5  end 7
     step=4;
     
     组后一组 可能少于一个step的数据
    2  如何将一个step 数据排序完毕
    
    
    
**/
void merge_sort(int * pData,int length)
{
    int step=0;//step 避免全部排序,为了判断是否第一我不要和每一个人打一架
    int begin=0;//下一个拆分合并数组的开始位置 
    int mid=0;//begin-mid,mid-end 拆分需要合并的2个数组
    int end =0;//待排序结束位置
    //int temp[length]={0};//无法为temp申请空间 因为length不知道
   
    //控制归并排序次数
   for(step =1;step<length;step*=2)
   {   
       cout<<"step=="<<step<<":"<<endl;
       
      //控制一次归并排序,有多少对数字需要合并
      //<=length必须等于 不如少计算一个数组
      for(begin=0;(begin+2*step)<=length;begin=end+1)
      {   
          mid=begin+step-1;
          end=mid+step;
          if(end>length-1)//第二个序列个数不足
          {
              end=length-1;
          }
           //cout<<"begin_mid__end:"<<begin<<"__"<<mid<<"__"<<end<<endl;
           merge(pData,begin,mid,end); 
          //showData(pData,length);
      }
      showData(pData,length);
      
   }
 
}
void testgetMaxSum()
{
  
   int array[8]={0,5,-2,1,-8,7,6,-3};   
   showData(array,8);
   merge_sort(array,8);
   
   //showData(array,12);
   
}

输出结果:

  • 题目描述:
  • 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
  • 输入:
  • 每个测试案例包括两行:

    第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。

    第二行包含n个整数,每个数组均为int类型。

  • 输出:
  • 对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。
    样例输入:

    4
    7 5 6 4
    样例输出:
    5
【解题思路】

1  模拟人工计算方式 ,缺点 顺序执行

7  3

5 1

6 1

sum=3+1+1=5

缺点:N*N

2 如何上面联系起来。例如学生成绩比较 班级A和班级B,如果班级A 第一名(i) 大约班级B(i) 第一名

比较 ,就不需要和B中其他值比较了

时间: 2024-11-18 12:04:01

归并排序-非递归应用的相关文章

归并排序(非递归,Java实现)

归并排序(非递归): public class MergeSort { /** * @param arr 待排序的数组 * @param left 本次归并的左边界 * @param mid 本次归并的中间位置,也就是分界线 * @param right 本次归并的右边界 * @param <T> 泛型 * @local aux 辅助空间(Auxiliary Space) */ private static <T extends Comparable<? super T>&g

归并排序 非递归 不回写

#include<iostream>using namespace std;void Merge(int a[],int b[],int first,int mid,int last)//合并两个有序数组{ int p=first,q=mid+1; int pos=first; while(p<=mid&&q<=last) { if(a[p]<a[q]) { b[pos++]=a[p++]; } else { b[pos++]=a[q++]; } } if(p

归并排序的递归与非递归实现java

package com.edu.hpu.sort.merge; import com.edu.hpu.sort.Sort; public class MergeSort extends Sort { @Override public int[] doSort(int[] arr) { return mergeSort2(arr, 0, arr.length - 1); } @SuppressWarnings("unused") private int [] mergeSort(int

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

描述 [题解] 让区间的长度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

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

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

算法之归并排序的递归与非递归的实现

一.什么是归并排序 归并排序就是将多个有序的数据段合成一个有序的数据段,如果参与合并的只有两个有序的数据段,则称为二路归并.与快速排序和堆排序相比,其最大的特点是一种稳定的算法,算法的平均时间复杂度O(nlog2n). 二.归并排序的基本思路 (1).对于一个原始的待排序表,可以将R[1]到R[n]可以看做是n个长度为1的有序表,即分解. (2).进行第一趟归并,即将上述的n个子序两两合并,得到 n/2向上取整 个有序表,若n为奇数,则归并到最后一个子序列长度为1,即合并. (3).再将两个 n

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

首先,归并排序,分治,递归解决小的范围,再合并两个有序的小范围数组,便得到整个有序的数组. 这是很适合用递归来写的,至于非递归,便是从小到大,各个击破,从而使得整个数组有序.代码如下: 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&&

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

首先,归并排序,分治.递归解决小的范围.再合并两个有序的小范围数组,便得到整个有序的数组. 这是非常适合用递归来写的.至于非递归.便是从小到大.各个击破,从而使得整个数组有序.代码例如以下: 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&&a

归并排序(递归、非递归、以及自然归并排序)算法总结

注:本文所指归并排序指 二路归并排序. 归并排序是平均情况.最坏情况.最好情况时间复杂度都为O(Nlog2N)的稳定的排序算法.最近梳理了下归并排序的递归.非递归.以及自然归并排序算法. 归并排序的基础:将两个有序数组合并为一个有序数组,需要O(n)的辅助空间. 图片来自:https://www.cnblogs.com/chengxiao/p/6194356.html // array:待排序数组 //temparray: 临时数组 //startindex:起始下标 //middleindex