一、树的基本概念
树是一种层次结构,表达一对多的关系
树的节点:包含数据元素,还有指向其他节点的指针:孩纸指针,父节点指针
叶子节点,根节点,孩纸节点,双亲节点,兄弟节点,堂兄弟节点,祖先节点,子孙节点
节点的度:节点分支的个数
树的度:所有节点的度的最大值
树的路径:根节点到该节点上的所有节点连接起来的
层次:从根节点开始定义,根为第一层,根的孩纸为第二层,若节点中在第k层,其子树的根在第k+1层
树的深度(高度):树种节点的最大层次
有序树:树中节点的各个子树从左到右看做是有次序的
森林:即m个互不相交的树的集合
树的基本操作:求根节点,求双亲节点,求孩纸节点,建立一棵树,销毁一棵树等
二、二叉树
二叉树是每一个节点最多有两个子树的特殊的树,即树的度为2。二叉树是有序树,有左右子树之分。二叉树比较特殊的有完全二叉树、满二叉树,二叉平衡树等等。如下图所示:
二叉树的操作:新建树,销毁树,前序遍历,中序遍历,后续遍历,层次遍历,查找节点,树的高度,节点个数。。。。。。。。。
二叉树的性质:
二叉树在实现过程中,使用链表结构比较方便,下面给出二叉树的C++实现:
三、二叉树的C++实现
#pragma once
//#include"arrayQueue.h"//使用标准库的队列
#include
#include
using namespace std;
//节点结构
template
struct TreeNode
{
T element;//元素
TreeNode* leftchild;//左孩子
TreeNode* rightchild;//右孩子
TreeNode()
{
leftchild = rightchild = NULL;
}
TreeNode(const T& theElement)
{
element = theElement; leftchild = rightchild = NULL;
}
TreeNode(const T& theElement, TreeNode* left, TreeNode* right)
{
element = theElement; leftchild = left; rightchild = right;
}
};
//二叉树
template
class binaryTree
{
public:
//构造函数,复制构造函数和析构函数
binaryTree(){ root = NULL; theSize = 0; }//构造一个空树
~binaryTree(){ erase(); }//析构,通过调用erase函数删除所有节点
binaryTree(const binaryTree &thebinaryTree)//复制构造函数
{
theSize = thebinaryTree.theSize;
if (theSize==0)//如果树为空
{
root = NULL;
return;
}
//树不为空,挨个节点复制
deque*> q, p;//队列q存放原来的树的节点,p存放新建的树的节点
TreeNode* sourceNode = thebinaryTree.root;
root = new TreeNode(sourceNode->element);
TreeNode* targetNode = root;
q.push_back(sourceNode);
p.push_back(targetNode);
//将sourceNode复制到targetNode
while (q.empty()==0)
{
sourceNode = q.front();
targetNode = p.front();
if (sourceNode->leftchild != NULL)
{
q.push_back(sourceNode->leftchild);
targetNode->leftchild = new TreeNode(sourceNode->leftchild->element);
p.push_back(targetNode->leftchild);
}
if (sourceNode->rightchild != NULL)
{
q.push_back(sourceNode->rightchild);
targetNode->rightchild = new TreeNode(sourceNode->rightchild->element);
p.push_back(targetNode->rightchild);
}
q.pop_front();
p.pop_front();
}
}
//各种成员函数
int size() const{ return theSize; }//树的大小
bool empty() const{ return theSize == 0; }//树是否为空
T* rootelement() const//返回根节点的地址
{
if (theSize == 0){ return NULL; }
else { return &root->element; }//注意优先级
}
int height() const { return height(root); }//通过调用height(root)来求整个树的高度
void makeTree(const T& element, binaryTree& left, binaryTree& right);//建造一个树
binaryTree removeLeftSubtree();//移除左子树
binaryTree removeRightSubtree();//移除右子树
//整个树的前序遍历,形参表示一个函数用来处理遍历的当前节点,theVist是函数地址,返回值是void,其参数是TreeNode*
void preOrder(void(*theVisit) (TreeNode*)) { preOrder(theVisit, root); }
//整个树的中序遍历,
void inOrder(void (*theVisit) (TreeNode*)) { inOrder(theVisit,root); }
//整个树的后序遍历,
void postOrder(void (*theVisit) (TreeNode*)) { postOrder(theVisit,root); }
//整个树的层次遍历
void levelOrder(void(*theVisit) (TreeNode*)) { levelOrder(theVisit, root); }
//几种不同的输出
void preOrderOutput() { preOrder(output,root); cout << endl; }
void inOrderOutput() { inOrder(output,root); cout << endl; }
void postOrderOutput() { postOrder(output,root); cout << endl; }
void levelOrderOutput() { levelOrder(output,root); cout << endl; }
//删除树,清空整个树
void erase()
{
postOrder(dispose,root);
root = NULL;
theSize = 0;
}
//查找树的某一个节点
bool find(const T& theElement)
{
deque*> q;//队列
TreeNode *t = root;
while (t != NULL)
{
if (t->element==theElement)
{
return true;
}
// 将t的孩纸加入队列
if (t->leftchild != NULL)
q.push_back(t->leftchild);
if (t->rightchild != NULL)
q.push_back(t->rightchild);
// 获得下一个节点
if (q.empty() == 0)
t = q.front();
else
break;
q.pop_front();
}
return false;
}
protected:
TreeNode* root;//指向根节点的指针
int theSize;//树的元素个数
//前序遍历以t为根节点的树,参数visit是对节点的处理函数,
static void preOrder(void(*visit) (TreeNode*), TreeNode *t)
{
if (t != NULL)
{
visit(t);
preOrder(visit,t->leftchild);
preOrder(visit,t->rightchild);
}
}
//中序遍历以t为根节点的树,参数visit是对节点的处理函数,
static void inOrder(void(*visit) (TreeNode*), TreeNode *t)
{
if (t != NULL)
{
inOrder(visit,t->leftchild);
visit(t);
inOrder(visit,t->rightchild);
}
}
//后序遍历以t为根节点的树,参数visit是对节点的处理函数,
static void postOrder(void(*visit) (TreeNode*), TreeNode *t)
{
if (t != NULL)
{
postOrder(visit,t->leftchild);
postOrder(visit,t->rightchild);
visit(t);
}
}
//层次遍历以t为根节点的树
void levelOrder(void(*theVisit) (TreeNode*),TreeNode* t)
{
deque*> q;//队列
//TreeNode *t = root;
while (t != NULL)
{
theVisit(t); // 处理节点t
// 将t的孩纸加入队列
if (t->leftchild != NULL)
q.push_back(t->leftchild);
if (t->rightchild != NULL)
q.push_back(t->rightchild);
// 获得下一个节点
if (q.empty() == 0)
t = q.front();
else
return;
q.pop_front();
}
}
//返回节点t为根节点的树的节点个数,使用层次遍历好写,其他遍历方法也可以实现。。
static int countNodes(TreeNode *t)
{
int count = 0;
deque*> q;//队列
while (t != NULL)
{
count++; // 处理节点t
// 将t的孩纸加入队列
if (t->leftchild != NULL)
q.push_back(t->leftchild);
if (t->rightchild != NULL)
q.push_back(t->rightchild);
// 获得下一个节点
if (q.empty() == 0)
t = q.front();
else
break;
q.pop_front();
}
return count;
}
static void dispose(TreeNode *t) { delete t; }//删除节点t
static void output(TreeNode *t) { cout << t->element << ' '; }//输出节点t
static int height(TreeNode *t)//返回节点t为根节点的树的高度
{
if (t == NULL)
return 0; // 空树
int hl = height(t->leftchild); // 左树高度
int hr = height(t->rightchild); // 右树高度
if (hl > hr)
return ++hl;
else
return ++hr;
}
};
//创建一棵树
template
void binaryTree::makeTree(const T& element, binaryTree& left, binaryTree& right)
{
root = new TreeNode(element, left.root, right.root);
theSize = left.theSize + right.theSize + 1;
left.root = right.root = NULL;
left.theSize = right.theSize = 0;
}
template
binaryTree binaryTree::removeLeftSubtree()
{// 删除左子树
if (theSize == 0)
{
cerr << "The tree is empty"; exit(0);
}
binaryTree leftSubtree;
leftSubtree.root = root->leftchild;
leftSubtree.theSize = countNodes(leftSubtree.root);
//原来的树的左子树为空,theSize改变
root->leftchild = NULL;
theSize -= leftSubtree.theSize;
return leftSubtree;//需要定义复制构造函数
}
template
binaryTree binaryTree::removeRightSubtree()
{// 删除右子树
if (theSize == 0)
{
cerr << "The tree is empty"; exit(0);
}
binaryTree rightSubtree;
rightSubtree.root = root->rightchild;
rightSubtree.theSize = countNodes(rightSubtree.root);
root->rightchild = NULL;
theSize -= rightSubtree.theSize;
return rightSubtree;
}
#include "binaryTree.h"
#include
using namespace std;
void main()
{
binaryTree a, x, y, z;
y.makeTree(1, a, a);
z.makeTree(2, a, a);
x.makeTree(3, y, z);
y.makeTree(4, x, a);
cout << "Number of nodes = ";
cout << y.size() << endl;
cout << "height = ";
cout << y.height() << endl;
cout << "Rootment of The tree is ";
cout << *(y.rootelement()) << endl;
cout << "Preorder sequence is ";
y.preOrderOutput();
cout << "Inorder sequence is ";
y.inOrderOutput();
cout << "Postorder sequence is ";
y.postOrderOutput();
cout << "Level order sequence is ";
y.levelOrderOutput();
(y.find(4) == 1) ? cout << "The tree have 4" : cout << "The tree have not 4";
cout << endl;
cout << "The leftSubtree:";
y.removeLeftSubtree().postOrderOutput();
cout << "The copy of the Tree is ";
binaryTree s = y;
s.levelOrderOutput();
}