路径长度:根节点到任何节点有唯一路径,路径所经过的边数,称为路径长度。
节点深度:根节点到任一节点的路径长度,即所谓该节点的深度。
节点高度:该节点到叶子节点的路径长度。
二叉树和树的根本区别:
二叉树的每个元素都恰好有两棵子树。而树的每个元素可有任意数量的子树。
在二叉树中,每个元素的子树都是有序的,有左子树和右子树之分。树的子树是无序的。
二叉树的特性
- 一棵二叉树有n个元素,n>0,该二叉树有n-1条边。
- 一棵二叉树的高度为h,h>=0,它最少有h个元素,最多有2^h-1个元素(满二叉树)。
- 一棵二叉树有n个元素,n>0,它的高度最大为n,最小高度为log2(n+1)。
二叉树的描述
在数组表示中,二叉树的元素按照其编号存储在数组的相应位置。如果二叉树的元素较少时,这样的表示方法比较浪费空间。所以二叉树最常用的表示方法是用指针。每个元素用一个节点表示,节点有两个指针域,分别是leftChild和rightChild,还有一个element域。
template<class T>
struct binaryTreeNode{
T element;
binaryTreeNode<T> *leftChild;
*rightChild;
binaryTreeNode() {leftChild=NULL;rightChild=NULL;}
binaryTreeNode(const T& theElement){
element(theElement);
leftChild=rightChild=NULL;
}
binaryTreeNode(const T& theElement,binaryTreeNode *left,binaryTreeNode *right){
element(theElement);
leftChild=left;
rightChild=right;
}
}
二叉树遍历
前序遍历
template<class T>
void preOrder(binaryTreeNode<T> *t)
{
if(t!=NULL)
{
visit(t);
preOrder(t->leftChild);
preOrder(t->rightChild);
}
}
中序遍历
template<class T>
void inOrder(binaryTreeNode<T> *t)
{
if(t!=NULL)
{
inOrder(t->leftChild);
visit(t);
inOrder(t->rightChild);
}
}
后序遍历
template<class T>
void postOrder(binaryTreeNode<T> *t)
{
if(t!=NULL)
{
postOrder(t->leftChild);
postOrder(t->rightChild);
visit(t);
}
}
层次遍历
template<class T>
void levelOrder(binaryTreeNode<T> *t)
{
arrayQueue<binaryTreeNode<T>*> q;
while(t!=NULL){
visit(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();
}
}
二叉树抽象类
template<class T>
class binaryTree
{
public:
virtual ~binaryTree() {}
virtual bool empty() const = 0;
virtual int size() const = 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;
}
class linkedBinaryTree:public binaryTree<binaryTreeNode<E>>
{
public:
linkedBinaryTree(){ root=NULL; treeSize=0;}
~linkedBinaryTree(){erase();};
void preOrder(void(*theVisit)(binaryTreeNode<E>*))
{
visit=theVisit;
preOrder(root);
}
void erase()
{
postOrder(dispose);
root=NULL;
treeSize=0;
}
private:
binaryTreeNode<E> *root;
int treeSize;
static void (*visit) (binaryTreeNode<E>*);
static void preOrder(binaryTreeNode<E> *t);
static void inder(binaryTreeNode<E> *t);
static void postOrder(binaryTreeNode<E> *t);
static void dispose(binaryTreeNode<E> *t) {delete t;}
}