怎样实现二叉树的前序遍历的非递归算法

2024-05-19 16:23

1. 怎样实现二叉树的前序遍历的非递归算法

在前面一文,说过二叉树的递归遍历算法(二叉树先根(先序)遍历的改进),此文主要讲二叉树的非递归算法,采用栈结构
总结先根遍历得到的非递归算法思想如下:
1)入栈,主要是先头结点入栈,然后visit此结点
2)while,循环遍历当前结点,直至左孩子没有结点
3)if结点的右孩子为真,转入1)继续遍历,否则退出当前结点转入父母结点遍历转入1)
先看符合此思想的算法:

[cpp] view plain copy print?
int PreOrderTraverseNonRecursiveEx(const BiTree &T, int (*VisitNode)(TElemType data))  
{  
    if (T == NULL)  
    {  
        return -1;  
    }  
  
    BiTNode *pBiNode = T;  
    SqStack S;  
    InitStack(&S);  
    Push(&S, (SElemType)T);  
  
    while (!IsStackEmpty(S))  
    {  
        while (pBiNode)  
        {  
            VisitNode(pBiNode->data);  
            if (pBiNode != T)  
            {  
                Push(&S, (SElemType)pBiNode);  
            }             
            pBiNode = pBiNode->lchild;  
        }  
        if(pBiNode == NULL)  
        {  
            Pop(&S, (SElemType*)&pBiNode);   
        }         
        if ( pBiNode->rchild == NULL)  
        {  
            Pop(&S, (SElemType*)&pBiNode); //如果此时栈已空,就有问题  
        }  
        pBiNode = pBiNode->rchild;  
    }  
  
    return 0;  
}

怎样实现二叉树的前序遍历的非递归算法

2. python 二叉树实现思想

第一 :return 的缩进不对 ,
if self.root==None:    self.root=node    return      #如果这里不缩进,下面的语句无意义,直接返回,不会执行。while queue这个循环的作用的是从root根结点开始,向下查找第一个左(右)子结点为空的结点,将node插入这个位置,queue的作用是将查找到的非空子结点保存在queue中,然后依次向下查找这些子结点的左右子结点

3. python编写欧式二叉树的问题

所以我就遇到了一下几个问题:
1、该怎么把二叉树各个节点连起来?
2、怎么定义内部数据成员?
3、如何实例化左右孩子?

在网上也没找到比较简单比较通用的Python二叉树类实现,所以我花了点时间自己写一个。
[python] view plain copy 在CODE上查看代码片派生到我的代码片
class Tree:  
def __init__(self, val = '#', left = None, right = None):  
self.val = val  
self.left = left  
self.right = right  

#前序构建二叉树  
def FrontBuildTree(self):  
temp = input('Please Input: ')  
node = Tree(temp)  
if(temp != '#'):  
node.left = self.FrontBuildTree()  
node.right = self.FrontBuildTree()  
return node#因为没有引用也没有指针,所以就把新的节点给返回回去  

#前序遍历二叉树  
def VisitNode(self):  
print(self.val)  
if(self.val != '#'):  
self.left.VisitNode()  
self.right.VisitNode()  

if __name__ == '__main__':  
root = Tree()  
root = root.FrontBuildTree()  
root.VisitNode()

python编写欧式二叉树的问题

4. 你好,请帮忙编写递归和非递归算法,在二叉树中求位于先序序列中第K个位置的结点,用c语言写??

#include
#include
#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef struct _Tree{
    char data;
    struct _Tree *lchild, *rchild;
}Tree;

typedef struct _List{
    Tree *data;
    struct _List *next;
}List;

typedef struct _stack{
    List *top;
    int size;
}Stack;

Tree* getTop(Stack stack)
{
    if (stack.size > 0)
        return (stack.top)->data;
    return NULL;
}

int Pop(Stack *stack)
{
    if (stack->size > 0){
        List *top = stack->top;
        stack->top = top->next;
        stack->size--;
        free(top);
        return OK;
    }
    return ERROR;
}

int Push(Stack *stack, Tree *tree)
{
    List *node = (List*)malloc(sizeof(List));
    if (!node) exit(OVERFLOW);
    node->data = tree;
    node->next = stack->top;
    stack->top = node;
    stack->size++;
    return OK;
}

void init(Tree **tree)
{
     //输入一个字符作为该节点的数据,
     //如果输入空格,'_'代表节点为NULL,先序输入字符
    char data;
    *tree = NULL;
    data = getchar();
    if (data != '_'){
        *tree = (Tree*)malloc(sizeof(Tree));
        (*tree)->data = data;
        init(&(*tree)->lchild); //初始化左子树
        init(&(*tree)->rchild); //初始化右子树
    }
}


Tree* findPreKey1(Tree *tree, int K)
{
//二叉树中求位于先序序列中第K个位置的结点
//如果函数返回的结果为NULL, 则说明不存在
//递归版本
    Tree* _findPreKey1(Tree *tree, int *p);
    int p[1] = {K};
    Tree *node;    
    node = _findPreKey1(tree, p);
    return node;
}

