直接上代码吧,改了好长一段时间,重点在写那个二叉树的非递归遍历,就写了一个中序的(太麻烦了),层序遍历需要队列,中序遍历竟然需要栈,属实蚌埠住了。
中序非递归遍历:
void inorder(BiTNode *t)//中序遍历的非递归算法
{
BiTNode *temp = t;
while(temp != NULL||S.top != 0)
{
while(temp != NULL)//先把左孩子入栈,所有左孩子入栈结束
{
Push(temp);
temp = temp->lchild;
}
if(S.top != 0)//左孩子入栈结束,取栈顶,输出栈顶元素,遍历右孩子
{
temp = Pop();
printf("%c",temp->data);
temp = temp->rchild;
}
}
printf("\n");
}
当时写不对原因是因为自己直接把以前的栈拿来用了,加上层序遍历都是直接存数据,我也没怎么想,后面发现中序遍历不能只存数据,这样的话回不去,原来竟然需要直接存结点,害....... 服了啊!
对了,我创建树的代码长这样:
int CreatBiTree(BiTree &T, char* ch, int &i)//创建二叉树
{
if(ch[i] == '#')
{
T = NULL;
}
else
{
if(!(T = (BiTNode *)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
T->data = ch[i];
i++;
CreatBiTree(T->lchild, ch, i);
i++;
CreatBiTree(T->rchild, ch, i);
}
return 0;
}
这个的意思是只要没检查到#,就一直存左节点,遇到#存右结点,我的例子为ac#de##b##f##
如图:
丑图见谅;
总代码:
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAXTSIZE 100
#define MAXSIZE 100
#define isMyFaith main
#define TRUE 1
#define TURE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef char TElemType;
typedef char SElemType;
typedef int QElemType;
typedef int Status;
typedef int Kurumi;
typedef struct BiNode{
TElemType data;
struct BiNode *lchild, *rchild;
}BiTNode, *BiTree;
typedef struct stack
{
BiTNode *elements[100];
int top;
}SqStack;
SqStack S;
typedef struct QNode {
BiTree az;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
} LinkQueue; //链队
Status InitQueue(LinkQueue &Q) { //链队初始化
Q.front = Q.rear = new QNode;
Q.front->next = NULL;
return OK;
}
Status EnQueue(LinkQueue &Q, BiTree &e) { //入队
QueuePtr p;
p = new QNode;
p->az = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status DeQueue(LinkQueue &Q, BiTree &e) { //出队
QueuePtr p;
if (Q.front == Q.rear)
return ERROR;
p = Q.front->next;
e = p->az;
Q.front->next= p->next;
if (Q.rear == p)
Q.rear = Q.front;
delete p;
return OK;
}
Status QueueEmpty(LinkQueue &Q)
{
if(Q.front == Q.rear)
{
return 0;
}
else
{
return 1;
}
}
int CreatBiTree(BiTree &T, char* ch, int &i)//创建二叉树
{
if(ch[i] == '#')
{
T = NULL;
}
else
{
if(!(T = (BiTNode *)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
T->data = ch[i];
i++;
CreatBiTree(T->lchild, ch, i);
i++;
CreatBiTree(T->rchild, ch, i);
}
return 0;
}
void setnull()//初始化栈
{
S.top =0;
}
void Push(BiTNode *temp)//入栈操作
{
S.elements[S.top++] = temp;
}
BiTNode *Pop()//取栈顶并出栈顶
{
return S.elements[--S.top];
}
int StackEmpty()//判断空栈
{
return S.top == 0;
}
void visit(BiTree T)
{
printf("%c",T->data);
}
Status PreOrderTraverse(BiTree T)
{
if(T == NULL) return OK;
else{
visit(T);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
return OK;
}//先序遍历
Status InOrderTraverse(BiTree T)
{
if(T == NULL) return OK;
else{
InOrderTraverse(T->lchild);
visit(T);
InOrderTraverse(T->rchild);
}
} //中序递归遍历
Status PostOrderTraverse(BiTree T)
{
if(T == NULL) return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
visit(T);
}
} //后序遍历
void LevelOrder(BiTree b)
{
BiTree p;
LinkQueue Q;
InitQueue(Q); //初始化队列
EnQueue(Q,b); //根节点指针进入队列
while(QueueEmpty(Q)){ //队列不为空,则循环
DeQueue(Q, p); //出队结点p;
printf("%c", p->data); //访问p
if(p->lchild!=NULL) EnQueue(Q,p->lchild);
//有左节点时将其进队
if(p->rchild!=NULL) EnQueue(Q,p->rchild);
//有右节点时将其进队
}
} //层序遍历
void inorder(BiTNode *t)//中序遍历的非递归算法
{
BiTNode *temp = t;
while(temp != NULL||S.top != 0)
{
while(temp != NULL)//先把左孩子入栈,所有左孩子入栈结束
{
Push(temp);
temp = temp->lchild;
}
if(S.top != 0)//左孩子入栈结束,取栈顶,输出栈顶元素,遍历右孩子
{
temp = Pop();
printf("%c",temp->data);
temp = temp->rchild;
}
}
printf("\n");
}
int Copy(BiTree T, BiTree &NewT){ //复制二叉树
if(T == NULL)
{
NewT = NULL; return 0;
}
else{
NewT = new BiTNode; NewT->data = T->data;
Copy(T->lchild, NewT->rchild);
Copy(T->rchild, NewT->rchild);
}
}
int Depth(BiTree T){ //计算树的深度
int m = 0, n = 0;
if(T == NULL) return 0;
else{
m = Depth(T->lchild);
n = Depth(T->rchild);
if(m > n) return m+1;
else return n+1;
}
}
int NodeCount(BiTree T){ //根节点
if(T == NULL)
return 0;
else
return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}
int LeafCount(BiTree T){ //叶子结点
if(T == NULL)
return 0;
if(T->rchild == NULL && T->lchild == NULL)
return 1;
else
return LeafCount(T->lchild) + LeafCount(T->rchild);
}
Kurumi isMyFaith()
{
BiTree T;
char* tempString = "ac#de##b##f##";
int a = 0;
CreatBiTree(T, tempString, a);
printf("Pre: ");
PreOrderTraverse(T);
printf("\nIn: ");
InOrderTraverse(T);
printf("\nPost: ");
PostOrderTraverse(T);
printf("\nLevel: ");
LevelOrder(T);
printf("\nIn2: ");
inorder(T);
return 0;
}
运算结果:
前序遍历Pre: acdebf
中序遍历In: cedbaf
后序遍历Post: ebdcfa
层序遍历Level: acfdeb
中序非递归遍历In2: cedbaf
完毕!