归并排序 的非递归算法

算法思想:

先假设length=1; 表示先将相邻的2个元素进行排序。A[0]与A[1],A[2]与A[3].............A[N-2]与A[N-1](N为偶数 假设)

然后length=2;A[0]A[1]是有序序列,与A[2]A[3] 进行2个有序序列的归并。

依次类推。

  void Merge_Pass(ElementType A[],ElementType Temp[],int N,int length)
{ int i,j;
    for(i=0;i<N-2*length;i+=2*length)
        Merge1(A,Temp,i,i+length,i+length*2-1);
    if (i+length<N)
       Merge1(A,Temp,i,i+length,N-1);//超级错误
    else
    {
        for(j=i;j<N;j++)
            Temp[j]=A[j];
    }

}

 void Merge_Sort(ElementType A[],int N)
 {
     int length;
     ElementType *Temp;

      Temp = (ElementType *)malloc( N * sizeof( ElementType ) );

    length=1;
     if (Temp!=NULL)
     {
         while(length<N)
         {
             Merge_Pass(A,Temp,N,length);
             length=length*2;
             Merge_Pass(Temp,A,N,length);
             length=length*2;
         }
     }
     else
         printf("error\n");
 }
 void Merge1(ElementType A[],ElementType Temp[],int  Left,int Right,int RightEnd)
{
    int temp,i, LeftEnd,count;
    LeftEnd=Right-1;
    count=RightEnd-Left+1;
    temp=Left;
    while(Left<=LeftEnd&& Right<=RightEnd)
    {
        if(A[Left]<=A[Right])
            Temp[temp++]=A[Left++];
        else
            Temp[temp++]=A[Right++];
    }
    while(Left<=LeftEnd)
        Temp[temp++]=A[Left++];
    while(Right<=RightEnd)
        Temp[temp++]=A[Right++];

}

错误分析:

Merge1(A,Temp,i,i+length,N);应该有N个元素,最后一个元素的下标是N-1!!!!!!!!!!!!!
时间: 2024-10-19 15:59:29

归并排序 的非递归算法的相关文章

归并排序的非递归算法

#include<iostream>   #include<stdio.h> #include<stdlib.h> using namespace std; //智二 //交换数组中两个元素的位置 void swap(int left, int right, int sort[]){ int temp; temp = sort[left]; sort[left] = sort[right]; sort[right] = temp; } //两个已经排好序的小数组整合成较

二叉树的前序、中序、后序遍历的递归和非递归算法实现

1 /** 2 * 二叉树的前序.中序.后序遍历的递归和非递归算法实现 3 **/ 4 5 //二叉链表存储 6 struct BTNode 7 { 8 struct BTNode *LChild; // 指向左孩子指针 9 ELEMENTTYPE data; // 结点数据 10 struct BTNode *RChild; // 指向右孩子指针 11 }; 12 13 /** 14 * 前序遍历 15 **/ 16 // 递归实现 17 void PreorderTraversal(BTNo

二叉树遍历非递归算法——后序遍历

在前面先后介绍了二叉树先序遍历的非递归算法和中序遍历的非递归算法,这里则来介绍二叉树后序遍历非递归算法,二叉树后序非递归遍历真的非常之 重要,因为它具有独特的特性(文章结尾会阐述),所以,在很多与二叉树相关的复杂算法中,经常要用到二叉树后序遍历的非递归算法.并且在互联网面试笔 试也经常考察该算法,所以,我们应该对二叉树后序遍历非递归算法乱熟于心. 和二叉树先序遍历.中序遍历非递归算法一样,后序遍历非递归算法同样是使用栈来实现:从根结点开始,将所有最左结点全部压栈,每当一个结点出栈时, 都先扫描该

数据结构算法实现-二叉树遍历的非递归算法

由于递归算法使用系统堆栈,性能较差,所以应尽可能使用非递归算法. 1.先序遍历 先序遍历,即得到节点时输出数据. // 先序遍历 function PreOrder(node){ if(node!==undefined){ console.log(node.data) } var stack=[] //模仿递归的栈 stack.push(node) for(var temp=node,i=0;temp!==undefined;temp=stack[stack.length-1]){ if(tem

二叉树的三种遍历的递归与非递归算法

今天复习了一下二叉树的前序遍历.中序遍历.后序遍历的递归与非递归算法,顺便记录一下: //TreeTest.h #include <iostream> struct TreeNode { int value; TreeNode* leftChild; TreeNode* rightChild; void print() { printf("%d ",value); } }; class MyTree { private: TreeNode* m_root; TreeNode

算法学习(二) 全排列问题的非递归算法——模拟堆栈

前一段时间总结了全排列问题的几种递归解法,今天再总结一下如何通过对系统栈行为的模拟来非递归的实现全排列问题. 我们用一个数组stack[]来表示一个栈,用一个top指针来表示栈顶,用一个flags[]数组来标示每一个数字的可用性:用i来表示当前的状态. 初始状态top=0:i=-1:flags数组全为1: i递增,如果i没有越界并且flags[i]==1,那么就将i写入栈中,栈顶往前移动一位:最后把flags[i]赋值为0,i回溯到初始状态-1: 当栈顶越界,就将整个栈的信息打印出来,然后top

二叉树遍历的非递归算法

闲来无事,重看了<数据结构>一书,突然发现其中的很多代码写的很精妙,以下就是我对二叉树一部分的做的记录.一般遍历就是使用前序.中序.后序三种遍历,我自己平时都是使用递归算法,今天看书才发现递归算法不是最优解,因为函数调用栈层层叠加,还要保存函数的返回地址,实际参数传递,创建局部变量等等. 一.二叉树前序非递归算法 前序遍历的特点是:首先访问根,访问完根后再访问左子树,所以对每一个结点,在访问完该结点后,沿着左链访问下来 ,直到为左链为空,然后将所有访问过的结点进栈.然后结点出栈,每一个出栈的结

二叉树3种遍历的非递归算法

http://blog.csdn.net/pipisorry/article/details/37353037 c实现: 1.先序遍历非递归算法 #define maxsize 100 typedef struct { Bitree Elem[maxsize]; int top; } SqStack; void PreOrderUnrec(Bitree t) { SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { w

二叉树先序中序非递归算法

一直想要写的 二叉树 中序 先序 后序遍历算法 当年学习DS最虚的就是这个,因为非递归算法复杂,测试数据不好弄,只能一个一个手动插入.感觉明显比图的难,虽然大家都觉得图更难..... 递归的太简单了,就不写了.关键是非递归版本. 先序: 我自己的版本: void RootPreTraverse(Node* p) { Stack S; while(S not empty) { p=S.top(); S.pop(); Show(p); if(p->right!=null) S.push(p->ri