二叉树

来源:互联网 发布:tcp网络编程步骤 编辑:程序博客网 时间:2024/06/02 02:06
(1)二叉树
基本特征:
每个结点最多只有两棵子树(不存在度大于2的结点)
② 左子树和右子树次序不能颠倒。下面是两棵不同的树:
l结点的层次:根结点的层数为0,根的孩子层数为1,依此类推。
l二叉树深度:树中结点的最大层次。
l二叉树的高度:层数最大的叶结点的层数加1。
满二叉树和完全二叉树

满二叉树:棵二叉树的任何结点,或者是树叶,或者恰有两棵非空子树,这样的二叉树称为满二叉树

完全二叉树:如果一棵深度为k,有n个结点的二叉树中各结点能够与深度为k的顺序编号的满二叉树从1n标号的结点相对应的二叉树称为完全二叉树。(只有最下两层结点可以度小于2

特点:

•叶子结点只可能在层次最大的两层上出现;
•前k-1层中的结点都是“满”的,且第k 层的结点都集中在左边。
(2)二叉树的遍历
•遍历
–按一定的规律走遍二叉树的每个结点使每个结点被访问一次,且只被访问一次
遍历方式
–深度优先遍历
按根、左子树、右子树三个部分进行访问
–广度优先遍历(逐层遍历)
•从根节点开始,向下逐层访问每个节点,在每一层次上,从左到右访问每个节点。
•基于二叉树的递归定义,这三种深度优先周游的递归定义         

     (1) 前序法(tLR次序,preorder traversal)。其递归定义是

            访问根结点;

            按前序周游左子树;

            按前序周游右子树。

     (2) 中序法(LtR次序,inorder traversal)。其递归定义是

           按中序周游左子树;

           访问根结点;

           按中序周游右子树。

     (3) 后序法(LRt次序,postorder traversal)。其递归定义是

           按后序周游左子树;

           按后序周游右子树;

           访问根结点。

 

BinaryTreeNode.h

#include<iostream>using namespace std;class BinaryTreeNode  {friend class BinaryTree;private:int  element;//二叉树结点数据域BinaryTreeNode*  left;//二叉树结点指向左子树的指针BinaryTreeNode*  right;//二叉树结点指向左子树的指针public:BinaryTreeNode();BinaryTreeNode(const int & ele);//给定数据的构造函数BinaryTreeNode(const int & ele,BinaryTreeNode* l, BinaryTreeNode* r);//给定数据的左右指针的构造函数int  value() const;//返回当前结点的数据//BinaryTreeNode& operator= (const BinaryTreeNode& Node){this=Node;};//重载赋值操作符BinaryTreeNode*  leftchild() const;//返回当前结点指向左子树的指针BinaryTreeNode*  rightchild() const;//返回当前结点指向右子树的指针void  setLeftchild(BinaryTreeNode*);//设置当前结点的左子树void  setRightchild(BinaryTreeNode*);//设置当前结点的右子树void  setValue(const int & val);//设置当前结点的数据域bool  isLeaf() const;//判定当前结点是否为叶结点,若是返回true};BinaryTreeNode::BinaryTreeNode(){left=right=NULL;}BinaryTreeNode::BinaryTreeNode(const int & ele)//给定数据的构造函数{element=ele;left=right=NULL;}BinaryTreeNode::BinaryTreeNode(const int & ele,BinaryTreeNode* l, BinaryTreeNode* r)//给定数据的左右指针的构造函数{element=ele;left=l;right=r;}int  BinaryTreeNode::value() const{return element; }BinaryTreeNode*  BinaryTreeNode::leftchild() const//返回当前结点指向左子树的指针{return left;}BinaryTreeNode*  BinaryTreeNode::rightchild() const//返回当前结点指向右子树的指针{return right;}void  BinaryTreeNode::setLeftchild(BinaryTreeNode* subroot)//设置当前结点的左子树{left=subroot;}void  BinaryTreeNode::setRightchild(BinaryTreeNode* subroot)//设置当前结点的右子树{right=subroot;}void  BinaryTreeNode::setValue(const int & val)//设置当前结点的数据域{element = val; } bool  BinaryTreeNode::isLeaf() const //判定当前结点是否为叶结点,若是返回true{return (left == NULL) && (right == NULL); }



 

BinaryTree.cpp

#include<iostream>#include<stack>#include<queue>#include "BinaryTreeNode.h"using namespace std;class BinaryTree{private:BinaryTreeNode * root;                                   //二叉树根节点public:BinaryTree(){root=NULL;}                                 //构造函数~BinaryTree(){DeleteBinaryTree(root);}                   //析构函数bool isEmpty()const;                                    //判断二叉树是否为空BinaryTreeNode * Root(){return root;}                   //返回二叉树的根节点BinaryTreeNode * Parent(BinaryTreeNode * current);      //返回当前节点的父节点BinaryTreeNode * LeftSibling(BinaryTreeNode * current); //返回当前节点的左兄弟BinaryTreeNode * RightSibling(BinaryTreeNode * current);//返回当前节点的右兄弟void CreateTree(const int & info,BinaryTree &leftTree,BinaryTree & rightTree); //构造新数void PreOrder(BinaryTreeNode * root);            //递归前序周游void InOrder(BinaryTreeNode * root);              //递归中序周游                                             void PostOrder(BinaryTreeNode * root);             //递归后序周游void LevelOrder(BinaryTreeNode * root);            //广度优先周游void DeleteBinaryTree(BinaryTreeNode * root);      //删除给定的二叉树void Visit(int data){ cout<<data<<" "<<endl;};                                  void PreOrderWithoutRecursion(BinaryTreeNode * root);   //非递归前序周游void InOrderWithoutRecursion(BinaryTreeNode * root);   //非递归中序周游void PostOrderWithoutRecursion(BinaryTreeNode * root); //非递归后序周游}void BinaryTree::PreOrder(BinaryTreeNode * root){if (root!=NULL){Visit(root->value());PreOrder(root->leftchild());PreOrder(root->rightchild());}}void BinaryTree::InOrder(BinaryTreeNode * root){if (root!=NULL){InOrder(root->leftchild());Visit(root->value());InOrder(root->rightchild());}}void BinaryTree::PostOrder(BinaryTreeNode * root){if (root!=NULL){PostOrder(root->leftchild());PostOrder(root->rightchild());Visit(root->value());}}void BinaryTree::PostOrderWithoutRecursion(BinaryTreeNode * root){using std::stack;                             //使用STL中的栈stack<BinaryTreeNode * > aStack;BinaryTreeNode * pointer=root;aStack.push(NULL);                 //栈底监视哨while (pointer){Visit(pointer->value());if(pointer->rightchild()!=NULL)aStack.push(pointer->rightchild());if (pointer->leftchild()!=NULL)pointer=pointer->leftchild();else{pointer=aStack.top();            //获得栈顶元素aStack.pop();}}}void BinaryTree::InOrderWithoutRecursion(BinaryTreeNode * root){using std::stack;stack<BinaryTreeNode* > aStack;BinaryTreeNode * pointer;while (!aStack.empty() || pointer){if (pointer){aStack.push(pointer);pointer=pointer->leftchild();}else{pointer=aStack.top();aStack.pop();Visit(pointer->value());pointer=pointer->rightchild();}}}enum Tags{Left,Right};      //定义枚举类型标志位class StackElement{public:BinaryTreeNode * pointer;Tags tag;};void BinaryTree::PostOrderWithoutRecursion(BinaryTreeNode * root){using std::stack;StackElement element;stack<StackElement> aStack;BinaryTreeNode * pointer;if (root==NULL)return;elsepointer=root;while (!aStack.empty() || pointer){while (pointer!=NULL){element.pointer=pointer;element.tag=Left;               //标志位为Left表示进入左子树aStack.push(element);pointer=pointer->leftchild();}element=aStack.top();aStack.pop();pointer=element.pointer;if(element.tag==Left){                           //如果从左子树返回element.tag=Right;                         //标志位为Right表示进入右子树aStack.push(element);pointer=pointer->rightchild();}else{                                           //如果从右子树返回Visit(pointer->value());pointer=NULL;}}}void BinaryTree::LevelOrder(BinaryTreeNode * root){using std::queue;queue<BinaryTreeNode *> aQueue;BinaryTreeNode * pointer=root;if(pointer)aQueue.push(pointer);                                      //根节点入队列while (!aQueue.empty()){                                       //队列非空pointer=aQueue.front();                                    //获得列首节点aQueue.pop();                                              //列首节点出队列Visit(pointer->value());if(pointer->leftchild()!=NULL)aQueue.push(pointer->leftchild());if(pointer->rightchild()!=NULL)aQueue.push(pointer->rightchild());}}

原创粉丝点击