二叉树
来源:互联网 发布:java 图片服务器搭建 编辑:程序博客网 时间:2024/06/07 08:08
最近在mooc上发现了清华、北大2门数据结构的课程,一直在潜心学习他们的课程,博客没有及时更新,今天刚刚学习了二叉树,趁热打铁,记录下二叉树的学习经历吧,老规矩,还是看代码
二叉树节点类的实现:
- #ifndef BINARY_TREE_NODE_H
- #define BINARY_TREE_NODE_H
- template <typename T> class BinaryTree;
- template <typename T>
- class BinaryTreeNode
- {
- friend class BinaryTree<T>;
- private:
- T data; //二叉树结点数据域
- BinaryTreeNode<T>* left; //二叉树结点指向左子树的指针
- BinaryTreeNode<T>* right; //二叉树结点指向左子树的指针
- public:
- //缺省构造函数
- BinaryTreeNode()
- {
- left = right = nullptr;
- }
- //给定了结点值和左右子树的构造函数
- BinaryTreeNode(T val,BinaryTreeNode<T> *lc = nullptr,BinaryTreeNode<T> *rc = nullptr) : data(val),left(lc),right(rc)
- {
- }
- //返回当前结点的数据
- T value() const
- {
- return this->data;
- }
- //返回当前结点左子树
- BinaryTreeNode<T> * leftChild() const
- {
- return this->left;
- }
- //返回当前结点右子树
- BinaryTreeNode<T> * rightChild() const
- {
- return this->right;
- }
- //设置当前结点的左子树
- void setLeftChild(BinaryTreeNode<T> * lc)
- {
- this->left = lc;
- }
- //设置当前结点的右子树
- void setRightChild(BinaryTreeNode<T> * rc)
- {
- this->right = rc;
- }
- //设置当前结点的数据域
- void setValue(T val)
- {
- this->data = val;
- }
- //判定当前结点是否为叶结点,若是返回true
- bool isLeaf() const
- {
- return (this->left == nullptr) && (this->right == nullptr);
- }
- //重载赋值操作符
- BinaryTreeNode<T>& operator = (const BinaryTreeNode<T>& Node)
- {
- this = Node;
- }
- };
- #endif
二叉树的实现:
- #ifndef BINARY_TREE_H
- #define BINARY_TREE_H
- #include "BinaryTreeNode.h"
- #include <iostream>
- #include <stack>
- #include <queue>
- using std::cout;
- using std::endl;
- using std::stack;
- using std::queue;
- enum Tags{Left,Right}; //枚举类型
- template <class T>
- class StackElement
- { //StackElement
- public:
- BinaryTreeNode<T>* pointer;
- Tags tag;
- };
- template <typename T>
- class BinaryTree
- {
- private:
- BinaryTreeNode<T> *root;
- public:
- BinaryTree(BinaryTreeNode<T> *r = nullptr)
- {
- root = r;
- }
- ~BinaryTree()
- {
- deleteBinaryTree(root);
- }
- //以后序周游的方式删除二叉树
- void deleteBinaryTree(BinaryTreeNode<T> *r)
- {
- if(r)
- {
- deleteBinaryTree(r->left);
- deleteBinaryTree(r->right);
- delete r;
- }
- }
- //判定二叉树是否为空树
- bool isEmpty() const
- {
- return this->root == nullptr;
- }
- //返回二叉树根结点
- BinaryTreeNode<T>* getRoot()
- {
- return root;
- }
- //构造一棵以info为根、leftTree和rightTree为左右子树的新二叉树
- void createTree(const T& info, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree)
- {
- root = new BinaryTreeNode<T>(info,leftTree.root,rightTree.root);
- leftTree.root = rightTree.root = nullptr;
- }
- void visit(BinaryTreeNode<T> *node)
- {
- cout << node->value() << "\t";;
- }
- //前序周游二叉树
- void preOrder (BinaryTreeNode<T> *root)
- {
- if(root)
- {
- visit(root);
- preOrder(root->leftChild());
- preOrder(root->rightChild());
- }
- }
- //前序周游二叉树without递归
- void preOrderWithoutRecursion(BinaryTreeNode<T> *root)
- {
- stack<BinaryTreeNode<T> * > aStack;
- BinaryTreeNode<T> *point = root;
- while(!aStack.empty() || point)
- {
- if(point)
- {
- visit(point); //访问当前结点
- aStack.push(point);//当前结点地址入栈,为了便于查找右孩子
- point = point->leftChild();//当前链接结构指向左孩子
- }
- else //左子树访问完毕,转向访问右子树
- {
- point = aStack.top();//栈顶元素退栈
- aStack.pop();
- point = point->rightChild();//当前链接结构指向右孩子
- }
- }
- }
- //中序周游二叉树
- void inOrder (BinaryTreeNode<T> *root)
- {
- if(root)
- {
- inOrder(root->leftChild());
- visit(root);
- inOrder(root->rightChild());
- }
- }
- //中序周游二叉树without递归
- void inOrderWithoutRecursion(BinaryTreeNode<T> *root)
- {
- stack<BinaryTreeNode<T> * > aStack;
- BinaryTreeNode<T> *point = root;
- while(!aStack.empty() || point)
- {
- if(point)
- {
- aStack.push(point);//当前结点地址入栈
- point = point->leftChild();//当前链接结构指向左孩子
- }
- else //左子树访问完毕,转向访问右子树
- {
- point = aStack.top();//栈顶元素退栈
- aStack.pop();
- visit(point); //访问当前结点
- point = point->rightChild();//当前链接结构指向右孩子
- }
- }
- }
- //后序周游二叉树
- void postOrder (BinaryTreeNode<T> *root)
- {
- if(root)
- {
- postOrder(root->leftChild());
- postOrder(root->rightChild());
- visit(root);
- }
- }
- //后序周游二叉树without递归
- void postOrderWithoutRecursion(BinaryTreeNode<T> *root)
- {
- StackElement<T> element;
- stack<StackElement<T> > aStack;
- BinaryTreeNode<T> *point;
- if(root == nullptr)
- {
- return ;
- }
- else
- {
- point = root;
- }
- while(!aStack.empty() || point)
- {
- while(point)
- {
- element.pointer = point;
- element.tag = Left;
- aStack.push(element);
- point = point->leftChild();//沿左子树方向向下周游
- }
- element = aStack.top();
- aStack.pop();//托出栈顶元素
- point = element.pointer;
- if(element.tag == Left)
- {
- //从左子树回来
- element.tag = Right;
- aStack.push(element);
- point = point->rightChild();
- }
- else
- {
- //从右子树回来
- visit(point); //访问当前结点
- point = nullptr;
- }
- }
- }
- //按层次周游二叉树或其子树
- void LevelOrder(BinaryTreeNode<T>* root)
- {
- queue<BinaryTreeNode<T> * > aQueue;
- BinaryTreeNode<T> *point = root;
- if(point)
- {
- aQueue.push(point);//根结点入队列
- }
- while(!aQueue.empty())//队列非空
- {
- point = aQueue.front();//取队列首结点
- aQueue.pop();//当前结点出队列
- visit(point);//访问当前结点
- if(point->leftChild() != nullptr)
- {
- aQueue.push(point->leftChild());//左子树进队列
- }
- if(point->rightChild() != nullptr)
- {
- aQueue.push(point->rightChild());//右子树进队列
- }
- }
- }
- };
- #endif
测试代码
- #include "BinaryTree.h"
- #include <iostream>
- int main()
- {
- //建一棵树(如图5.5所示)
- BinaryTree<char> a, b, c, d, e, f, g, h, i,nulltree;
- d.createTree('D', nulltree, nulltree);
- g.createTree('G', nulltree, nulltree);
- h.createTree('H', nulltree, nulltree);
- i.createTree('I', nulltree, nulltree);
- f.createTree('F', h, i);
- e.createTree('E', g, nulltree);
- b.createTree('B', d, e);
- c.createTree('C', nulltree, f);
- a.createTree('A', b, c);
- //前序周游二叉树
- cout << "Preorder sequence is: "<<endl;
- a.preOrder(a.getRoot()); //递归
- cout << endl;
- cout << "Preorder sequence Without Recursion is: " <<endl;
- a.preOrderWithoutRecursion(a.getRoot());//非递归
- cout << endl;
- //中序周游二叉树
- cout << "Inorder sequence is: "<<endl;
- a.inOrder(a.getRoot()); //递归
- cout << endl;
- cout << "Inorder sequence Without Recursion is: " <<endl;
- a.inOrderWithoutRecursion(a.getRoot());//非递归
- cout << endl;
- //后序周游二叉树
- cout << "Postorder sequence is: "<<endl;
- a.postOrder(a.getRoot()); //递归
- cout << endl;
- cout << "Postorder sequence Without Recursion is: " <<endl;
- a.postOrderWithoutRecursion(a.getRoot());//非递归
- cout << endl;
- cout << "Levelorder sequence Without Recursion is: " <<endl;
- a.LevelOrder(a.getRoot());//非递归
- cout << endl;
- //root
- cout << "Root is: " << a.getRoot()->value() <<endl;
- /* //delete tree
- a.deleteBinaryTree(a.getRoot());
- cout<<"Tree is deleted."<<endl; //没有问题,在析构函数中调用
- */
- system("pause");
- return 0;
- }
0 0