二叉樹層次周遊和深度周遊
源碼實作過程:
#include <stdio.h>
#include <QUEUE> //必須使用的是QUEUE,和using namespace std,缺一不可;
#include <STACK>
using namespace std;
typedef char DataType;
typedef struct Node {
DataType elem;
Node * rChild;
Node * lChild;
}NODE,*pNode;
queue<pNode> Q;
bool creat(pNode &root){
DataType temp;
scanf("%c",&temp);
if (temp==EOF)
{
return false;
}else if(temp=='#')
{
root = NULL;
}else{
root = (pNode )malloc(sizeof(Node));
root->elem=temp;
creat(root->lChild);
creat(root->rChild);
}
return true;
}
void preOrder(pNode root){
if (root!=NULL)
{
printf("%c ",root->elem);
if (root->lChild)
{
preOrder(root->lChild);
}
if (root->rChild)
{
preOrder(root->rChild);
}
}
}
void inOrder(pNode root){
if (root!=NULL)
{
if (root->lChild)
{
inOrder(root->lChild);
}
printf("%c ",root->elem);
if (root->rChild)
{
inOrder(root->rChild);
}
}
}
//這是錯誤的,原因是使用了遞歸,将所有節點都加入到了隊列中,再開始出隊。造成了有重複的節點加入。
void level_print(pNode &root){
if (root != NULL)
{
// printf("%c",root->elem);
if (Q.empty())//放入第一個節點
{
Q.push(root);
}
if (root->lChild)
{
Q.push(root->lChild);
}
if (root->rChild)
{
Q.push(root->rChild);
}
if (root->lChild)
{
level_print(root->lChild);
}
if (root->rChild)
{
level_print(root->rChild);
}
}
while(!Q.empty())
{
pNode temp = Q.front();
printf("%c ",temp->elem);
Q.pop();
}
}
//這個算法是成功的實作了樹的層次周遊
void level_print2(pNode root){
while (!Q.empty())//清空隊列
{
Q.pop();
}
if (root)//先使根節點入隊
{
Q.push(root);
}
do
{
pNode temp;
temp = Q.front();
printf("%c ",temp->elem);
Q.pop();
if (temp->lChild)//如果左子樹不為空,将左子樹入隊
{
Q.push(temp->lChild);
}
if (temp->rChild)//如果右子樹不為空,将右子樹入隊
{
Q.push(temp->rChild);
}
}while (!Q.empty());
}
// 如果要實作按層列印數的話,還是修改樹的層次周遊,注意的是要統計樹中每層的個數
void level_print3(pNode root){
int parentSize=1;
int childSize=0;
// 1.清空樹;
while (!Q.empty())
{
Q.pop();
}
// 2.将樹分層次加入到隊列中
Q.push(root);
do
{
pNode temp = Q.front();
printf("%c ",temp->elem);
Q.pop();
parentSize--;
if (temp->lChild)
{
Q.push(temp->lChild);
childSize++;
}
if (temp->rChild)
{
Q.push(temp->rChild);
childSize++;
}
if (parentSize==0)
{
parentSize=childSize;
childSize=0;
printf("\n");
}
} while (!Q.empty());
}
// 因為深度優先周遊,周遊了根節點後,就開始周遊左子樹,
// 是以右子樹肯定最後周遊。我們利用棧的性質,先将右子
// 樹壓棧,然後在對左子樹壓棧。此時,左子樹節點是在top上的,
// 是以可以先去周遊左子樹。
void DepthFirstTravel(pNode root){
stack<pNode> S;
if (root)
{
S.push(root);
}
while (!S.empty())
{
pNode temp = S.top();
printf("%c ",temp->elem);
S.pop();
if (temp->rChild)
{
S.push(temp->rChild);
}
if (temp->lChild)
{
S.push(temp->lChild);
}
}
}
int main(){
pNode T;
creat(T);
printf("preOrder:");
preOrder(T);
printf("\n");
printf("inOrder:");
inOrder(T);
printf("\n");
printf("level_travel is :\n");
level_print2(T);
printf("\n");
printf("level_travel is :\n");
level_print3(T);
printf("\n");
printf("DepthFirstTravel is :\n");
DepthFirstTravel(T);
printf("\n");
// queue<int> q;
// q.push(1);
// q.push(2);
// q.push(3);
// q.push(4);
// while(!q.empty()){
// printf("%d ",q.front());
// q.pop();
// }
// printf("\n");
return 0;
}