标签:
二叉树定义:
1.有且仅有一个特定的称之为根root的结点
2.当n>1时,除根结点之外的其余结点分为两个互不相交的子集。他们称为二叉树的左子树和右子树。
二叉树的一种建立方法:
若对有n个结点的完全二叉树进行顺序编号(1<=i<=n),那么,对于编号为i(i>=1)的结点。
当i=1时,该结点为根,它无双亲结点;
当i>1时,该节点的双亲编号为[i/2];
若2i<=n,该结点为编号为2i的左孩子,否则没有左孩子
当2i+1<=n,该结点有编号为2i+1的右孩子,否则没有右孩子
利用上个性质,对任意二叉树,先按满二叉树对其所有结点进行编号。
注意:由于此树并非完全树,所以结点的编号并不连续。
遍历二叉树:
遍历二叉树是指以一定的次序访问二叉树中的每个结点,并且每个结点仅被访问一次,访问结点是指进行各种操作的简称。3种遍历次序:中根遍历二叉树、先根遍历二叉树、后根遍历二叉树。
递归算法:
先根遍历:如果根不为空,1.访问根结点2.按先根次序遍历左子树,3.按先根次序遍历右子树,否则返回。
中根遍历:如果根不为空,1.按中根次序遍历左子树,2.访问根结点,3.按中根次序遍历右子树,否则返回。
后根遍历:如果根不为空,1.按后根次序遍历左子树,2.按后根次序遍历右子树,3.访问根结点,否则返回。
中根遍历非递归算法:
需要人为设置一个栈来存放所经过的根结点的指针(栈我图简单,直接调用STL标准库的),第一次遇到根结点并不访问,而是如栈,然后中根遍历左子树。左子树遍历结束后,第二次遇到根结点,退栈并访问该结点。然后遍历右子树。
先根遍历非递归算法:同中根遍历非递归算法,只是把输出位置提前
后根遍历非递归算法:
后根遍历在搜索线第一次经过根结点时不访问进行如栈,在遍历左子树之后,搜索线第二次经过根结点时也不能访问,继续遍历右子树,直到搜索线第三次经过根结点时,退栈并且访问根结点。因此,另设一个辅助栈用来记录经过某个结点的次数。
废话少说,上代码......
BinaryTree.h
#ifndef BINARYTREE_H_ #define BINARYTREE_H_ typedef int T; struct Node { T data; Node *lch; Node *rch; }; class BinaryTree { protected: Node *root; public: BinaryTree(); ~BinaryTree(); void Create(); void preorder(); void Preorder() { Preorder(root); } void inorder(); void Inorder() { Inorder(root); } void postorder(); void Postorder() { Postorder(root); } private: void Inorder(Node *p); void Preorder(Node *p); void Postorder(Node *p); void Destroy(Node *p); }; #endifBinaryTree.cpp
#include "BinaryTree.h" #include <iostream> #include <stack> using namespace std; BinaryTree::BinaryTree() { root=NULL; } BinaryTree::~BinaryTree() { Destroy(root); root=NULL; } void BinaryTree::Inorder(Node *p) { if(p!=NULL) { Inorder(p->lch); cout<<p->data<<" "; Inorder(p->rch); } } //非递归法实现中根遍历 void BinaryTree::inorder() { Node *p=root; Node *q; stack<Node *> S; do { while(p!=NULL) { S.push(p); p=p->lch; } p=S.top(); S.pop(); cout<<p->data<<" "; p=p->rch; }while(!(S.empty() && p==NULL)); } //先根遍历,用递归法 void BinaryTree::Preorder(Node *p) { if(p!=NULL) { cout<<p->data<<" "; Preorder(p->lch); Preorder(p->rch); } } //先根遍历的非递归算法 void BinaryTree::preorder() { Node *p=root; stack<Node *> S; do { while(p!=NULL) { S.push(p); cout<<p->data<<" "; p=p->lch; } p=S.top(); p=p->rch; S.pop(); }while(!(S.empty() && p==NULL)); } //后根 void BinaryTree::Postorder(Node *p) { if(p!=NULL) { Postorder(p->lch); Postorder(p->rch); cout<<p->data<<" "; } } //非递归法实现后根遍历 void BinaryTree::postorder() { stack<Node *>S; stack<int> s; Node *p=root; int t=0; do { while(p!=NULL) { s.push(1); S.push(p); p=p->lch; } t=s.top(); if(t==2) { p=S.top(); S.pop(); s.pop(); cout<<p->data<<" "; p=NULL; } if(!s.empty()) { t=s.top(); } if(t==1) { p=S.top(); p=p->rch; s.pop(); s.push(2); } }while(!(S.empty() && p==NULL)); } void BinaryTree::Destroy(Node *p) { if(p!=NULL) { Destroy(p->lch); Destroy(p->rch); delete p; } } void BinaryTree::Create() { Node *q, *s[20]; T x; int i,j; cout<<"请按照二叉树的层序,自上而下自左至右的顺序组织数据"<<endl; cout<<"每次输入结点的序号和数据,假设根结点值为11;"<<endl; cout<<"那么输入应是:1 11,若两者都输入0,则输入结束。"<<endl; root=NULL; cout<<"i,x = "; cin>>i>>x; while((i!=0)&&(x!=0)) { q=new Node; q->data=x; q->lch=NULL; q->rch=NULL; s[i]=q; if(i==1) { root=q; } else { j=i/2; if(i%2==0) { s[j]->lch=s[i]; } else { s[j]->rch=s[i]; } } cout<<"i,x = "; cin>>i>>x; } cout<<"二叉树建立完毕!"<<endl; }main.cpp
//直接调用STL库中的栈吧,不在 #include "BinaryTree.h" #include <iostream> using namespace std; int main() { /*cout<<"hello,world"<<endl;*/ BinaryTree BT; BT.Create(); cout<<"先根遍历二叉树:"<<endl; BT.Preorder(); cout<<endl<<"先根非递归遍历二叉树:"<<endl; BT.preorder(); cout<<endl<<"中根遍历二叉树:"<<endl; BT.Inorder(); cout<<endl<<"中根非递归遍历二叉树:"<<endl; BT.inorder(); cout<<endl<<"后根遍历二叉树:"<<endl; BT.Postorder(); cout<<endl<<"后根非递归遍历二叉树:"<<endl; BT.postorder(); cout<<endl; system("pause"); return 0; }结果:
标签:
原文地址:http://blog.csdn.net/jiang111_111shan/article/details/46418273