Tree* _findPreKey1(Tree *tree, int *p)
{
    Tree *node;
    if (tree != NULL){
        if (*p == 1)  //当*p == 1时,则这个节点就是需要查找的节点
            return tree;
    else{
        if (tree->lchild != NULL){
            //如果tree的左子树不为NULL,结果即为左子树的先序序列的第*p-1个元素
            (*p)--;
            node = _findPreKey1(tree->lchild, p);
        }
        if (*p == 1) //在左子树中找到第K个元素,返回结果
            return node;
        //当在左子树已经遍历完,此时有*p != 1,即还没遍历到第K个元素
        if (tree->rchild != NULL){
        //如果右子树不为NULL,此时已经遍历了K-*p + 1个元素,那么结果即为右子树的先序
        //序列的第*p-1个元素
            (*p)--;
            node = _findPreKey1(tree->rchild, p);
        }
        return node;
        }
    }
    return NULL;
}

Tree* findPreKey2(Tree *tree, int K)
{
//二叉树中求位于先序序列中第K个位置的结点
//如果函数返回的结果为NULL, 则说明不存在
//非递归版本
    Stack s = {top:NULL, size:0};
    List *top;
    Tree *node;
    f(tree == NULL)
        return NULL;
    else{
        Push(&s, tree);
        while(K != 1 && s.size > 0){
            node = getTop(s);
            Pop(&s);
            if (node->rchild)
                Push(&s, node->rchild);
             if (node->lchild)
                Push(&s, node->lchild);
            K--;
        }
        if (K == 1) 
            return getTop(s);
        else 
            return NULL;
    }
}

int main()
{
    Tree *tree, *node1, *node2;
    int K;
    printf("按先序建立二叉树,'_'(下画线)代表节点为NULL:\n");
    init(&tree);
    printf("请输入先序序列中的第K个位置(注意不要超过树的节点数):\n");
    scanf("%d", &K);
    node1 = findPreKey1(tree, K);
    if (node1 != NULL)
        printf("(递归版本)先序序列中的第%d个位置元素的值为:%c\n", K,node1->data);
    else
        printf("(递归版本)先序序列中不存在第%d个位置元素\n", K);
    node2 = findPreKey2(tree, K);
    if (node2 != NULL)
        printf("(非递归版本)先序序列中的第%d个位置元素的值为:%c\n", K,node2->data);
    else
        printf("(非递归版本)先序序列中不存在第%d个位置元素\n", K);
    return 0;

}


测试结果:
按先序建立二叉树,'_'(下画线)代表节点为NULL:
ABC__DE_G__F___
请输入先序序列中的第K个位置(注意不要超过树的节点数):
6
(递归版本)先序序列中的第6个位置元素的值为:G
(非递归版本)先序序列中的第6个位置元素的值为:G


虽然代码显得有点冗余,不过还望楼主采纳!!

5. 关于python中一个递归二叉树遍历的问题

if subsetWork+s[WORK]>maxWork:中,
s[WORK]是否应该改为s[WORK][2]

关于python中一个递归二叉树遍历的问题

6. 递归做二叉树的宽度

def permute(str,prefix):
    if len(str) == 0:
        print prefix,
        return 
    permute(str[1:],prefix) 
    permute(str[1:],prefix+str[0])

permute('123','')


这是解答的结果,和上面二叉树来表示完全一致

 3 2 23 1 13 12 123


由于用Python的人并不是很多,所以我也用C写了个程序作为参考

#include 
#include 

#define BUFFER_SIZE 255

using namespace std;

void permute(char *src, char *prefix)
{
    char buf[BUFFER_SIZE];
    int len = strlen(prefix);

    if (strlen(src) == 0)
    {
        cout<<prefix<<" ";
        return;
    }
    strcpy(buf,prefix);
    permute(src+1, prefix);
    prefix[len] = *src;
    prefix[len+1] = '\0';
    permute(src+1, prefix);
}

int main(int argc,char argv)
{
    char buf[BUFFER_SIZE] = "";
    permute("12345",buf);
    return 0;
}


 

相比之下,这个程序看起来要复杂得多,远不入Python那么简洁,这就是Python的魅力所在.

另外stone.zh也提供了一个简洁的方法,不过我现在也没有看懂,因为我不知道yield到底是什么做什么用的,不知道有没有知道,顺便告诉一下,谢过了先. 

def permute(str):
    for i in str:
        yield i;
        for j in permute(str[str.index(i)+1:]):
            yield i+j

for i in permute("12345"):
    print i,

7. Python编程求解二叉树中和为某一值的路径代

1、如果只有根节点或者找到叶子节点,我们就把其对应的val值返回
2、如果不是叶子节点,我们分别对根节点的左子树、右子树进行递归,直到找到叶子结点。然后遍历把叶子结点和父节点对应的val组成的序列返回上一层;

Python编程求解二叉树中和为某一值的路径代

8. 问一个关于新建一个二叉树结点的问题。

因为return之后的u和node[++cnt]指向同一块静态内存,如果你不小心把它们两个各释放一次呢?容易出现此类问题