内容概要:
- 二叉树相关概念
- 简单二叉树模板类的实现:二叉树的遍历、计算高度、计算节点数目
- 注意事项
一、二叉树相关概念:
第一部分:
- 节点(node),根节点(root),左子树(left subtree),右子树(right suntree),子节点(children),父节点(parent);每一个非空二叉树有一个根节点和左右子树。
- 路径(path),路径的长度(length),祖先(ancestor),深度(depth),高度(height),层数(level);其中 高度=深度+1=层数+1,根节点深度为0,层数为0,高度为1。
- 叶节点(leaf):子树均为空的节点。
- 分支节点或内部节点(internal node):至少有一个非空子树的节点。
- 满二叉树(full binary tree):二叉树中的每一个内部节点都有两个非空子节点,其更严格的定义是高度为h的二叉树,有2^h -1个节点
- 完全二叉树(complete binary tree):从二叉树的根节点起,每一层从左到右依次填充
第二部分:
- 非空满二叉树的叶节点数等于其内部节点数加1(用数学归纳法证明)
- 一棵非空二叉树空子树的数目等于其节点数目加1
二、CODE(测试环境:VS2017):
//BT.h
#ifndef BT_H
#define BT_H
#include<iostream>
template<typename E>
class BTNode
{
private:
E key;
BTNode*lc;
BTNode*rc;
public:
BTNode() { lc = rc = NULL; }
BTNode(E k, BTNode*l = NULL, BTNode*r = NULL) { key = k; lc = l; rc = r; }
~BTNode(){}
E& element() { return key; }
void setElement(const E&it) { key = it; }
inline BTNode*left () const { return lc; }
void setLeft(BTNode*l) { lc = l; }
inline BTNode*right () const { return rc; }
void setRight(BTNode*r) { rc = r; }
bool isLeaf() const { return (lc == NULL) && (rc == NULL); }
void traverse() const
{
if (isLeaf())
{
std::cout << "Leaf:" << key << endl;
}
else
{
std::cout << "Internal:" << key << endl;
if (lc != NULL)
lc->traverse();
if (rc != NULL)
rc->traverse();
}
}
};
#endif // !BT_H
//《数据结构与算法分析(第三版)》
//main.cpp
#include<iostream>
#include"BT.h"
using namespace std;
template<typename E>
void preOrder(BTNode<E>*root)
{
if (root == NULL)
return;
cout << root->element() << " ";//do something
preOrder(root->left());
preOrder(root->right());
}
template<typename E>
void inOrder(BTNode<E>*root)
{
if (root == NULL)
return;
inOrder(root->left());
cout << root->element() << " ";//do something
inOrder(root->right());
}
template<typename E>
void postOrder(BTNode<E>*root)
{
if (root == NULL)
return;
postOrder(root->left());
postOrder(root->right());
cout << root->element() << " ";//do something
}
template<typename E>
int height(BTNode<E>*root)
{
if (root == NULL)
return 0;
int hl = height(root->left());
int hr = height(root->right());
if (hl > hr)
return ++hl;
else
return ++hr;
}
template<typename E>
int nodeSize(BTNode<E>*root)
{
/*static int nodesize = 1;
if (root == NULL)
return 0;
nodeSize(root->left());
nodeSize(root->right());
return nodesize++;*/
if (root == NULL)
return 0;
return 1 + nodeSize(root->left()) + nodeSize(root->right());
}
int main()
{
BTNode<int>*root;
root = new BTNode<int>;
root->setElement(10);
root->setLeft(new BTNode<int>(4));
root->setRight(new BTNode<int>(5));
root->left()->setRight(new BTNode<int>(7));
root->right()->setLeft(new BTNode<int>(9));
root->traverse();
preOrder(root);
cout << endl;
inOrder(root);
cout << endl;
postOrder(root);
cout << endl;
cout <<"height:"<< height(root) << endl;
cout << "node size:"<<nodeSize(root) << endl;
system("pause");
}
输出:
三、注意事项:
- 用链式存储二叉树的结构性内存开销十分大
- 鉴于完全二叉树的特点,可以用数组来存储完全二叉树
- 实际使用二叉树时,叶节点与内部节点是否使用相同的类定义十分重要