//轉載請標明出處,原文地址:http://blog.csdn.net/hackbuteer1/article/details/6583988
#include
#include
#include
usingnamespacestd;
//二叉樹結點的描述
typedefstructBiTNode
{
chardata;
structBiTNode?*lchild,?*rchild;//左右孩子
}BiTNode,*BiTree;
//按先序遍歷創建二叉樹
//BiTree?*CreateBiTree()?????//返回結點指針類型
//void?CreateBiTree(BiTree?&root)??????//引用類型的參數
voidCreateBiTree(BiTNode?**root)//二級指針作為函數參數
{
charch;//要插入的數據
scanf("\n%c",?&ch);
//cin>>ch;
if(ch=='#')
*root?=?NULL;
else
{
*root?=?(BiTNode?*)malloc(sizeof(BiTNode));
(*root)->data?=?ch;
printf("請輸入%c的左孩子:",ch);
CreateBiTree(&((*root)->lchild));
printf("請輸入%c的右孩子:",ch);
CreateBiTree(&((*root)->rchild));
}
}
//前序遍歷的算法程序
voidPreOrder(BiTNode?*root)
{
if(root==NULL)
return;
printf("%c?",?root->data);//輸出數據
PreOrder(root->lchild);//遞歸調用,前序遍歷左子樹
PreOrder(root->rchild);//遞歸調用,前序遍歷右子樹
}
//中序遍歷的算法程序
voidInOrder(BiTNode?*root)
{
if(root==NULL)
return;
InOrder(root->lchild);//遞歸調用,前序遍歷左子樹
printf("%c?",?root->data);//輸出數據
InOrder(root->rchild);//遞歸調用,前序遍歷右子樹
}
//后序遍歷的算法程序
voidPostOrder(BiTNode?*root)
{
if(root==NULL)
return;
PostOrder(root->lchild);//遞歸調用,前序遍歷左子樹
PostOrder(root->rchild);//遞歸調用,前序遍歷右子樹
printf("%c?",?root->data);//輸出數據
}
/*
二叉樹的非遞歸前序遍歷,前序遍歷思想:先讓根進棧,只要棧不為空,就可以做彈出操作,
每次彈出一個結點,記得把它的左右結點都進棧,記得右子樹先進棧,這樣可以保證右子樹在棧中總處于左子樹的下面。
*/
voidPreOrder_Nonrecursive(BiTree?T)//先序遍歷的非遞歸
{
if(!T)
return;
stack?s;
s.push(T);
while(!s.empty())
{
BiTree?temp?=?s.top();
cout<data<<"?";
s.pop();
if(temp->rchild)
s.push(temp->rchild);
if(temp->lchild)
s.push(temp->lchild);
}
}
voidPreOrder_Nonrecursive1(BiTree?T)//先序遍歷的非遞歸
{
if(!T)
return;
stack?s;
BiTree?curr?=?T;
while(curr?!=?NULL?||?!s.empty())
{
while(curr?!=?NULL)
{
cout<data<<"??";
s.push(curr);
curr?=?curr->lchild;
}
if(!s.empty())
{
curr?=?s.top();
s.pop();
curr?=?curr->rchild;
}
}
}
voidPreOrder_Nonrecursive2(BiTree?T)//先序遍歷的非遞歸
{
if(!T)
return;
stack?s;
while(T)//?左子樹上的節點全部壓入到棧中
{
s.push(T);
cout<data<<"??";
T?=?T->lchild;
}
while(!s.empty())
{
BiTree?temp?=?s.top()->rchild;//?棧頂元素的右子樹
s.pop();//?彈出棧頂元素
while(temp)//?棧頂元素存在右子樹,則對右子樹同樣遍歷到最下方
{
cout<data<<"??";
s.push(temp);
temp?=?temp->lchild;
}
}
}
voidInOrderTraverse1(BiTree?T)//?中序遍歷的非遞歸
{
if(!T)
return;
BiTree?curr?=?T;//?指向當前要檢查的節點
stack?s;
while(curr?!=?NULL?||?!s.empty())
{
while(curr?!=?NULL)
{
s.push(curr);
curr?=?curr->lchild;
}//while
if(!s.empty())
{
curr?=?s.top();
s.pop();
cout<data<<"??";
curr?=?curr->rchild;
}
}
}
voidInOrderTraverse(BiTree?T)//?中序遍歷的非遞歸
{
if(!T)
return;
stack?s;
BiTree?curr?=?T->lchild;//?指向當前要檢查的節點
s.push(T);
while(curr?!=?NULL?||?!s.empty())
{
while(curr?!=?NULL)//?一直向左走
{
s.push(curr);
curr?=?curr->lchild;
}
curr?=?s.top();
s.pop();
cout<data<<"??";
curr?=?curr->rchild;
}
}
voidPostOrder_Nonrecursive1(BiTree?T)//?后序遍歷的非遞歸
{
stack?S;
BiTree?curr?=?T?;//?指向當前要檢查的節點
BiTree?previsited?=?NULL;//?指向前一個被訪問的節點
while(curr?!=?NULL?||?!S.empty())//?棧空時結束
{
while(curr?!=?NULL)//?一直向左走直到為空
{
S.push(curr);
curr?=?curr->lchild;
}
curr?=?S.top();
//?當前節點的右孩子如果為空或者已經被訪問,則訪問當前節點
if(curr->rchild?==?NULL?||?curr->rchild?==?previsited)
{
cout<data<<"??";
previsited?=?curr;
S.pop();
curr?=?NULL;
}
else
curr?=?curr->rchild;//?否則訪問右孩子
}
}
voidPostOrder_Nonrecursive(BiTree?T)//?后序遍歷的非遞歸?????雙棧法
{
stack?s1?,?s2;
BiTree?curr?;//?指向當前要檢查的節點
s1.push(T);
while(!s1.empty())//?棧空時結束
{
curr?=?s1.top();
s1.pop();
s2.push(curr);
if(curr->lchild)
s1.push(curr->lchild);
if(curr->rchild)
s1.push(curr->rchild);
}
while(!s2.empty())
{
printf("%c?",?s2.top()->data);
s2.pop();
}
}
intvisit(BiTree?T)
{
if(T)
{
printf("%c?",T->data);
return1;
}
else
return0;
}
voidLeverTraverse(BiTree?T)//方法一、非遞歸層次遍歷二叉樹
{
queue??Q;
BiTree?p;
p?=?T;
if(visit(p)==1)
Q.push(p);
while(!Q.empty())
{
p?=?Q.front();
Q.pop();
if(visit(p->lchild)?==?1)
Q.push(p->lchild);
if(visit(p->rchild)?==?1)
Q.push(p->rchild);
}
}
voidLevelOrder(BiTree?BT)//方法二、非遞歸層次遍歷二叉樹
{
BiTNode?*queue[10];//定義隊列有十個空間
if(BT==NULL)
return;
intfront,rear;
front=rear=0;
queue[rear++]=BT;
while(front!=rear)//如果隊尾指針不等于對頭指針時
{
cout<data<<"??";//輸出遍歷結果
if(queue[front]->lchild!=NULL)//將隊首結點的左孩子指針入隊列
{
queue[rear]=queue[front]->lchild;
rear++;//隊尾指針后移一位
}
if(queue[front]->rchild!=NULL)
{
queue[rear]=queue[front]->rchild;//將隊首結點的右孩子指針入隊列
rear++;//隊尾指針后移一位
}
front++;//對頭指針后移一位
}
}
intdepth(BiTNode?*T)//樹的深度
{
if(!T)
return0;
intd1,d2;
d1=depth(T->lchild);
d2=depth(T->rchild);
return(d1>d2?d1:d2)+1;
//return?(depth(T->lchild)>depth(T->rchild)?depth(T->lchild):depth(T->rchild))+1;
}
intCountNode(BiTNode?*T)
{
if(T?==?NULL)
return0;
return1+CountNode(T->lchild)+CountNode(T->rchild);
}
intmain(void)
{
BiTNode?*root=NULL;//定義一個根結點
intflag=1,k;
printf("?????????????????????本程序實現二叉樹的基本操作。\n");
printf("可以進行建立二叉樹,遞歸先序、中序、后序遍歷,非遞歸先序、中序遍歷及非遞歸層序遍歷等操作。\n");
while(flag)
{
printf("\n");
printf("|--------------------------------------------------------------|\n");
printf("|????????????????????二叉樹的基本操作如下:?????????????????????|\n");
printf("|????????????????????????0.創建二叉樹??????????????????????????|\n");
printf("|????????????????????????1.遞歸先序遍歷????????????????????????|\n");
printf("|????????????????????????2.遞歸中序遍歷????????????????????????|\n");
printf("|????????????????????????3.遞歸后序遍歷????????????????????????|\n");
printf("|????????????????????????4.非遞歸先序遍歷??????????????????????|\n");
printf("|????????????????????????5.非遞歸中序遍歷??????????????????????|\n");
printf("|????????????????????????6.非遞歸后序遍歷??????????????????????|\n");
printf("|????????????????????????7.非遞歸層序遍歷??????????????????????|\n");
printf("|????????????????????????8.二叉樹的深度????????????????????????|\n");
printf("|????????????????????????9.二叉樹的結點個數????????????????????|\n");
printf("|????????????????????????10.退出程序????????????????????????????|\n");
printf("|--------------------------------------------------------------|\n");
printf("????????????????????????請選擇功能:");
scanf("%d",&k);
switch(k)
{
case0:
printf("請建立二叉樹并輸入二叉樹的根節點:");
CreateBiTree(&root);
break;
case1:
if(root)
{
printf("遞歸先序遍歷二叉樹的結果為:");
PreOrder(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case2:
if(root)
{
printf("遞歸中序遍歷二叉樹的結果為:");
InOrder(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case3:
if(root)
{
printf("遞歸后序遍歷二叉樹的結果為:");
PostOrder(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case4:
if(root)
{
printf("非遞歸先序遍歷二叉樹:");
PreOrder_Nonrecursive1(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case5:
if(root)
{
printf("非遞歸中序遍歷二叉樹:");
InOrderTraverse1(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case6:
if(root)
{
printf("非遞歸后序遍歷二叉樹:");
PostOrder_Nonrecursive(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case7:
if(root)
{
printf("非遞歸層序遍歷二叉樹:");
//LeverTraverse(root);
LevelOrder(root);
printf("\n");
}
else
printf("??????????二叉樹為空!\n");
break;
case8:
if(root)
printf("這棵二叉樹的深度為:%d\n",depth(root));
else
printf("??????????二叉樹為空!\n");
break;
case9:
if(root)
printf("這棵二叉樹的結點個數為:%d\n",CountNode(root));
else
printf("??????????二叉樹為空!\n");
break;
default:
flag=0;
printf("程序運行結束,按任意鍵退出!\n");
}
}
system("pause");
return0;
}