/**鏈式二叉樹非遞歸的前序遍歷和中序遍歷
*後序遍歷比較特殊
**利用順序棧來存儲樹的節點
**代碼實現如下
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define NAMESIZE 255//字符串的最大長度
#define OK 1
#define ERROR 0
#define MAXSIZE 100//順序棧的最大長度
static int id=0;//編號
typedef int Statu;//函數返回值的數據類型
typedef char *NameType;//數據域的名稱的數據類型
typedef int IdType;//數據域的編號的數據類型
typedef struct elementtype
{
NameType name;//名稱
IdType id;//編號
}ElementType;//數據域的結構體
typedef struct linktree
{
ElementType *data;//樹節點的數據域
struct linktree *Lchild;//左孩子節點
struct linktree *Rchild;//右孩子節點
}Link_Tree;//樹的結構體
void Init_linktree(Link_Tree*tree);//樹的初始化
Statu create_linktree(Link_Tree*tree);//樹的創建
void preorder_tree(Link_Tree*tree);//非遞歸的前序遍歷
void inorder_tree(Link_Tree*tree);//非遞歸的中序遍歷
void main()
{
Link_Tree*tree;//樹的指針
tree=(Link_Tree*)malloc(sizeof(Link_Tree));
if(tree!=NULL)
//對樹進行初始化
Init_linktree(tree);
//對其進行創建
printf("根節點:");
int result=create_linktree(tree);
if(result=ERROR)
{
printf("二叉樹創建失敗\n");
}
else
{
printf("二叉樹創建成功\n");
}
printf("非遞歸的前序遍歷\n");
preorder_tree(tree);
printf("\n");
printf("非遞歸的中序遍歷的結果爲\n");
inorder_tree(tree);
printf("\n");
}
void Init_linktree(Link_Tree*tree)//樹的初始化
{
//對樹進行判斷是否合法
if(tree==NULL)
{
printf("樹的初始化失敗\n");
return ;
}
else
{
tree->Rchild=NULL;
tree->Lchild=NULL;//對左右孩子指針進行初始化
}
}
Statu create_linktree(Link_Tree*tree)//樹的創建
{
if(tree==NULL)
return ERROR;
char name[NAMESIZE];
gets(name);
if(strcmp(name,"\0")==0)
return ERROR;
else
{
tree->data=(ElementType*)malloc(sizeof(ElementType));
tree->data->name=(NameType)malloc(sizeof(char)*NAMESIZE);
tree->data->id=++id;//編號++
strcpy(tree->data->name,name);//name本身就是一個指針
}
//創建左孩子節點
tree->Lchild=(Link_Tree*)malloc(sizeof(Link_Tree));
//創建右孩子節點
tree->Rchild=(Link_Tree*)malloc(sizeof(Link_Tree));
//對左右孩子進行遞歸創建
printf("左孩子:");
if(create_linktree(tree->Lchild)==ERROR)
{
//釋放節點的內存
tree->Lchild=NULL;
free(tree->Lchild);
}
printf("右孩子:");
if(create_linktree(tree->Rchild)==ERROR)
{
//釋放節點的內存
tree->Rchild=NULL;
free(tree->Rchild);
}
return OK;//創建成功
}
void preorder_tree(Link_Tree*tree)//非遞歸的前序遍歷
{
//非遞歸的前序遍歷的思想基棧的先進後出的思想
Link_Tree*n[MAXSIZE];//順序棧 存儲樹的節點
int top=0;//棧的top指針
//對指針進行空間
n[top++]=tree;//將根節點進行入棧
printf("[%d,%s]->",tree->data->id,tree->data->name);
Link_Tree*node;//指針變量
node=tree->Lchild;
while(node!=NULL||top!=0)
{
while(node!=NULL)
{
n[top++]=node;
printf("[%d,%s]->",node->data->id,node->data->name);
node=node->Lchild;
}
if(top==0)
return ;
else
{
node=n[--top];
node=node->Rchild;
}
}
}
void inorder_tree(Link_Tree*tree)//非遞歸的中序遍歷
{
Link_Tree* n[MAXSIZE];
int top=0;//top指針
Link_Tree *node;//指針變量
n[top++]=tree;//將根節點進行入棧
node=tree->Lchild;//將指針指向根節點的左孩子
while(node!=NULL||top!=-1)
{
while(node!=NULL)
{
n[top++]=node;
node=node->Lchild;
}
if(top==0)
return ;
else
{
node=n[--top];
printf("[%d,%s]->",node->data->id,node->data->name);
node=node->Rchild;//將指針指向右孩子再次進入循環
}
}
}
/*void postorder_tree(Link_Tree*tree)//非遞歸的後序遍歷
{
//進行後序遍歷
Link_Tree*n[MAXSIZE];
int flag;
int top=0;//top指針
n[top++]=tree;//將根節點進行入棧
Link_Tree*node;
node=tree->Lchild;
while(node!=NULL||top!=0)
{
printf("[%d,%s]->",node->data->id,node->data->name);
while(node!=NULL)
{
n[top++]=node;
node=node->Lchild;
}
//printf("[%d,%s]->",node->data->id,node->data->name);
if(top==0)
return ;
else
{
node=n[--top];//出棧
node=node->Rchild;
}
}*/