数据结构(六)二叉树
二叉树–c++实现
二叉树的定义
一颗二叉树 t 是有限个元素的集合。当二叉树非空时,其中有一个元素称为根,余下的元素被划分成两颗二叉树,分别称为 t 的左子树和右子树。
二叉树的特性
-
一棵二叉树有n个元素,n > 0,它有n-1条边。
-
一棵二叉树的高度为 h, h ≥ 0 h\ge0 h≥0,它最少有h个元素,最多有 2 h − 1 2^h-1 2h−1个元素。
-
一棵二叉树有n个元素,n > 0,它的高度最大为n,最小高度为 [ l o g 2 ( n + 1 ) ] [log_2(n+1)] [log2(n+1)]。
-
设完全二叉树的一元素其编号为i, 1 ≤ i ≤ n 1\le i\le n 1≤i≤n 。有以下关系成立:
a. 如果i=1,则该元素为二叉树的根。若i>1,则其父节点的编号为[i/2]。
b. 如果2i>n,则该元素无左孩子。否则,其左孩子的编号为2i。
c. 如果 2i+1>n,则该元素无右孩子。否则,其右孩子的编号为 2i+1。
二叉树的描述
二叉树的常用表示方法是使用链表描述。每个节点有两个指针域leftChild、rightChild和一个数据域data。
二叉树的实现
在BinaryTree文件中,定义了binaryTreeNode结构体,声明了二叉树类
template<class T> struct binaryTreeNode{
T data;
binaryTreeNode<T> *leftChild,*rightChild;
binaryTreeNode() {leftChild = rightChild = nullptr;}
binaryTreeNode(const T& element){
data = element;
leftChild = rightChild = nullptr;
}
binaryTreeNode(const T& element, binaryTreeNode<T>*lChild, binaryTreeNode<T> *rChild){
data = element;
leftChild = lChild;
rightChild = rChild;
}
};
template<class T>
class BinaryTree {
private:
binaryTreeNode<T> *root;
public:
BinaryTree();
BinaryTree(const T& element);
BinaryTree(binaryTreeNode<T> *node);
~BinaryTree(){};
void visit(binaryTreeNode<T> *node) const;
void preOrder(binaryTreeNode<T> *root) const;
void inOrder(binaryTreeNode<T> *root) const;
void postOrder(binaryTreeNode<T> *root) const;
void levelOrder(binaryTreeNode<T> *root) const;
bool isEmpty() const;
int size(binaryTreeNode<T> *node) const;
int height(binaryTreeNode<T> *node) const;
};
二叉树类的实现:
#include <iostream>
#include "BinaryTree.h"
#include <queue>
template<class T>
BinaryTree<T>::BinaryTree() {
root = new binaryTreeNode<T>;
}
template<class T>
BinaryTree<T>::BinaryTree(const T &element) {
root = new binaryTreeNode<T>(element);
}
template<class T>
BinaryTree<T>::BinaryTree(binaryTreeNode<T> *node) {
root = node;
}
template<class T>
void BinaryTree<T>::visit(binaryTreeNode<T> *node) const {
std::cout << node->data << " ";
}
template<class T>
void BinaryTree<T>::preOrder(binaryTreeNode<T> *root) const {
if (root == nullptr) return;
else{
visit(root);
preOrder(root->leftChild);
preOrder(root->rightChild);
}
}
template<class T>
void BinaryTree<T>::inOrder(binaryTreeNode<T> *root) const {
if (root == nullptr) return;
else{
inOrder(root->leftChild);
visit(root);
inOrder(root->rightChild);
}
}
template<class T>
void BinaryTree<T>::postOrder(binaryTreeNode<T> *root) const {
if (root == nullptr) return;
else{
postOrder(root->leftChild);
postOrder(root->rightChild);
visit(root);
}
}
template<class T>
void BinaryTree<T>::levelOrder(binaryTreeNode<T> *root) const {
std::queue<binaryTreeNode<T>*> q;
q.push(root);
binaryTreeNode<T> *t;
while (!q.empty()){
t = q.front();
visit(t);
q.pop();
if (t->leftChild != nullptr) q.push(t->leftChild);
if (t->rightChild != nullptr) q.push(t->rightChild);
}
}
template<class T>
bool BinaryTree<T>::isEmpty() const {
return root == nullptr;
}
template<class T>
int BinaryTree<T>::size(binaryTreeNode<T> *node) const {
if (node == nullptr) return 0;
else{
int lSize = size(node->leftChild);
int rSize = size(node->rightChild);
return lSize + rSize + 1;
}
}
template<class T>
int BinaryTree<T>::height(binaryTreeNode<T> *node) const {
if (node == nullptr){
return 0;
} else{
int lHeight = height(node->leftChild);
int rHeight = height(node->rightChild);
return std::max(lHeight, rHeight) + 1;
}
}
测试程序:
int main(){
binaryTreeNode<char> a('A'),b('B'),c('C'),d('D'),e('E'),f('F');
a.leftChild = &b;
a.rightChild = &c;
b.leftChild = &d;
b.rightChild = &e;
d.leftChild = &f;
BinaryTree<char> binaryTree(&a);
binaryTree.preOrder(&a);
std::cout << std::endl;
binaryTree.inOrder(&a);
std::cout << std::endl;
binaryTree.postOrder(&a);
std::cout << std::endl;
binaryTree.levelOrder(&a);
std::cout << std::endl;
std::cout << "height = " << binaryTree.height(&a) << std::endl;
std::cout << "size = " << binaryTree.size(&a) <<std::endl;
return 0;
}
测试结果:
A B D F E C
F D B E A C
F D E B C A
A B C D E F
height = 4
size = 6