曾品闲的数据结构复习之四:二叉树(BinaryTree)(一)

二叉树涉及到的东西很多,分成几天来复习


一.基本概念(参考电子科大mooc内容)

递归定义:

二叉树或为空树,或由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。

相关概念:

1.结点的度:结点拥有的子树个数
2.叶子:度为0的结点
3.child:结点子树的根
4.parent:child结点的上层结点
5.子孙:以某节点为根的子树中的任意一个结点
6. 祖先:从叶子走到根结点所经的所有结点
7. 结点的层次:根为一层,其孩子为第二层,孩子的孩子为第三层,以此类推
8. 兄弟:同一个结点的孩子
9. 堂兄:双亲在同一层的结点
10.二叉树的度:最大的结点度(二叉树度最大为2)
11.深度:结点的最大层次数

特点:

1 . 每一个节点最多有两颗子树,不存在节点度大于2的节点
2 . 子树有左右之分,不能颠倒

几种基本形态:

1 .空树
2 .只含根结点
3 .右子树为空树(左子树为空树)
4 .左右子树均不为空树

两种特殊的二叉树:

1.满二叉树:除了叶子结点,所有结点的度都为2,且叶子节点在同一层
2.完全二叉树:除了最后一层,其他各层结点都达到最大个数,最后一层所有节点集中在左边(结点只可能出现在最下层或次最下层,结点数n满足: 2 k − 1 − 1 2^{k-1}-1 2k11<n<= 2 k − 1 2^k-1 2k1
满二叉树是完全二叉树,反之不成立

二叉树的性质:

1.在二叉树的第i层上至多有( 2 i − 1 2^{i-1} 2i1)个结点(i>=1)(即每层最大节点数是确定的)
2.深度为k的二叉树至多含( 2 k 2^k 2k )-1个结点(k>=1)
3.叶节点与双分支结点的关系:
对任何一棵二叉树,设叶子节点数为n0,度为2的结点数为n2,则有n0=n2+1
4.具有n个结点的完全二叉树深度为: l o g 2 n log_2{n} log2n+1
5.对一个完全二叉树(n个结点)结点按层序编号,对任意一个结点i有:
若i=1,则结点为二叉树的根,i>1,则其双亲为i/2(向下取整)
若2i>n,则结点i无左孩子,若2i<=n,则其左孩子为2i
若2i+1>n,则结点i无右孩子,若2i<=n,则其右孩子为2i+1

二.二叉树构建分析(c++)

(一)相关操作:

创建二叉树
三种方式遍历(先序,中序,后序)
找到结点并填入数据
销毁二叉树

今天就先实现这么多,免得消化不良

(二)相关定义和声明

结点定义:

//包含:左右子树,序号,数据
template<typename T>
class BiNode{
public:
 BiNode<T> *lchild;
 BiNode<T> *rchild;
 T data;
 char No;
}; 

二叉树定义:

/*包含:构造函数,析构函数
       三种遍历函数
       输入数据函数*/
template<typename T>
class My_BiTree{
public:
 My_BiTree();
 ~My_BiTree();
 void CreateBiTree();
 void PreTraversing();
 void InTraversing();
 void PostTraversing();
 void InputData(char n,T data)
private:
 BiNode<T> *parent;
};    

(三)函数实现代码

template<typename T>
My_BiTree<T>::My_BiTree()
{
 parent=new BiNode<T>;
 parent->lchild=NULL;
 parent->rchild=NULL;
 std::cout<<"please input char as no.,'#' to stop"<<std::endl;
 parent=CreateBiTree();
};
template<typename T>
BiNode<T>* My_BiTree<T>::CreateBiTree()
{
 BiNode<T> *node;
 char temp;
 std::cin>>temp;
 if(temp=='#')
 {
  return NULL;
 }
 else
 {
  node=new BiNode<T>;
  node->No=temp;
  std::cout<<"add success:"<<node->No<<std::endl;
  node->lchild=CreateBiTree();
  node->rchild=CreateBiTree();
  return node;
 }
};
template<typename T>
void My_BiTree<T>::PreTraversing(BiNode<T> *node)
{
 if(node)
 {
  std::cout<<node->No<<" ";
  PreTraversing(node->lchild);
  PreTraversing(node->rchild);
 }
};
template<typename T>
void My_BiTree<T>::PreTraversing()
{
 PreTraversing(parent);
 std::cout<<std::endl;
}
template<typename T>
void My_BiTree<T>::InTraversing(BiNode<T> *node)
{
 if(node!=NULL)
 {
  InTraversing(node->lchild);
  std::cout<<node->No<<" ";
  InTraversing(node->rchild); 
 }
};
template<typename T>
void My_BiTree<T>::InTraversing()
{
 InTraversing(parent);
 std::cout<<std::endl;
}
template<typename T>
void My_BiTree<T>::PostTraversing(BiNode<T> *node)
{
 if(node!=NULL)
 {
  PostTraversing(node->lchild);
  PostTraversing(node->rchild);
  std::cout<<node->No<<" ";
 }
};
template<typename T>
void My_BiTree<T>::PostTraversing()
{
 PostTraversing(parent);
 std::cout<<std::endl;
}
template<typename T>
void My_BiTree<T>::InputData(BiNode<T> *node)
{
 if(node!=NULL)
 {
  std::cout<<"this is no."<<node->No<<" please input data"<<std::endl;
  std::cin>>node->data;
  InputData(node->lchild);
  InputData(node->rchild);
 }
}
template<typename T>
void My_BiTree<T>::DestroyTree(BiNode<T> *node)
{
 if(node!=NULL)
 {
  DestroyTree(node->lchild);
  DestroyTree(node->rchild);
  if(node==parent)std::cout<<"destruction complete"<<std::endl;
  delete node;
 }
};
template<typename T>
My_BiTree<T>::~My_BiTree()
{
 DestroyTree(parent);
};
int main()
{
 My_BiTree<int> b1; 
 b1.PreTraversing();
 b1.InTraversing();
 b1.PostTraversing();
 return 0;
}

在CreateTree上卡了很久…一开始用的void来写的,在指针传值上被搞晕了,后面直接改成返回一个Binode的指针,以赋值的形式来创建就好了
结果:
在这里插入图片描述没问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值