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()
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]
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组成的序列返回上一层;
8. 问一个关于新建一个二叉树结点的问题。
因为return之后的u和node[++cnt]指向同一块静态内存,如果你不小心把它们两个各释放一次呢?容易出现此类问题