C++实现二叉树的存储与遍历

#pragma once
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
template<class T>
//定义二叉树的节点结构体
struct BinaryTreeNode
{
BinaryTreeNode <T>* _left;
BinaryTreeNode <T>* _right;
T _data;
//二叉树节点的构造函数,若去掉引用会构成死循环
BinaryTreeNode(T &data)
:_left(NULL)
,_right(NULL)
,_data(data)
{}
};
 
template<class T>
class BinaryTree
{
private:
typedef BinaryTreeNode<T> Node;
Node* _root;
 
public:
//无参的构造函数
BinaryTree()
:_root(NULL)
{}
//带参的构造函数
BinaryTree( T* a,size_t size,size_t index, const T& Invalid)
{
_root=_CreateBinaryTree(a,size,index,Invalid);
}
 
//创造二叉树
Node* _CreateBinaryTree( T* a,size_t size,size_t &index,const T& Invalid)
{
Node* root=NULL;
   if(a[index]!=Invalid&&index<size)
   {
root=new Node(a[index]);
root->_left=_CreateBinaryTree(a, size,++index,Invalid);
root->_right=_CreateBinaryTree(a, size,++index,Invalid);
   }
   return root;
}
//递归先序遍历二叉树
void PrevOrder( )
{
_PrevOrder(_root);
}
//
void _PrevOrder(Node* root)
{
if(root==NULL)
return;
cout<<root->_data<<" ";
_PrevOrder(root->_left );
_PrevOrder(root->_right);
}
//非递归先序遍历
void PrevOrder_NonR()
{
 stack<Node*> s;
 Node* cur=_root;
 while(cur||!s.empty())
 {
   if(cur)
   {//先将左子树遍历输出后压栈
     cout<<cur->_data <<" ";
 s.push(cur);
 cur=cur->_left;
   }
   else
   {//当左子树为空时开始访问右子树
    cur=s.top ();
s.pop();
cur=cur->_right;
   }
 }
}
 
 
//递归中序遍历二叉树
void InOrder()
{
_InOrder(_root);
}
//
void _InOrder(Node* root)
{
  if(root==NULL)
  return;
  _InOrder(root->_left );
  cout<<root->_data <<" ";
   _InOrder(root->_right );
}
//非递归中序遍历
void InOrder_NonR()
{
  Node* cur=_root;
  stack<Node*> s;
  while(cur||!s.empty())//cur非空或者栈非空
  {
if(cur)
{
  s.push(cur);//根节点进栈遍历左子书树
  cur=cur->_left;
}
else
{
  Node* top=s.top();
  cout<<top->_data<<" ";
  s.pop();
  cur=top->_right;
}
  }
  cout<<endl;
}
 
//递归后续遍历
void PostOrder()
{
_PostOrder(_root);
}
 
void _PostOrder(Node* root)
{
  if(root!=NULL)
  {
  _PostOrder(root->_left);
  _PostOrder(root->_right);
  cout<<root->_data<<" ";
  }
}
 
//非递归后序遍历
void PostOrder_NonR()
{
  stack<Node*> s;
  Node* cur=_root;
  Node* prev=NULL;//设置标志域
  s.push(_root);
  while(!s.empty())
  {
cur=s.top();
//
if((cur->_left ==NULL&&cur->_right ==NULL)
||(prev!=NULL&&(prev==cur->_left ||prev ==cur->_right )))
{
  cout<<cur->_data<<" ";
  prev=cur;
  s.pop();
}
 
else
{
if(cur->_right!=NULL)
  s.push(cur->_right);
    if(cur->_left!=NULL)
   s.push(cur->_left); 
}
  }
}
 

//层序遍历二叉树
void Leve1Order()
{
 queue<Node*>q;
 if(_root!=NULL)
 {
 q.push(_root);
 }
while(!q.empty())
{
   Node* front=q.front();
   cout<<front->_data <<" ";
   if(front->_left!=NULL)
q.push(front->_left);
   if(front->_right!=NULL)
q.push(front->_right);
   q.pop();
 }
 cout<<endl;
}

//求二叉树节点的个数
/*size_t Size()
{
return _Size(_root);
 
}
 
size_t _Size(Node* root)
{
  if(root==NULL)
  return 0;
  return 1+_Size(root->_left)+_Size(root->_right);
}*/
//
size_t Size()
{
  return _Size(_root);
}
//
size_t _Size(Node* root)
{
  static size_t Ssize=0;
  if(root==NULL)
  return 0;
  ++Ssize;
  _Size(root->_left);
  _Size(root->_right);
  return Ssize;
}
 
//二叉树的深度
size_t Depth()
{
return _Depth(_root);
}
 
size_t _Depth(Node* root)
{
if(root==NULL)
return 0;
     size_t left=_Depth(root->_left )+1;
 size_t right=_Depth(root->_right)+1;
return (left>right)?left:right;
}
 
//递归求二叉树叶子节点的个数
size_t LeafSize()
{
  return _LeafSize(_root);
}
 
//
size_t _LeafSize(Node* root)
{
  if(root==NULL)
  return 0;
  if(root->_left  ==NULL&&root->_right ==NULL)
  {
    return 1;
  }
  return _LeafSize(root->_left )+_LeafSize(root->_right );
}
 
};
 
 
void test()
{
int arr[10]={1,2,3,‘#‘,‘#‘,4,‘#‘,‘#‘,5,6};
BinaryTree<int>bt(arr,10,0,‘#‘);
 
cout<<"先序递归遍历:";
bt.PrevOrder();
cout<<endl;
cout<<"先序非递归遍历:";
bt.PrevOrder_NonR();
cout<<endl;
 
cout<<"中序递归遍历:";
bt.InOrder();
cout<<endl;
cout<<"中序非递归遍历:";
bt.InOrder_NonR();
cout<<endl;
 
cout<<"后序递归遍历:";
bt.PostOrder();
cout<<endl;
cout<<"后序非递归遍历:";
bt.PostOrder_NonR();
cout<<endl;
 
cout<<"层序遍历二叉树:";
bt.Leve1Order();
cout<<endl;
 
cout<<"二叉树的大小:"<<bt.Size()<<endl;
cout<<"二叉树的深度:"<<bt.Depth()<<endl;
cout<<"二叉树叶子节点个数:"<<bt.LeafSize()<<endl;
};
int main()
{
test();
  getchar();
  return 0;
}
时间: 2024-11-03 01:35:55

C++实现二叉树的存储与遍历的相关文章

二叉树的存储与遍历

typedef char status; typedef char Telemtype; #define NULL 0 #define OK 1 typedef struct bitnode{ Telemtype data; struct bitnode *lchild,*rchild; }bitnode,*bitree; Creatbitree(bitree &t) { //先序创建二叉树 char ch; scanf("%c",&ch); if(ch=='*') t

二叉树的存储方式以及递归和非递归的三种遍历方式

树的定义和基本术语 树(Tree)是n(n>=0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件: (1)有且仅有一个特定的称为根(Root)的结点: (2)其余的结点可分为m(m>=0)个互不相交的子集T1,T2,T3-Tm,其中每个子集又是一棵树,并称其为子树(Subtree). 树形结构应用实例: 1.日常生活:家族谱.行政组织结构:书的目录 2.计算机:资源管理器的文件夹: 编译程序:用树表示源程序的语法结构: 数据库系统:用树组织信息: 分析算法:用树来描述其执行过程:

二叉树 二叉树的性质 存储结构 遍历二叉树 C实现二叉树的创建和遍历 线索二叉树

定义 二叉树(binary tree)是n(n>=0)个结点的有限集合,该集合为空集合称为空二叉树,或者有一个根结点和两棵互不相交的,分别称为树根结点的左孩子树和右孩子树组成. 二叉树的特点 每个结点最多有两棵子树,所以二叉树总没有度大于2的结点 左子树和右子树是有顺序的,次数不能任意颠倒 即使树中某结点只有一棵子树,也要区分是左子树还是右子树 特殊的二叉树 1. 斜树 所有的结点都只有左子树的二叉树称为左斜树; 所有的结点都只有右子树的二叉树称为右斜树; 这两者统称为斜树 2. 满二叉树 在一

二叉树的三种遍历的应用(表达式,求深度,叶子数,结点数,二叉树的建立,复制)

表达式的表示 如图所示的二叉树表达式: a+b*(c-d)-e/f 若先序遍历此二叉树,按访问结点的先后次序将结点排列起来,其先序序列为: (波兰式,前缀表达式)  -+a*b-cd/ef 按中序遍历,其中序序列为:a+b*c-d-e/f (中缀表达式) 按后序遍历,其后序序列为:abcd-*+ef/- (逆波兰式,后缀表达式) 注:人喜欢中缀形式的算术表达式,对于计算机,使用后缀易于求值 查询二叉树中某个结点 使用先序遍历算法进行查询遍历 // 若二叉树中存在和 x 相同的元素,则 p 指向该

关于二叉树的几种遍历方法

转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/38390513 作者:小马 一 二叉树的一些概念 二叉树就是每个结点最多有两个子树的树形存储结构.先上图,方便后面分析. 1 满二叉树和完全二叉树 上图就是典型的二叉树,其中左边的图还叫做满二叉树,右边是完全二叉树.然后我们可以得出结论,满二叉树一定是完全二叉树,但是反过来就不一定.满二叉树的定义是除了叶子结点,其它结点左右孩子都有,深度为k的满二叉树,结点数就是2的k次方减1.完

Leetcode: Binary Tree Preorder Traversal(二叉树非递归前序遍历)

题目: Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [1,2,3]. Note: Recursive solution is trivial, could you do it iteratively? 二叉树的前序遍历 先看递归的写法(C++): /** * Definition f

【算法与数据结构】二叉树的 中序 遍历

前一篇写了二叉树的先序遍历,本篇记录一下二叉树的中序遍历,主要是非递归形式的中序遍历. 由于距离上篇有好几天了,所以这里把二叉树的创建和存储结构也重复的写了一遍. 二叉树如下 二叉树的存储方式依然是二叉链表方式,其结构如下 typedef struct _tagBinTree { unsigned char value; struct _tagBinTree* left; struct _tagBinTree* right; }BinTree, *PBinTree; 先序递归形式的创建二叉树代码

树与森林的存储、遍历和树与森林的转换

树的存储结构 双亲表示法 孩子表示法: (a)多重链表(链表中每个指针指向一棵子树的根结点); (b)把每个跟结点的孩子结点排列起来,看成一个线性表,且以单链表做存储结构.且N个头指针也组成一个线性表. 孩子兄弟表示法://二叉树表示法或二叉链表表示法 以二叉链表做树的存储结构,链表中结点的两个链域分别指向该结点的第一个孩子结点和下一个兄弟结点(fchild 和nsibling) //孩子兄弟表示法 typedef struct CSNode{ int data; CSNode *fchild

数据结构 - 二叉树的存储结构

顺序存储结构 二叉树存储结构的类型定义: #define MAX_SIZE 100 typedef telemtype sqbitree[MAX_SIZE]; 用一组地址连续的存储单元依次"自上而下.自左至右"存储完全二叉树的数据元素. 对于完全二叉树上编号为i的结点元素存储在一维数组的下标值为i-1的分量中,如图6-6(c)所示. 对于一般的二叉树,将其每个结点与完全二叉树上的结点相对照,存储在一维数组中, 链式存储结构 设计不同的结点结构可构成不同的链式存储结构. (1) 结点的类