1、题目描述
编写一个二叉链表类,试写出求二叉树结点数目和二叉树叶子节点的数目。(只要写二叉链表的前序输入、先序中序后序输出、求节点数目和求叶子节点数目的方法)
2、 设计思路
二叉树一般多采用二叉链表(binary linked list)存储,其基本思想是:令二叉树的每一个结点对应一个链表结点链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针。二叉链表的结点结构如下图所示:
其中,data为数据域,存放该结点的数据信息;
lchild为左指针域,存放指向左孩子的指针,当左孩子不存在时为空指针;
rchild为右指针域,存放指向右孩子的指针,当右孩子不存在时为空指针;
创建二叉树时,需要设置RefValue,在以下设计中以’#’表示创建的二叉树结点的data域为空,利用前序遍历创建二叉树。又因为二叉链表属于动态内存分配,需要在析构函数中释放二叉链表的所有结点。在释放某结点时,该结点的左右都子树已经释放,所以应该采用后序遍历。
代码实现
#include<iostream>
using namespace std;
template <class T>
struct BinTreeNode
{
T data;
BinTreeNode<T>* leftChild;
BinTreeNode<T>* rightChild;
BinTreeNode()
{
leftChild = NULL;
rightChild = NULL;
}
BinTreeNode(T x, BinTreeNode<T>* lChild=NULL, BinTreeNode<T>* rChild=NULL)
{
data = x;
leftChild = lChild;
rightChild = rChild;
}
};
template <class T>
class BinaryTree
{
public:
BinaryTree(T value);
~BinaryTree(){Release(root);}
//返回节点数
int Size() { return size;};
//返回叶节点数
int NumberOfLeafNodes() { return numberOfLeafNodes; };
// 递归前序遍历二叉树
void PreOrder() { PreOrder(root); };
// 递归中序遍历二叉树
void InOrder() { InOrder(root); };
// 递归后序遍历二叉树
void PostOrder() { PostOrder(root); };
protected:
//叶子数
int numberOfLeafNodes;
//个数
int size;
//根节点
BinTreeNode<T>* root;
//停止输入标志
T RefValue;
//个数
void set(BinTreeNode<T>* bt);
// 建立二叉树
BinTreeNode<T>* Creat(BinTreeNode<T>*bt);
// 析构函数调用
void Release(BinTreeNode<T>*bt);
// 前序遍历函数调用
void PreOrder(BinTreeNode<T>* bt);
// 中序遍历函数调用
void InOrder(BinTreeNode<T>* bt);
// 后序遍历函数调用
void PostOrder(BinTreeNode<T>* bt);
};
template <class T>
BinaryTree<T>::BinaryTree(T value)
{
RefValue = value;
root = Creat(root);
size = 0;
numberOfLeafNodes = 0;
set(root);
}
template<class T>
void BinaryTree<T>::set(BinTreeNode<T>* bt)
{
// 递归调用的结束条件
if (bt == NULL)
{
return;
}
// 访问根节点bt的数据域
size++;
if (bt->leftChild == NULL && bt->rightChild == NULL)
{
numberOfLeafNodes++;
}
// 前序递归遍历bt的左子树
set(bt->leftChild);
// 前序递归遍历bt的右子树
set(bt->rightChild);
}
template<class T>
BinTreeNode<T>* BinaryTree<T>::Creat(BinTreeNode<T>* bt)
{
T value;
// 输入结点的数据信息
cin >> value;
// 建立一棵空树
if (value == RefValue)
bt = NULL;
else
{
// 生成一个结点,数据域为ch
bt = new BinTreeNode<T>;
bt->data = value;
// 递归建立左子树
bt->leftChild = Creat(bt->leftChild);
// 递归建立右子树
bt->rightChild = Creat(bt->rightChild);
}
return bt;
}
template<class T>
void BinaryTree<T>::Release(BinTreeNode<T>* bt)
{
if (bt != NULL)
{
// 释放左子树
Release(bt->leftChild);
// 释放右子树
Release(bt->rightChild);
// 释放根节点
delete bt;
}
}
template<class T>
void BinaryTree<T>::PreOrder(BinTreeNode<T>* bt)
{
// 递归调用的结束条件
if (bt == NULL)
{
return;
}
// 访问根节点bt的数据域
cout << bt->data;
// 前序递归遍历bt的左子树
PreOrder(bt->leftChild);
// 前序递归遍历bt的右子树
PreOrder(bt->rightChild);
}
template<class T>
void BinaryTree<T>::InOrder(BinTreeNode<T>* bt)
{
if (bt == NULL)
{
return;
}
InOrder(bt->leftChild);
cout << bt->data;
InOrder(bt->rightChild);
}
template<class T>
void BinaryTree<T>::PostOrder(BinTreeNode<T>* bt)
{
if (bt == NULL)
{
return;
}
PostOrder(bt->leftChild);
PostOrder(bt->rightChild);
cout << bt->data;
}
int main()
{
cout << "开始建立二叉树,请输入:\n";
BinaryTree<char> BT('#');
cout << "结点数目:";
cout << BT.Size() << endl;
cout << "叶节点个数:";
cout << BT.NumberOfLeafNodes() << endl;
cout << "前序遍历: ";
BT.PreOrder();
cout << endl;
cout << "中序遍历: ";
BT.InOrder();
cout << endl;
cout << "后序遍历: ";
BT.PostOrder();
cout << endl;
return 0;
}