二叉樹

1.樹的節點:節點包含數據和指向其它節點的指針,因爲不知道有幾個指向其它節點的指針呢個,所以樹的結構變得難以定義(因爲子節點的個數是未知的),這是可以採用左孩子和右兄弟的表示方法,左孩子可以訪問左子樹的節點,用右子樹可以一直往下訪問它的兄弟節點,這樣就可以實現樹的定義和訪問。

2.二叉樹:對於二叉樹,它只有左子樹和右子樹,所以二叉樹就不難表示,二叉鏈中包含數據,指向左子樹的指針和指向右子樹的指針,三叉鏈中包含數據,指向左子樹的指針,指向右子樹的指針和指向父親節點的指針。

3.二叉樹的遍歷:

         先序:根節點->左子樹節點->右子樹節點

         中根:左子樹節點->根節點->右子樹節點

         後根:左子樹節點->左子樹節點->根節點

#pragma once

#include<iostream>

#include<queue>

using namespace std;

template <typename T>

struct BinaryTreeNode

{

                 BinaryTreeNode<T >* _left;

                 BinaryTreeNode<T >* _right;

                 T _data;

                BinaryTreeNode( const T & data)

                                :_data( data)

                                , _left( NULL)

                                , _right( NULL)

                {

                }

};


template<typename T>

class BinaryTree

{

public:

                BinaryTree()

                                :_root( NULL)

                {

                }

                BinaryTree( const T * a,int size,const T& invalid)

                {

                                 int pos = 0;

                                _root = _CreatBinaryTree( a,pos,size ,invalid);

                }

                ~BinaryTree()

                {

                                 int pos = 0;

                                _DelBinaryTree(_root);

                                cout << endl;

                }

                BinaryTree( const BinaryTree <T>& b)//樹的拷貝構造

                {

                                _root=_CopyBinaryTree( b._root);

                }

                 BinaryTree<T >& operator=(BinaryTree< T> b )

                {

                                swap(_root, b._root);//現代寫法

                                 return *this ;

                }

                 void PrevOrder()//先序遍歷

                {

                                _PrintPrevOrder(_root);

                                cout << endl;


                }

                 void InOrder()//中序遍歷

                {

                                _PrintInOrder(_root);

                                cout << endl;

                }

                 void PostOrder()//後序遍歷

                {

                                _PrintPostOrder(_root);

                                cout << endl;

                }

                 void LevelOrder()//層序遍歷

                {

                                _PrintLevelOrder(_root);

                }

                 size_t Size()

                {

                                 return _Size(_root);

                }

                 size_t Depth()

                {

                                 return _Depth(_root);

                }

                 size_t LeafSize()//葉子節點個數

                {

                                 return _LeafSize(_root);

                }

protected:

                 BinaryTreeNode<T >* _CopyBinaryTree(BinaryTreeNode< T>* root )//複製樹

                {

                                 BinaryTreeNode<T >* newroot = NULL;

                                 if (root == NULL)

                                {

                                                 return NULL ;

                                }

                                newroot = new BinaryTreeNode <T>(root->_data);

                                newroot->_left = _CopyBinaryTree( root->_left);

                                newroot->_right = _CopyBinaryTree( root->_right);

                                 return newroot;

                }

                 int _LeafSize(BinaryTreeNode <T>* root)//樹的葉子節點個數(左子樹葉子節點個數+右子樹葉子節點個數)

                {

                                 if (root ==NULL)

                                {

                                                 return 0;

                                }

                                 else if (root->_left == NULL&&root ->_right == NULL)

                                {

                                                 return 1;

                                }

                                 else

                                {

                                                 return _LeafSize(root ->_left) + _LeafSize(root->_right);

                                }

                }


                 int _Depth(BinaryTreeNode <T>* root)//樹的深度

