C++實現二叉樹的順序儲存及三種遞迴遍歷
阿新 • • 發佈:2021-02-19
文章目錄
#include<iostream>
#include<stack>
#include<queue>
#include<string.h>
using namespace std;
#define MaxSize 101
class BinTree
{
public:
BinTree();
void CreatTree(); //生成二叉樹
void PreOrderTraverse1(int i=1); //先序遞迴遍歷
void InOrderTraverse1 (int i=1); //中序遞迴遍歷
void PostOrderTraverse1(int i=1); //後序遞迴遍歷
void LevelOrder(); //層次遍歷
void Visit(int i); //輸出第i個位置的資料
int Depth(int i=1); //獲得二叉樹深度
int NodeCount(int i=1); //獲得結點個數
int LeafCount(int i=1); //獲得葉子結點個數
~BinTree();
private:
int* list; //結點儲存的資料為整形數
int size; //記錄結點的個數
};
BinTree::BinTree()
{
list = new int[MaxSize];
memset(list,0,MaxSize);
}
void BinTree::CreatTree() //生成二叉樹
{
int n = 0;
cout << "請輸入結點個數:";
cin >> n;
if(n<=0)
{
cout << "結點數不能小於1" << endl;
return;
}
while(n>MaxSize)
{
cout << "最大結點數為:" << MaxSize << endl;
cout << "請輸入結點個數:";
cin >> n;
}
size = n;
cout << "請輸入每個結點的資料:";
for(int i=0; i<n; ++i)
{
cin >> list[i];
}
}
void BinTree::PreOrderTraverse1(int i) //先序遞迴遍歷
{
if(!size)
{
return;
}
else
{
if(list[i-1]!=0)
{
Visit(i);
PreOrderTraverse1(2*i);
PreOrderTraverse1(2*i+1);
}
else
{
return;
}
}
}
void BinTree::InOrderTraverse1(int i) //中序遞迴遍歷
{
if(!size)
{
return;
}
else
{
if(list[i-1]!=0)
{
InOrderTraverse1(2*i);
Visit(i);
InOrderTraverse1(2*i+1);
}
else
{
return;
}
}
}
void BinTree::PostOrderTraverse1(int i) //後序遞迴遍歷
{
if(!size)
{
return;
}
else
{
if(list[i-1]!=0)
{
PostOrderTraverse1(2*i);
PostOrderTraverse1(2*i+1);
Visit(i);
}
else
{
return;
}
}
}
void BinTree::LevelOrder() //層次遍歷
{
if(!size)
{
return;
}
else
{
queue<int> q;
int i = 1;
q.push(i);
while(!q.empty())
{
if(list[q.front()-1]!=0) //如果隊頭結點的資料域不為0,說明該結點在二叉樹中
{
i = q.front();
q.push(2*i);
q.push(2*i+1); //將隊頭結點的左右結點入隊
Visit(i);
q.pop();
}
else
{
q.pop();
}
}
}
}
void BinTree::Visit(int i) //輸出第i個位置的資料
{
if(list[i-1]!=0)
{
cout << list[i-1] << " ";
}
}
int BinTree::Depth(int i) //獲得二叉樹深度
{
if(!size)
{
return 0;
}
else
{
if(list[i-1]==0)
{
return 0;
}
else
{
int m = Depth(2*i);
int n = Depth(2*i+1);
return m>n?(m+1):(n+1);
}
}
}
int BinTree::NodeCount(int i) //獲得結點個數
{
if(!size)
{
return 0;
}
else
{
if(list[i-1]==0)
{
return 0;
}
else
{
return NodeCount(2*i) + NodeCount(2*i+1) + 1; //返回左子樹的結點個數+右子樹的結點個數+1
}
}
}
int BinTree::LeafCount(int i) //獲得葉子結點個數
{
if(!size)
{
return 0;
}
else
{
if(list[2*i-1]==0&&list[2*i]==0)
{
return 1;
}
else
{
if(list[2*i-1]!=0&&list[2*i]==0)
{
return LeafCount(2*i);
}
else if(list[2*i]!=0&&list[2*i-1]==0)
{
return LeafCount(2*i+1);
}
else
{
return LeafCount(2*i) + LeafCount(2*i+1);
}
}
}
}
BinTree::~BinTree()
{
delete[] list;
}
int main()
{
BinTree bt;
bt.CreatTree();
cout << "先序遞迴遍歷:";bt.PreOrderTraverse1();
cout << endl;
cout << "中序遞迴遍歷:";bt.InOrderTraverse1();
cout << endl;
cout << "後序遞迴遍歷:";bt.PostOrderTraverse1();
cout << endl;
cout << "層次遍歷:";bt.LevelOrder();
cout << endl;
cout << "深度:" << bt.Depth();
cout << endl;
cout << "葉子結點數:" << bt.LeafCount();
cout << endl;
cout << "結點數:" << bt.NodeCount();
cout << endl;
}
測試結果: