二叉树

来源:互联网 发布:java 图片服务器搭建 编辑:程序博客网 时间:2024/06/07 08:08

最近在mooc上发现了清华、北大2门数据结构的课程,一直在潜心学习他们的课程,博客没有及时更新,今天刚刚学习了二叉树,趁热打铁,记录下二叉树的学习经历吧,老规矩,还是看代码

二叉树节点类的实现:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #ifndef BINARY_TREE_NODE_H  
  2. #define BINARY_TREE_NODE_H  
  3.   
  4. template <typename T> class BinaryTree;  
  5.   
  6. template <typename T>  
  7. class BinaryTreeNode  
  8. {  
  9. friend class BinaryTree<T>;  
  10. private:  
  11.     T  data;                                //二叉树结点数据域  
  12.     BinaryTreeNode<T>* left;              //二叉树结点指向左子树的指针  
  13.     BinaryTreeNode<T>* right;             //二叉树结点指向左子树的指针  
  14.   
  15. public:  
  16.     //缺省构造函数  
  17.     BinaryTreeNode()      
  18.     {  
  19.         left = right = nullptr;  
  20.     }  
  21.   
  22.     //给定了结点值和左右子树的构造函数  
  23.     BinaryTreeNode(T val,BinaryTreeNode<T> *lc = nullptr,BinaryTreeNode<T> *rc = nullptr) : data(val),left(lc),right(rc)  
  24.     {  
  25.   
  26.     }  
  27.   
  28.     //返回当前结点的数据  
  29.     T value() const  
  30.     {  
  31.         return this->data;  
  32.     }  
  33.     //返回当前结点左子树  
  34.     BinaryTreeNode<T> * leftChild() const   
  35.     {  
  36.         return this->left;  
  37.     }  
  38.   
  39.     //返回当前结点右子树  
  40.     BinaryTreeNode<T> * rightChild() const  
  41.     {  
  42.         return this->right;  
  43.     }  
  44.   
  45.     //设置当前结点的左子树  
  46.     void setLeftChild(BinaryTreeNode<T> * lc)  
  47.     {  
  48.         this->left = lc;  
  49.     }  
  50.   
  51.     //设置当前结点的右子树  
  52.     void setRightChild(BinaryTreeNode<T> * rc)  
  53.     {  
  54.         this->right = rc;  
  55.     }  
  56.   
  57.     //设置当前结点的数据域  
  58.     void setValue(T val)  
  59.     {  
  60.         this->data = val;  
  61.     }  
  62.   
  63.     //判定当前结点是否为叶结点,若是返回true  
  64.     bool isLeaf() const  
  65.     {  
  66.         return (this->left == nullptr) && (this->right == nullptr);  
  67.     }  
  68.   
  69.     //重载赋值操作符  
  70.     BinaryTreeNode<T>& operator = (const BinaryTreeNode<T>& Node)  
  71.     {  
  72.         this = Node;  
  73.     }  
  74.   
  75. };  
  76.   
  77.   
  78. #endif  

