C语言二叉树操作
一、实验目的
- 掌握二叉树的逻辑结构特征和二叉链表存储结构;
- 掌握二叉树的遍历方法,学会灵活运用遍历算法实现二叉树的相关计算;
- 掌握二叉树中序遍历方法的递归和非递归实现算法;
- 掌握二叉树的构造方法;
- 二叉树中的结点信息要从终端以正确的方式输入,具体的输入和输出格式不限;
- 算法要具有较好的健壮性,对错误操作要做适当处理;
- 对二叉树做中序遍历时,要对所采用的算法类型加以说明。
二、实验任务
- 输入二叉树的先序序列构造相应的二叉树;
- 分别用递归算法和非递归算法中序遍历二叉树,输出该二叉树的中序序列;
- 对二叉树进行层次遍历,输出得到的结点序列;
- 计算二叉树中结点的总数N,度为2的结点个数N2和叶子结点个数N0;
- 计算二叉树的深度Height。
三、实验过程与结果
二叉树的链式存储结构
#include"stdafx.h"
#include<iostream>
#include<string>
#include<stack>
#include<queue>
using namespace std;
template<typename T>
struct BiNode{
T date;
BiNode<T> *LChild, *RChild;
};
template<typename T>
class BiTree {
private:
BiNode<T>* BiTreeRoot;
public:
BiTree() {
BiTreeRoot = NULL;
//createBiTree(BiTreeRoot);
}
void create() {
cout << "输入数据:";
createBiTree(BiTreeRoot);
}
void traverse() {
PreOrderTraverse(BiTreeRoot);
}
void createBiTree(BiNode<T>* &p) { //递归先序创建
char s;
cin >> s;
if (s == '#') {
p = NULL;
}
else {
p= new BiNode<T>;
p->date = s;
p->LChild = p->RChild = NULL;
createBiTree(p->LChild);
createBiTree(p->RChild);
}
}
/*
void PreOrderTraverse(BiNode<T>* p,int d) { //森林递归先序遍历,同时打印层次
if (p) {
cout << p->date << " "<<d<<endl;
PreOrderTraverse(p->LChild,d+1);
PreOrderTraverse(p->RChild,d);
}
}
*/
void PreOrderTraverse(BiNode<T>* p) { //递归先序遍历
if (p) {
cout << p->date << " ";
PreOrderTraverse(p->LChild);
PreOrderTraverse(p->RChild);
}
}
void InOrderTraverse(BiNode<T>* p) { //递归中序遍历
if (p) {
PreOrderTraverse(p->LChild);
cout << p->date << " ";
PreOrderTraverse(p->RChild);
}
}
void RreOrderTraverse_N() { //非递归先序遍历
stack<BiNode<T>*> s;
BiNode<T>* t = BiTreeRoot;
while (t || !s.empty()) {
if (t) {
s.push(t);
t = t->LChild;
}
else {
cout << t->date << " ";
t = s.top();
s.pop();
t = t->RChild;
}
}
}
void InOrderTraverse_N() { //非递归中序遍历
stack<BiNode<T>*> s;
BiNode<T>* t = BiTreeRoot;
while (t || !s.empty()) {
if (t) {
s.push(t);
t = t->LChild;
}
else {
t=s.top();
s.pop();
cout << t->date << " ";
t = t->RChild;
}
}
}
void LevelOrderTraverse() { //层次遍历二叉树
queue<BiNode<T>*> q;
BiNode<T> *p;
q.push(BiTreeRoot);
while (!q.empty()) {
p = q.front();
q.pop();
cout << p->date << " ";
if (p->LChild)
q.push(p->LChild);
if (p->RChild)
q.push(p->RChild);
}
}
int getDeepth(BiNode<T> *p) { //获取该树的深度
if (!p)
return 0;
int leftdeepth = getDeepth(p->LChild);
int rightdeepth = getDeepth(p->RChild);
if (leftdeepth >= rightdeepth)
return leftdeepth+1;
else
return rightdeepth+1;
}
int countLeaf(BiNode<T> *p) { //叶子结点个数N0;
if (!p)
return 0;
if (p->LChild == NULL && p->RChild == NULL)
return 1;
return countLeaf(p->LChild) + countLeaf(p->RChild);
}
int countAllNode(BiNode<T>* p) { //统计所有节点个数
if (!p)
return 0;
return countAllNode(p->LChild) + countAllNode(p->RChild)+1;
}
int countDoubleNode(BiNode<T>* p) { //计算度为二的节点数
if (p == NULL)
return 0;
if (p->LChild != NULL && p->RChild != NULL)
return countDoubleNode(p->LChild) + countDoubleNode(p->RChild)+1;
if (p->LChild == NULL && p->RChild == NULL) //都空
return 0;
if (p->LChild == NULL || p->RChild == NULL) //有一个非空
return countDoubleNode(p->RChild)+ countDoubleNode(p->LChild);
}
BiNode<T> *getRoot(){
return BiTreeRoot;
}
};
//测试数据: ABD#G###CE##F##
int main() {
BiTree<char> t;
t.create();
//t.traverse();
cout << "\n中序遍历:" << endl;
t.InOrderTraverse_N();
cout << "\n层次遍历:" << endl;
t.LevelOrderTraverse();
//cout << "\n递归先序" << endl;
//t.PreOrderTraverse(t.getRoot(), 0);
cout << endl;
cout<<"总结点数:"<<t.countAllNode(t.getRoot())<<endl;
cout<<"叶子节点数:"<<t.countLeaf(t.getRoot())<<endl;
cout<<"度为二的节点数:"<<t.countDoubleNode(t.getRoot())<<endl;
cout << "深度为:" << t.getDeepth(t.getRoot()) << endl;
return 0;
}

浙公网安备 33010602011771号