数据结构之二叉树(一)
目录 (Table of Contents)
树的简单介绍
树和二叉树的术语
- 节点的度:一个节点含有的子树的个数称为该节点的度;
- 树的度:一棵树中,最大的节点的度称为树的度;
- 叶节点或终端节点:度为零的节点;
- 非终端节点或分支节点:度不为零的节点;
- 父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
- 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
- 兄弟节点:具有相同父节点的节点互称为兄弟节点;
- 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
- 树的高度或深度:树中节点的最大层次;
- 堂兄弟节点:父节点在同一层的节点互为堂兄弟;
- 节点的祖先:从根到该节点所经分支上的所有节点;
- 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
森林:由m(m>=0)棵互不相交的树的集合称为森林;
引自:树的基本术语
树的特点
- 每个节点有零个或多个子节点
- 没有父节点的节点称为根节点
- 每一个非根节点有且仅有一个父节点
- 除了根节点外,每个子节点可以分为多个不相交的子树
树的种类
- 二叉树
- 完全二叉树
- 满二叉树
- 平衡二叉树
- 二叉搜索树
- 完全二叉树
- 霍夫曼树
- B树
二叉树
二叉树和树的根本区别:
- 二叉树的每个元素都恰好有两颗子树,而树的每个元素可以有任意数量的子树
- 二叉树中,每个元素的子树都是有序的
- 二叉树可以为空,而树不可以为空
二叉树的简单创建
#include <iostream>
using namespace std;
template <typename T>
struct binaryTreeNode
{
T element;
binaryTreeNode<T> *leftChild, *rightChild;
};
template <typename T>
void printvalue(binaryTreeNode<T> *t)
{
cout << t->element << " ";
}
template <typename T>
void inOrder(binaryTreeNode<T> *t)
{
if (t != NULL)
{
inOrder(t->leftChild);
printvalue<T>(t);
inOrder(t->rightChild);
}
}
int main()
{
binaryTreeNode<int> one, two, three;
one.element = 10;
two.element = 20;
three.element = 30;
one.leftChild = &two;
one.rightChild = &three;
two.leftChild = NULL;
two.leftChild = NULL;
three.leftChild = NULL;
three.rightChild = NULL;
inOrder<int>(&one);
return 0;
}
二叉树的遍历:
前序遍历
template <typename T>
void preOrder(binaryTreeNode<T> *t)
{
if(t != NULL)
{
printvalue(t); // 输出元素
preOrder(t->leftChild); // 前序遍历左子树
preOrder(t->rightChild); // 前序遍历右子树
}
}
中序遍历
template <typename T>
void inOrder(binaryTreeNode<T> *t)
{
if(t != NULL)
{
inOrder(t->leftChild); // 中序遍历左子树
printvalue(t); // 输出元素
inOrder(t->rightChild); // 中序遍历右子树
}
}
后序遍历
void postOrder(binaryTreeNode<T> *t)
{
if(t != NULL)
{
postOrder(t->leftChild); // 后序遍历左子树
postOrder(t->rightChild); // 后序序遍历右子树
printvalue(t); // 输出元素
}
}
层序遍历
// 层序遍历需要对列,递归编写很困难
template <typename T>
void levelOrder(binaryTreeNode<T> *t)
{
arrayQueue<<binaryTreeNode<T> *> q;
while(t != NULL)
{
printvalue(t);
if(t->leftChild != NULL)
q.push(t->leftChild);
if(t->rightChild != NULL)
q.push(t->rightChild);
try {
t = q.front();
}
catch(queueEmpty) {
return;
}
q.pop();
}
}
printvalue的实现
template <typename T>
void printvalue(binaryTreeNode<T> *t)
{
cout << t->element << ' ';
}
抽象二叉树的实现
二叉树节点的结构
template <typename T>
struct binaryTreeNode
{
T element;
binaryTreeNode<T> *leftChild, *rightChild;
binaryTreeNode() {
leftChild = rightChild = NULL;
}
binaryTreeNode(const T &theElement) : element(theElement)
{
leftChild = rightChild = NULL;
}
binaryTreeNode(const T &theElement, binaryTreeNode *theLeftChild, binaryTreeNode *theRightChild) : element(theElement)
{
leftChild = theLeftChild;
rightChild = theRightChild;
}
};
二叉树抽象类的构建
二叉树类的ADT描述
{
操作:
emtpy(); // 若树为空返回true
size(); // 返回树的节点个数
printvalue(t); // 输出节点元素函数
preOrder(t); // 前序遍历
inOrder(t); // 中序遍历
postOrder(t); // 后序遍历
levelOrder(t); // 层序遍历
}
代码实现
其中 T 表示二叉树节点结构
template <typename T>
class binaryTree
{
public:
virtual ~binaryTree() { };
virtual bool emtpy() const = 0;
virtual int size() const = 0;
virtual void printvalue(void *(T *)) = 0;
virtual void preOrder(void *(T *)) = 0;
virtual void inOrder(void *(T *)) = 0;
virtual void postOrder(void *(T *)) = 0;
virtual void levelOrder(void *(T *)) = 0;
}
余下代码的实现和完整代码将在下节中写出
附上: c语言实现二叉树遍历
原文: 数据结构之二叉树(一)