                {

                                 int leftdepth = 0;

                                 int rightdepth = 0;

                                 if (root == NULL)

                                {

                                                 return 0;

                                }

                                leftdepth = _Depth( root->_left);

                                rightdepth = _Depth( root->_right);

                                 return _Depth(root ->_left) > _Depth(root->_right) ? leftdepth + 1: rightdepth + 1;

                }


                 int _Size(BinaryTreeNode <T>* root)//樹的節點個數

                {

                                 if (root ==NULL)

                                {

                                                 return 0;

                                }

                                 return _Size(root ->_left) + _Size(root->_right) + 1; //左子樹個數+右子樹個數+跟節點

                }


                 void _PrintLevelOrder(BinaryTreeNode <T>* root)//層序遍歷(藉助隊來實現)

                {

                                 queue<BinaryTreeNode <T>*> q;

                                 if (root == NULL)

                                {

                                                 return;

                                }

                                q.push( root);

                                 while (q.size())

                                {

                                                 if (q.front()->_left != NULL )

                                                {

                                                                q.push(q.front()->_left);

                                                }

                                                 if (q.front()->_right != NULL )

                                                {

                                                                q.push(q.front()->_right);

                                                }

                                                cout << q.front()->_data << " " ;

                                                q.pop();

                                }

                }


                 void _PrintPrevOrder(BinaryTreeNode <T>* root)//先序打印

                {

                                 if (root == NULL)

                                {

                                                 return;

                                }

                                cout << root->_data << " " ;

                                _PrintInOrder( root->_left);

                                _PrintInOrder( root->_right);

                }


                 void _PrintInOrder(BinaryTreeNode <T>* root)//中序遍歷

                {

                                 if (root == NULL)

                                {

                                                 return;

                                }

                                _PrintInOrder( root->_left);

                                cout << root->_data << " " ;

                                _PrintInOrder( root->_right);

                }


                 void _PrintPostOrder(BinaryTreeNode <T>* root)//後序遍歷

                {

                                 if (root == NULL)

                                {

                                                 return;

                                }

                                _PrintPostOrder( root->_left);

                                _PrintPostOrder( root->_right);

                                cout << root->_data << " " ;

                }


                 void _DelBinaryTree(BinaryTreeNode <T>* root)//刪除二叉樹

                {

                                 if (root == NULL)

                                {

                                                 return;

                                }

                                 if (root ->_left == NULL&& root->_right == NULL )

                                {

                                                 delete root ;

                                                 return;

                                }

                                _DelBinaryTree( root->_left);

                                _DelBinaryTree( root->_right);

                }


                 BinaryTreeNode<T >* _CreatBinaryTree(const T* a, int& pos,int size, const T& invalid)//創建一個二叉樹

                {

                                 BinaryTreeNode<T >* root=NULL;

                                 if (a [pos] != invalid&&pos <size)

                                {

                                                root = new BinaryTreeNode <T>(a[pos]);

                                                root->_left = _CreatBinaryTree(a , ++pos, size, invalid);

                                                root->_right = _CreatBinaryTree(a ,++pos, size, invalid);

                                }

                                 return root;

                }

private:

                 BinaryTreeNode<T >* _root;

};

/*******************************/

#include"BinaryTree.h"

void test()

{

                 int a1[10] = { 1, 2, 3, '#' , '#', 4, '#', '#' , 5, 6 };

                 BinaryTree<int > b1(a1, 10, '#');//將#封裝,這樣靈活性更強,可以改變

                 //b1.PrevOrder();

                 /*b1.InOrder();

                b1.PostOrder();

                b1.LevelOrder();*/

                 //cout << endl;

                 //cout << b1.Size() << endl;;


                 BinaryTree<int > b2;

                b2 = b1;

                b2.PrevOrder();

                b2.InOrder();

                b2.PostOrder();

                 //cout<<b2.Size()<<endl;

                 //cout<<b2.Depth()<<endl;


                cout << b1.LeafSize() << endl;

}

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章