二叉树遍历的算法实现

作者&投稿:贾庭 (若有异议请与网页底部的电邮联系)
c语言编程实现二叉树的三种遍历算法 并针对一个二叉树列出三种遍历序列。功能要求:实现三种遍历算法、~

#include #include typedef struct BTree { char data; struct BTree *lChild; struct BTree *rChild;} BinTree;BinTree *CreateTree(BinTree *p) { char ch; scanf("%c", &ch); if (ch=='#') return NULL; p = (BinTree *)malloc(sizeof(BinTree)); p->data = ch; p->lChild = CreateTree(p->lChild); p->rChild = CreateTree(p->rChild); return p;}int SumLeaf(BinTree *T) { int sum=0, m, n; if (T) { if ((!T->lChild) && (!T->rChild)) sum++; m = SumLeaf(T->lChild); n = SumLeaf(T->rChild); sum +=m+n; } return sum;}void QianXu(BinTree *T) { if (T) { printf("%c, ", T->data); QianXu(T->lChild); QianXu(T->rChild); }}void ZhongXu(BinTree *T) { if (T) { ZhongXu(T->lChild); printf("%c,", T->data); ZhongXu(T->rChild); }}void HouXu(BinTree *T) { if (T) { HouXu(T->lChild); HouXu(T->rChild); printf("%c,", T->data); }}int Depth(BinTree *T) { int dep = 0, depl, depr; if (!T) dep = 0; else { depl = Depth(T->lChild); depr = Depth(T->rChild); dep = 1+(depl>depr?depl:depr); } return dep;}void FreeTree(BinTree *T) { if (T) { FreeTree(T->lChild); FreeTree(T->rChild); free(T); }}int main() { BinTree *Tree = NULL; Tree = CreateTree(Tree); //前序遍历 printf("QianXu Traversal:"); QianXu(Tree); printf("
ZhongXu Traversal:"); ZhongXu(Tree); printf("
HouXu Traversal:"); HouXu(Tree); printf("
Leaf's number:%d
", SumLeaf(Tree)); printf("Tree's Depth:%d", Depth(Tree)); FreeTree(Tree); return 0;}输入:#ABCD###E##FG#H##I#J##输出:

那个 答案我用了不行 啊,报错后改了运行没结果

