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;
}