二叉树的实现:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #ifndef BINARY_TREE_H  
  2. #define BINARY_TREE_H  
  3.   
  4. #include "BinaryTreeNode.h"  
  5. #include <iostream>  
  6. #include <stack>  
  7. #include <queue>  
  8. using std::cout;  
  9. using std::endl;  
  10. using std::stack;  
  11. using std::queue;  
  12.   
  13.   
  14. enum Tags{Left,Right};    //枚举类型  
  15.   
  16. template <class T>  
  17. class StackElement    
  18. {         //StackElement  
  19. public:  
  20.     BinaryTreeNode<T>* pointer;  
  21.     Tags tag;  
  22. };    
  23.   
  24. template <typename T>  
  25. class BinaryTree  
  26. {  
  27. private:  
  28.     BinaryTreeNode<T> *root;  
  29.   
  30. public:  
  31.     BinaryTree(BinaryTreeNode<T> *r = nullptr)  
  32.     {  
  33.         root = r;  
  34.     }  
  35.   
  36.     ~BinaryTree()  
  37.     {  
  38.         deleteBinaryTree(root);  
  39.     }  
  40.   
  41.     //以后序周游的方式删除二叉树  
  42.     void deleteBinaryTree(BinaryTreeNode<T> *r)  
  43.     {  
  44.         if(r)  
  45.         {  
  46.             deleteBinaryTree(r->left);  
  47.             deleteBinaryTree(r->right);  
  48.             delete r;  
  49.         }  
  50.     }  
  51.   
  52.     //判定二叉树是否为空树  
  53.     bool isEmpty() const  
  54.     {  
  55.         return this->root == nullptr;  
  56.     }  
  57.   
  58.     //返回二叉树根结点  
  59.     BinaryTreeNode<T>* getRoot()  
  60.     {  
  61.         return root;  
  62.     }  
  63.   
  64.       
  65.     //构造一棵以info为根、leftTree和rightTree为左右子树的新二叉树  
  66.     void createTree(const T& info, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree)  
  67.     {  
  68.         root = new BinaryTreeNode<T>(info,leftTree.root,rightTree.root);  
  69.         leftTree.root = rightTree.root = nullptr;  
  70.     }  
  71.   
  72.   
  73.     void visit(BinaryTreeNode<T> *node)  
  74.     {  
  75.         cout << node->value() << "\t";;  
  76.     }  
  77.   
  78.     //前序周游二叉树  
  79.     void preOrder (BinaryTreeNode<T> *root)  
  80.     {    
  81.         if(root)  
  82.         {  
  83.             visit(root);  
  84.             preOrder(root->leftChild());  
  85.             preOrder(root->rightChild());  
  86.         }  
  87.     }  
  88.   
  89.     //前序周游二叉树without递归  
  90.     void preOrderWithoutRecursion(BinaryTreeNode<T> *root)  
  91.     {  
  92.         stack<BinaryTreeNode<T> * > aStack;  
  93.         BinaryTreeNode<T> *point = root;  
  94.         while(!aStack.empty() || point)  
  95.         {  
  96.             if(point)  
  97.             {  
  98.                 visit(point); //访问当前结点  
  99.                 aStack.push(point);//当前结点地址入栈,为了便于查找右孩子  
  100.                 point = point->leftChild();//当前链接结构指向左孩子  
  101.             }  
  102.             else //左子树访问完毕,转向访问右子树  
  103.   
  104.             {  
  105.                 point = aStack.top();//栈顶元素退栈    
  106.                 aStack.pop();  
  107.                 point = point->rightChild();//当前链接结构指向右孩子  
  108.             }  
  109.         }  
  110.     }  
  111.   
  112.     //中序周游二叉树  
  113.     void inOrder (BinaryTreeNode<T> *root)  
  114.     {    
  115.         if(root)  
  116.         {  
  117.             inOrder(root->leftChild());  
  118.             visit(root);  
  119.             inOrder(root->rightChild());  
  120.         }  
  121.     }  
  122.   
  123.     //中序周游二叉树without递归  
  124.     void inOrderWithoutRecursion(BinaryTreeNode<T> *root)  
  125.     {  
  126.         stack<BinaryTreeNode<T> * > aStack;  
  127.         BinaryTreeNode<T> *point = root;  
  128.         while(!aStack.empty() || point)  
  129.         {  
  130.             if(point)  
  131.             {  
  132.                 aStack.push(point);//当前结点地址入栈  
  133.                 point = point->leftChild();//当前链接结构指向左孩子  
  134.             }  
  135.             else //左子树访问完毕,转向访问右子树  
  136.   
  137.             {  
  138.                 point = aStack.top();//栈顶元素退栈    
  139.                 aStack.pop();  
  140.                 visit(point); //访问当前结点  
  141.                 point = point->rightChild();//当前链接结构指向右孩子  
  142.             }  
  143.         }  
  144.     }  
  145.   
  146.     //后序周游二叉树  
  147.     void postOrder (BinaryTreeNode<T> *root)  
  148.     {    
  149.         if(root)  
  150.         {  
  151.             postOrder(root->leftChild());  
  152.             postOrder(root->rightChild());  
  153.             visit(root);  
  154.         }  
  155.     }  
  156.   
  157.     //后序周游二叉树without递归  
  158.     void postOrderWithoutRecursion(BinaryTreeNode<T> *root)  
  159.     {    
  160.         StackElement<T> element;  
  161.         stack<StackElement<T> > aStack;  
  162.         BinaryTreeNode<T> *point;  
  163.           
  164.         if(root == nullptr)  
  165.         {  
  166.             return ;  
  167.         }  
  168.         else  
  169.         {  
  170.             point = root;  
  171.         }  
  172.   
  173.         while(!aStack.empty() || point)  
  174.         {  
  175.             while(point)  
  176.             {  
  177.                 element.pointer = point;  
  178.                 element.tag = Left;  
  179.                 aStack.push(element);  
  180.                 point = point->leftChild();//沿左子树方向向下周游  
  181.             }  
  182.   
  183.             element = aStack.top();  
  184.             aStack.pop();//托出栈顶元素  
  185.             point = element.pointer;  
  186.   
  187.             if(element.tag == Left)  
  188.             {  
  189.                 //从左子树回来  
  190.                 element.tag = Right;  
  191.                 aStack.push(element);  
  192.                 point = point->rightChild();  
  193.             }  
  194.             else  
  195.             {  
  196.                 //从右子树回来  
  197.                 visit(point); //访问当前结点  
  198.                 point = nullptr;  
  199.             }  
  200.         }  
  201.     }  
  202.   
  203.     //按层次周游二叉树或其子树  
  204.     void LevelOrder(BinaryTreeNode<T>* root)  
  205.     {  
  206.         queue<BinaryTreeNode<T> * > aQueue;  
  207.         BinaryTreeNode<T> *point = root;  
  208.         if(point)  
  209.         {  
  210.             aQueue.push(point);//根结点入队列  
  211.         }  
  212.   
  213.         while(!aQueue.empty())//队列非空  
  214.         {  
  215.             point = aQueue.front();//取队列首结点  
  216.             aQueue.pop();//当前结点出队列  
  217.             visit(point);//访问当前结点  
  218.   
  219.             if(point->leftChild() != nullptr)  
  220.             {  
  221.                 aQueue.push(point->leftChild());//左子树进队列  
  222.             }  
  223.   
  224.             if(point->rightChild() != nullptr)  
  225.             {  
  226.                 aQueue.push(point->rightChild());//右子树进队列  
  227.             }  
  228.         }  
  229.     }  
  230.           
  231.   
  232. };  
  233.   
  234.   
  235. #endif  


