标签:style blog http color io os ar for art
二叉树是每个节点最多有两个子树的有序树。二叉树常被用于实现二叉查找树和二叉堆。值得注意的是,二叉树不是树的特殊情形。在图论中,二叉树是一个连通的无环图,并且每一个顶点的度不大于2。有根二叉树还要满足根结点的度不大于2。有了根结点后,每个顶点定义了唯一的根结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。二叉树详细请看本文:二叉树
所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。
代码如下:
#include<iostream> #include<cstdlib> using namespace std; typedef char ElemType; typedef struct Node { ElemType data; struct Node* LChild; struct Node* RChild; }BiTNode,*BiTree; int LeafCount; int Depth; void Visit(ElemType T)//用于遍历的输出 { cout<<T; } //1.建立二叉树 void CreateBiTree(BiTree *bt) { char ch; ch = getchar(); if(ch=='.') *bt=NULL; else { *bt=(BiTree)malloc(sizeof(BiTNode)); //生成一个新结点 (*bt)->data=ch; CreateBiTree(&((*bt)->LChild)); //生成左子树 CreateBiTree(&((*bt)->RChild)); //生成右子树 } } //2.二叉树遍历 void PreOrder(BiTree root) /*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ { if (root!=NULL) { Visit(root ->data); /*访问根结点*/ PreOrder(root ->LChild); /*先序遍历左子树*/ PreOrder(root ->RChild); /*先序遍历右子树*/ } else cout<<"."; } void InOrder(BiTree root) /*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ { if (root!=NULL) { InOrder(root ->LChild); /*中序遍历左子树*/ Visit(root ->data); /*访问根结点*/ InOrder(root ->RChild); /*中序遍历右子树*/ } else cout<<"."; } void PostOrder(BiTree root) /* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/ { if(root!=NULL) { PostOrder(root ->LChild); /*后序遍历左子树*/ PostOrder(root ->RChild); /*后序遍历右子树*/ Visit(root ->data); /*访问根结点*/ } else cout<<"."; } //3.输出二叉树上的“叶子”节点(三种方法,只写了先序,中后请参考前面的2.二叉树遍历) void leafPreOrder(BiTree root) /*先序遍历二叉树, root为指向二叉树根结点的指针*/ { if (root!=NULL) { if (root ->LChild==NULL && root ->RChild==NULL) Visit(root->data); /*输出叶子结点*/ PreOrder(root ->LChild); /*先序遍历左子树*/ PreOrder(root ->RChild); /*先序遍历右子树*/ } } //4.统计叶子节点数目(两个方法) /* LeafCount保存叶子结点的数目的全局变量,调用之前初始化值为0 */ void leaf_a(BiTree root)//统计叶子节点数目法1 { if(root!=NULL) { leaf_a(root->LChild); leaf_a(root->RChild); if (root ->LChild==NULL && root ->RChild==NULL) LeafCount++; } } int leaf_b(BiTree root)//统计叶子节点数目法2 { int LeafCount2; if(root==NULL) LeafCount2 =0; else if((root->LChild==NULL)&&(root->RChild==NULL)) LeafCount2 =1; else LeafCount2 =leaf_b(root->LChild)+leaf_b(root->RChild); /* 叶子数为左右子树的叶子数目之和 */ return LeafCount2; } //6.后序遍历求二叉树的高度递归算法 int PostTreeDepth(BiTree bt) { int hl,hr,max; if(bt!=NULL) { hl=PostTreeDepth(bt->LChild); /* 求左子树的深度 */ hr=PostTreeDepth(bt->RChild); /* 求右子树的深度 */ max=hl>hr?hl:hr; /* 得到左、右子树深度较大者*/ return(max+1); /* 返回树的深度 */ } else return(0); /* 如果是空树,则返回0 */ } //6.前序遍历求二叉树的高度递归算法 void PreTreeDepth(BiTree bt, int h) /* 前序遍历求二叉树bt高度的递归算法,h为bt指向结点所在层次,初值为1*/ /*depth为当前求得的最大层次,为全局变量,调用前初值为0 */ { if(bt!=NULL) { if(h>Depth) Depth = h; /*如果该结点层次值大于depth,更新depth的值*/ PreTreeDepth(bt->LChild, h+1); /* 遍历左子树 */ PreTreeDepth(bt->RChild, h+1); /* 遍历右子树 */ } } //7.“竖向”打印二叉树 void PrintTree(BiTree bt,int nLayer) /* 按竖向树状打印的二叉树 */ { if(bt == NULL) return; PrintTree(bt->RChild,nLayer+1); for(int i=0;i<nLayer;i++) printf(" "); printf("%c\n",bt->data); PrintTree(bt->LChild,nLayer+1); } int main() { LeafCount =0;Depth=0; BiTree T=NULL; cout<<"请以先序输出的形式输入二叉树构造二叉链表:"<<endl; CreateBiTree(&T); cout<<"先序遍历二叉树为:"<<endl; PreOrder(T); cout<<endl<<"中序遍历二叉树为:"<<endl; InOrder(T); cout<<endl<<"后序遍历二叉树为:"<<endl; PostOrder(T); cout<<endl<<"先序输出二叉树叶子节点为:"<<endl; leafPreOrder(T); cout<<endl<<"叶子节点数目为:"<<endl; leaf_a(T); cout<<endl<<"方法一显示共有"<<LeafCount<<"个叶子节点"<<endl; cout<<endl<<"方法二显示共有"<<leaf_b(T)<<"个叶子节点"<<endl; cout<<endl<<"后序遍历求二叉树的高度为"<<PostTreeDepth(T)<<endl; PreTreeDepth(T,1); cout<<endl<<"前序遍历求二叉树的高度为"<<Depth<<endl; cout<<endl<<"竖状打印二叉树为:"<<endl; PrintTree(T,1); return 0; }
/* 中后非递归遍历二叉树,作为遍历方法的参考*/ //8.中序遍历二叉树非递归算法(三个) /*算法a*/ void inorder(BiTree root); { int top=0; p=bt; L1: if (p!=NULL) /* 遍历左子树 */ { top=top+2; if(top>m) return; /*栈满溢出处理*/ s[top-1]=p; /* 本层参数进栈 */ s[top]=L2; /* 返回地址进栈 */ p=p->LChild; /* 给下层参数赋值 */ goto L1; /* 转向开始 */ L2: Visit(p->data); /* 访问根 */ top=top+2; if(top>m) return; /*栈满溢出处理*/; s[top-1]=p; /* 遍历右子树 */ s[top]=L3; p=p->RChild; goto L1; } L3: if(top!=0) { addr=s[top]; p=s[top-1]; /* 取出返回地址 */ top=top-2; /* 退出本层参数 */ goto addr; } } /*算法b*/ void inorder(BiTree root) /* 中序遍历二叉树,root为二叉树的根结点 */ { int top=0; BiTree p; BiTree s[Stack_Size]; int m; m = Stack_Size-1; p = root; do { while(p!=NULL) { if (top>m) return; top=top+1; s[top]=p; p=p->LChild; }; /* 遍历左子树 */ if(top!=0) { p=s[top]; top=top-1; Visit(p->data); /* 访问根结点 */ p=p->RChild; /* 遍历右子树 */ } } while(p!=NULL || top!=0); } /*算法c*/ void InOrder(BiTree root) /* 中序遍历二叉树的非递归算法 */ { SeqStack S; BiTree p; InitStack (&S); p=root; while(p!=NULL || !IsEmpty(&S)) { if (p!=NULL) /* 根指针进栈,遍历左子树 */ { Push(&S,p); p=p->LChild; } else { /*根指针退栈,访问根结点,遍历右子树*/ Pop(&S,&p); Visit(p->data); p=p->RChild; } } } //9.后序遍历二叉树的非递归算法 void PostOrder(BiTree root) { BiTNode *p,*q; BiTNode **s; int top=0; q=NULL; p=root; s=(BiTNode**)malloc(sizeof(BiTNode*)*NUM); /* NUM为预定义的常数 */ while(p!=NULL || top!=0) { while(p!=NULL) { top++; s[top]=p; p=p->LChild; } /*遍历左子树*/ if(top>0) { p=s[top]; if((p->RChild==NULL) ||(p->RChild==q)) /* 无右孩子,或右孩子已遍历过 */ { visit(p->data); /* 访问根结点*/ q=p; /* 保存到q,为下一次已处理结点前驱 */ top--; p=NULL; } else p=p->RChild; } } free(s); }
标签:style blog http color io os ar for art
原文地址:http://blog.csdn.net/u014492609/article/details/39402323