数据结构学习笔记(五)二叉树及其C++实现

来源:互联网 发布:知乎那些曾经轰动一时 编辑:程序博客网 时间:2024/05/29 04:27

一、树的基本概念

          树是一种层次结构,表达一对多的关系

          树的节点:包含数据元素,还有指向其他节点的指针:孩纸指针,父节点指针

叶子节点,根节点,孩纸节点,双亲节点,兄弟节点,堂兄弟节点,祖先节点,子孙节点

          节点的度:节点分支的个数

          树的度:所有节点的度的最大值

          树的路径:根节点到该节点上的所有节点连接起来的

          层次:从根节点开始定义,根为第一层,根的孩纸为第二层,若节点中在第k层,其子树的根在第k+1层

          树的深度(高度):树种节点的最大层次

          有序树:树中节点的各个子树从左到右看做是有次序的

          森林:即m个互不相交的树的集合

          树的基本操作:求根节点,求双亲节点,求孩纸节点,建立一棵树,销毁一棵树等


二、二叉树

           二叉树是每一个节点最多有两个子树的特殊的树,即树的度为2。二叉树是有序树,有左右子树之分。二叉树比较特殊的有完全二叉树、满二叉树,二叉平衡树等等。如下图所示:


            二叉树的操作:新建树,销毁树,前序遍历,中序遍历,后续遍历,层次遍历,查找节点,树的高度,节点个数。。。。。。。。。

            二叉树的性质:


                   二叉树在实现过程中,使用链表结构比较方便,下面给出二叉树的C++实现:

三、二叉树的C++实现

#pragma once//#include"arrayQueue.h"//使用标准库的队列#include<deque>#include<iostream>using namespace std;//节点结构template<class T>struct TreeNode{T element;//元素TreeNode<T>* leftchild;//左孩子TreeNode<T>* rightchild;//右孩子TreeNode(){ leftchild = rightchild = NULL;}TreeNode(const T& theElement){ element = theElement; leftchild = rightchild = NULL; }TreeNode(const T& theElement, TreeNode<T>* left, TreeNode<T>* right){ element = theElement; leftchild = left; rightchild = right;}};//二叉树template<class T>class binaryTree{public://构造函数,复制构造函数和析构函数binaryTree(){ root = NULL; theSize = 0; }//构造一个空树~binaryTree(){ erase(); }//析构,通过调用erase函数删除所有节点binaryTree(const binaryTree<T> &thebinaryTree)//复制构造函数{theSize = thebinaryTree.theSize;if (theSize==0)//如果树为空{root = NULL;return;}//树不为空,挨个节点复制deque<TreeNode<T>*> q, p;//队列q存放原来的树的节点,p存放新建的树的节点TreeNode<T>* sourceNode = thebinaryTree.root;root = new TreeNode<T>(sourceNode->element);TreeNode<T>* targetNode = root;q.push_back(sourceNode);p.push_back(targetNode);//将sourceNode复制到targetNodewhile (q.empty()==0){sourceNode = q.front();targetNode = p.front();if (sourceNode->leftchild != NULL){q.push_back(sourceNode->leftchild);targetNode->leftchild = new TreeNode<T>(sourceNode->leftchild->element);p.push_back(targetNode->leftchild);}if (sourceNode->rightchild != NULL){q.push_back(sourceNode->rightchild);targetNode->rightchild = new TreeNode<T>(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<T>& left, binaryTree<T>& right);//建造一个树binaryTree<T> removeLeftSubtree();//移除左子树binaryTree<T> removeRightSubtree();//移除右子树//整个树的前序遍历,形参表示一个函数用来处理遍历的当前节点,theVist是函数地址,返回值是void,其参数是TreeNode<T>*void preOrder(void(*theVisit) (TreeNode<T>*))   { preOrder(theVisit, root); }//整个树的中序遍历,void inOrder(void (*theVisit) (TreeNode<T>*)){ inOrder(theVisit,root);}//整个树的后序遍历,void postOrder(void (*theVisit) (TreeNode<T>*)){ postOrder(theVisit,root);}//整个树的层次遍历void levelOrder(void(*theVisit) (TreeNode<T>*)) { 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<TreeNode<T>*> q;//队列TreeNode<T> *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();elsebreak;q.pop_front();}return false;}protected:TreeNode<T>* root;//指向根节点的指针int theSize;//树的元素个数//前序遍历以t为根节点的树,参数visit是对节点的处理函数,static void preOrder(void(*visit) (TreeNode<T>*), TreeNode<T> *t){if (t != NULL){visit(t);preOrder(visit,t->leftchild);preOrder(visit,t->rightchild);}}//中序遍历以t为根节点的树,参数visit是对节点的处理函数,static void inOrder(void(*visit) (TreeNode<T>*), TreeNode<T> *t){if (t != NULL){inOrder(visit,t->leftchild);visit(t);inOrder(visit,t->rightchild);}}//后序遍历以t为根节点的树,参数visit是对节点的处理函数,static void postOrder(void(*visit) (TreeNode<T>*), TreeNode<T> *t){if (t != NULL){postOrder(visit,t->leftchild);postOrder(visit,t->rightchild);visit(t);}}//层次遍历以t为根节点的树void levelOrder(void(*theVisit) (TreeNode<T>*),TreeNode<T>* t){deque<TreeNode<T>*> q;//队列//TreeNode<T> *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();elsereturn;q.pop_front();}}//返回节点t为根节点的树的节点个数,使用层次遍历好写,其他遍历方法也可以实现。。static int countNodes(TreeNode<T> *t){int count = 0;deque<TreeNode<T>*> 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();elsebreak;q.pop_front();}return count;}static void dispose(TreeNode<T> *t) { delete t; }//删除节点tstatic void output(TreeNode<T> *t){ cout << t->element << ' ';}//输出节点tstatic int height(TreeNode<T> *t)//返回节点t为根节点的树的高度{if (t == NULL)return 0;                    // 空树int hl = height(t->leftchild);  // 左树高度int hr = height(t->rightchild); // 右树高度if (hl > hr)return ++hl;elsereturn ++hr;}};//创建一棵树template<class T>void binaryTree<T>::makeTree(const T& element, binaryTree<T>& left, binaryTree<T>& right){root = new TreeNode<T>(element, left.root, right.root);theSize = left.theSize + right.theSize + 1;left.root = right.root = NULL;left.theSize = right.theSize = 0;}template<class T>binaryTree<T> binaryTree<T>::removeLeftSubtree(){// 删除左子树if (theSize == 0){cerr << "The tree is empty"; exit(0);}binaryTree<T> leftSubtree;leftSubtree.root = root->leftchild;leftSubtree.theSize = countNodes(leftSubtree.root);//原来的树的左子树为空,theSize改变root->leftchild = NULL;theSize -= leftSubtree.theSize;return leftSubtree;//需要定义复制构造函数}template<class T>binaryTree<T> binaryTree<T>::removeRightSubtree(){// 删除右子树if (theSize == 0){cerr << "The tree is empty"; exit(0);}binaryTree<T> rightSubtree;rightSubtree.root = root->rightchild;rightSubtree.theSize = countNodes(rightSubtree.root);root->rightchild = NULL;theSize -= rightSubtree.theSize;return rightSubtree;}

测试代码:

#include "binaryTree.h"#include<iostream>using namespace std;void main(){binaryTree<int> 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<int> s = y;s.levelOrderOutput();}


0 0
原创粉丝点击