测试代码

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include "BinaryTree.h"  
  2. #include <iostream>  
  3.   
  4.   
  5. int main()  
  6. {  
  7.     //建一棵树(如图5.5所示)  
  8.     BinaryTree<char> a, b, c, d, e, f, g, h, i,nulltree;  
  9.     d.createTree('D', nulltree, nulltree);  
  10.     g.createTree('G', nulltree, nulltree);  
  11.     h.createTree('H', nulltree, nulltree);  
  12.     i.createTree('I', nulltree, nulltree);  
  13.     f.createTree('F', h, i);  
  14.     e.createTree('E', g, nulltree);  
  15.     b.createTree('B', d, e);  
  16.     c.createTree('C', nulltree, f);  
  17.     a.createTree('A', b, c);  
  18.   
  19.     //前序周游二叉树  
  20.     cout << "Preorder sequence is: "<<endl;  
  21.     a.preOrder(a.getRoot());                //递归  
  22.     cout << endl;  
  23.     cout << "Preorder sequence Without Recursion is: " <<endl;  
  24.     a.preOrderWithoutRecursion(a.getRoot());//非递归  
  25.     cout << endl;  
  26.   
  27.     //中序周游二叉树  
  28.     cout << "Inorder sequence is: "<<endl;  
  29.     a.inOrder(a.getRoot());         //递归  
  30.     cout << endl;  
  31.     cout << "Inorder sequence Without Recursion is: " <<endl;  
  32.     a.inOrderWithoutRecursion(a.getRoot());//非递归  
  33.     cout << endl;  
  34.       
  35.   
  36.     //后序周游二叉树  
  37.     cout << "Postorder sequence is: "<<endl;  
  38.     a.postOrder(a.getRoot());           //递归  
  39.     cout << endl;  
  40.     cout << "Postorder sequence Without Recursion is: " <<endl;  
  41.     a.postOrderWithoutRecursion(a.getRoot());//非递归    
  42.     cout << endl;   
  43.   
  44.     cout << "Levelorder sequence Without Recursion is: " <<endl;  
  45.     a.LevelOrder(a.getRoot());//非递归   
  46.     cout << endl;   
  47.   
  48.       
  49.   
  50.     //root  
  51.     cout << "Root is: " << a.getRoot()->value() <<endl;  
  52.   
  53.     /*  //delete tree 
  54.     a.deleteBinaryTree(a.getRoot()); 
  55.     cout<<"Tree is deleted."<<endl;        //没有问题,在析构函数中调用 
  56.     */  
  57.   
  58.   
  59.   
  60.     system("pause");  
  61.     return 0;  
  62. }  

0 0