从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
⑴访问结点本身(N),
⑵遍历该结点的左子树(L),
⑶遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
NLR、LNR、LRN、NRL、RNL、RLN。
注意:
前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。 根据访问结点操作发生位置命名:
① NLR:前序遍历(PreorderTraversal亦称(先序遍历))
——访问根结点的操作发生在遍历其左右子树之前。
② LNR:中序遍历(InorderTraversal)
——访问根结点的操作发生在遍历其左右子树之中(间)。
③ LRN:后序遍历(PostorderTraversal)
——访问根结点的操作发生在遍历其左右子树之后。
注意:
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。 1.先(根)序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴ 访问根结点;
⑵ 遍历左子树;
⑶ 遍历右子树。
2.中(根)序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵访问根结点;
⑶遍历右子树。
3.后(根)序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵遍历右子树;
⑶访问根结点。 用二叉链表做为存储结构,中序遍历算法可描述为:
void InOrder(BinTree T)
{ //算法里①~⑥是为了说明执行过程加入的标号
① if(T) { // 如果二叉树非空
② InOrder(T->lchild);
③ printf(%c,T->data); // 访问结点
④ InOrder(T->rchild);
⑤ }
⑥ } // InOrder 计算中序遍历拥有比较简单直观的投影法,如图
⑴在搜索路线中,若访问结点均是第一次经过结点时进行的,则是前序遍历;若访问结点均是在第二次(或第三次)经过结点时进行的,则是中序遍历(或后序遍历)。只要将搜索路线上所有在第一次、第二次和第三次经过的结点分别列表,即可分别得到该二叉树的前序序列、中序序列和后序序列。
⑵上述三种序列都是线性序列,有且仅有一个开始结点和一个终端结点,其余结点都有且仅有一个前驱结点和一个后继结点。为了区别于树形结构中前驱(即双亲)结点和后继(即孩子)结点的概念,对上述三种线性序列,要在某结点的前驱和后继之前冠以其遍历次序名称。
【例】上图所示的二叉树中结点C,其前序前驱结点是D,前序后继结点是E;中序前驱结点是E,中序后继结点是F;后序前驱结点是F,后序后继结点是A。但是就该树的逻辑结构而言,C的前驱结点是A,后继结点是E和F。
二叉链表基本思想
基于先序遍历的构造,即以二叉树的先序序列为输入构造。
注意:
先序序列中必须加入虚结点以示空指针的位置。
【例】
建立上图所示二叉树,其输入的先序序列是:ABD∮∮∮CE∮∮F∮∮。
构造算法
假设虚结点输入时以空格字符表示,相应的构造算法为:
void CreateBinTree (BinTree **T){ //构造二叉链表。T是指向根指针的指针,故修改*T就修改了实参(根指针)本身 char ch; if((ch=getchar())=='') *T=NULL; //读入空格,将相应指针置空 else{ //读人非空格 *T=(BinTNode *)malloc(sizeof(BinTNode)); //生成结点 (*T)->data=ch; CreateBinTree(&(*T)->lchild); //构造左子树 CreateBinTree(&(*T)->rchild); //构造右子树 }}
注意:
调用该算法时,应将待建立的二叉链表的根指针的地址作为实参。
示例
设root是一根指针(即它的类型是BinTree),则调用CreateBinTree(&root)后root就指向了已构造好的二叉链表的根结点。
二叉树建立过程见
下面是关于二叉树的遍历、查找、删除、更新数据的代码(递归算法): #include<iostream>#include<cstdio>#include<cmath>#include<iomanip>#include<cstdlib>#include<ctime>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<list>#include<stack>#include<queue>#include<map>#include<set>using namespace std;typedef int T;class bst{    struct Node    {        T data;        Node* L;        Node* R;        Node(const T& d,Node* lp=NULL,Node* rp=NULL):data(d),L(lp),R(rp) {}    };    Node* root;    int num;public:    bst():root(NULL),num(0) {}    void clear(Node* t)    {        if(t==NULL) return;        clear(t->L);        clear(t->R);        delete t;    } ~bst()    {        clear(root);    } void clear()    {        clear(root);        num = 0;        root = NULL;    } bool empty()    {        return root==NULL;    } int size()    {        return num;    } T getRoot()    {        if(empty()) throw empty tree;        return root->data;    } void travel(Node* tree)    {        if(tree==NULL) return;        travel(tree->L);        cout << tree->data << ' ';        travel(tree->R);    } void travel()    {        travel(root);        cout << endl;    } int height(Node* tree)    {        if(tree==NULL) return 0;        int lh = height(tree->L);        int rh = height(tree->R);        return 1+(lh>rh?lh:rh);    } int height()    {        return height(root);    } void insert(Node*& tree,const T& d)    {        if(tree==NULL)  tree = new Node(d);        else if(ddata)  insert(tree->L,d);        else  insert(tree->R,d);    } void insert(const T& d)    {        insert(root,d);        num++;    } Node*& find(Node*& tree,const T& d)    {        if(tree==NULL) return tree;        if(tree->data==d) return tree;        if(ddata)  return find(tree->L,d);        else  return find(tree->R,d);    } bool find(const T& d)    {        return find(root,d)!=NULL;    } bool erase(const T& d)    {        Node*& pt = find(root,d);        if(pt==NULL) return false;        combine(pt->L,pt->R);        Node* p = pt;        pt = pt->R;        delete p;        num--;        return true;    } void combine(Node* lc,Node*& rc)    {        if(lc==NULL) return;        if(rc==NULL) rc = lc;        else combine(lc,rc->L);    } bool update(const T& od,const T& nd)    {        Node* p = find(root,od);        if(p==NULL) return false;        erase(od);        insert(nd);        return true;    }};int main(){    bst b;    cout << input some integers:;    for(;;)    {        int n;        cin >> n;        b.insert(n);        if(cin.peek()=='
') break;    }for(;;)    {        cout << input data pair:;        int od,nd;        cin >> od >> nd;        if(od==-1&&nd==-1) break;  b.update(od,nd);    }}



二叉树遍历的算法实现
答:② LNR:中序遍历(InorderTraversal)——访问根结点的操作发生在遍历其左右子树之中(间)。③ LRN:后序遍历(PostorderTraversal)——访问根结点的操作发生在遍历其左右子树之后。注意:由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树...

二叉树的遍历是怎样实现的?
答:前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。若二叉树为空则结束返回。因此,A是根结点,B是A的左子树,F是A的右子树。E是B的左子树,C是B的右子树,...

二叉树的遍历
答:.中序遍历的算法实现 用二叉链表做为存储结构 中序遍历算法可描述为 void InOrder(BinTree T) { //算法里①~⑥是为了说明执行过程加入的标号 ① if(T) { // 如果二叉树非空 ② InOrder(T >lchild) ③ printf( %c T >data) // 访问结点 ④ InOrder(T >...

二叉树是怎么遍历的?
答:1、先根遍历一般是先序遍历(Pre-order),按照根左右的顺序沿一定路径经过路径上所有的结点。在二叉树中,先根后左再右。巧记:根左右。首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。例如,下图所示二...

设二叉树以二叉链表存储,试设计算法,实现二叉树的层序遍历。
答:按层次遍历算法如下:include <iostream> using namespace std;typedef struct treenode { //树结点结构 int data;struct treenode *left;struct treenode *right;}TreeNode;typedef struct stack{ //栈结点结构 TreeNode *node;struct stack *next;}STACK;void Traversal(TreeNode *root){ STACK *...

二叉树的遍历算法是怎样的?
答:所以最后访问的是树的根结点。先根遍历、中根遍历、后根遍历。先序遍历、中序遍历、后序遍历。是对同一种问题的两种说法。二叉树的先根遍历序列与其对应的二叉树的中序序列相同,仅有一种特例:即该二叉树的各结点仅有右子树,也就是一棵退化了的右偏的线性序列。

二叉树的遍历算法怎么写?
答:层次遍历EAFBHDGICKJ。后序遍历CDBAGJKIHFE。画法:根E,E左A右F,A右B,B右D。先看先序,其第一个为专树的根,属先序遍历是先根再左子树最后右子树,第一个肯定是树的根,先画A,A再中序遍历中左右都有,说明A有左子树也有右子树。

求java实现二叉树启遍历的算法
答://先根次序遍历二叉树 if(p!=null){ System.out.print(p.data+"");preorder(p.left);preorder(p.right);} } public void inorder(TreeNode1 p){ //中根次序遍历二叉树 if(p!=null){ inorder(p.left);System.out.print(p.data+"");inorder(p.right);} } public void postorder(...

二叉树的层次遍历算法
答:二叉树的层次遍历算法有如下三种方法:给定一棵二叉树,要求进行分层遍历,每层的节点值单独打印一行,下图给出事例结构:对此二叉树遍历的结果应该是:1,2 , 3 4, 5, 6 7, 8 第一种方法,就是利用递归的方法,按层进行打印,我们把根节点当做第0层,之后层次依次增加,如果我们想打印第二层...

试完成二叉树按层次(同一层自左至右)遍历的算法。
答:void CreateBiTree(BiTree &T){//按先序次序输入,构造二叉链表表示的二叉树T,空格表示空树 // if(T) return;char ch;ch=getchar(); //不能用cin来输入,在cin中不能识别空格。if(ch==' ') T=NULL;else{ if(!(T=(BTNode *)malloc(sizeof(BTNode))) cout<<"malloc fail!";T->...