您的位置:首页 > 理论基础 > 数据结构算法

数据结构 树(二叉树 链式存储)

2014-05-11 17:03 120 查看
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"

#define MAXNODE 100
typedef char TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//先序遍历(递归)
void PreOrder(BiTree T)
{
if(T!=NULL)
{
printf("%c",T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}

//中序遍历(递归)
void InOrderTraverse(BiTree T)
{
if(T==NULL)
{
return;
}
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
}
//后序递归
void PostOrderTraverse(BiTree T)
{
if(T==NULL)
{
return ;
}
else
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c",T->data);
}
}

//非递归遍历

/*
非递归遍历的先序和中序基本类似

先序在入栈前输出元素

后续再出栈后输出元素
*/

//非递归先序遍历
void NRPreOrder(BiTree bt)
{
BiTree stack[MAXNODE],p;
int top;
if(!bt)//bt==NULL
{
return;
}
else
{
top = -1;
p = bt;
while(!(p == NULL&&top==-1))  //p!=NULL||top!=-1  p top同时为NULL或0时才结束即:有一个不为NULL或0都要执行
{
//while(p!=NULL) //p不为NULL一直向下
if(p!=NULL)
{
printf("%c",p->data); //打印节点的值
if(top<MAXNODE-1)
{
stack[++top]=p; //节点入栈
}
else
{
printf("栈溢出\n");
return ;
}
p= p->lchild; //不断进入左子树
}
else
{
if(top<0)
{
return ;
}
else
{
p=stack[top--];//出栈
p=p->rchild;  //出栈之后指向右子树
}
}
}
}

}

//非递归中序遍历
void NRInOrder(BiTree bt)
{
BiTree stack[MAXNODE],p;
int top;
if(!bt)//bt==NULL
{
return;
}
else
{
top = -1;
p = bt;
while(!(p == NULL&&top==-1))  //p!=NULL||top!=-1  p top同时为NULL或0时才结束即:有一个不为NULL或0都要执行
{
//while(p!=NULL) //p不为NULL一直向下
if(p!=NULL)
{
if(top<MAXNODE-1)
{
stack[++top]=p; //节点入栈
}
else
{
printf("栈溢出\n");
return ;
}
p= p->lchild; //不断进入左子树
}
else
{
if(top<0)
{
return ;
}
else
{
p=stack[top--];//出栈
printf("%c",p->data); //打印节点的值
p=p->rchild;  //出栈之后指向右子树
}
}
}
}

}

//后序遍历非递归
/*
后序遍历非递归
结点在第一次出栈之后,还需要进栈,也就是说,结点需要进两次栈,出两次栈
而第二次出栈时才访问结点元素,栈中设置标志
flag =1 第一次出栈,结点不访问,falg=2 第二次出栈,结点访问
*/
typedef struct
{
BiTree link;
int flag;
}StackType;

void NRPostOrder(BiTree bt)
{
StackType stack[MAXNODE];
BiTree p;
int sign;  //得到stacl[i].flag;
int top;
if(bt==NULL)
return ;
else
{
top = -1;
p = bt;
while(!(p==NULL&&top==-1))
{
if(p!=NULL)
{
top++;
stack[top].link=p;
stack[top].flag = 1;
p=p->lchild;
}
else
{
if(top<0)
{
return ;
}
else//出栈
{
p=stack[top].link;
sign = stack[top].flag;
top--;
if(sign == 1)
{
top++;
stack[top].link=p;
stack[top].flag = 2;
p=p->rchild;
}
else
{
printf("%c",p->data);
p=NULL;
}
}
}
}
}

}

//层次遍历

/*
先访问指定结点
访问完之后,如果左后孩子不为空访问左右孩子进队列

*/
void LevelOrder(BiTree T)
{
BiTree queue[MAXNODE];
int front ,rear;
if(T==NULL)
return ;
else
{
front =-1; //队头指针
rear = 0;  //队尾指针
queue[rear]=T;
while(front!= rear)
{
front ++;//出队列
printf("%c",queue[front]->data);
if(queue[front]->lchild!=NULL)
{
rear++;
queue[rear]=queue[front]->lchild;
}
if(queue[front]->rchild!=NULL)
{
rear++;
queue[rear]=queue[front]->rchild;
}
}
}
}

//创建二叉树
void CreateBiTree(BiTree *T)//按先序遍历创建二叉树   T为bt的地址  *T为bt
{
TElemType ch;
scanf("%c",&ch);
//ch = getchar();
if(ch=='#'){
*T = NULL;
}else
{
*T= (BiTree)malloc(sizeof(BiTNode));
if((*T)==NULL)//和(!(*T))一样都是T为空时 表达式true,执行
{
exit(1);
}
else
{
(*T)->data = ch;
CreateBiTree(&((*T)->lchild)); //bt->lchild是一个指针,参数要为指针的地址,故取地址
CreateBiTree(&((*T)->rchild));
}
}
}

void main()
{
BiTree bt;  //指针
/*ABDH#K###E##CFI###G#J##*/
CreateBiTree(&bt);//初始化指针,传参数必须为指针的地址 ,故CreateBiTree1(BiTree *bt);//指向指针的指针

//先序
printf("  递归先序遍历:");
PreOrder(bt);
printf("\n非递归先序遍历:");
NRPreOrder(bt);

//中序
printf("\n\n  递归中序遍历:");
InOrderTraverse(bt);
printf("\n非递归中序遍历:");
NRInOrder(bt);

//后序
printf("\n\n  递归后序遍历:");
PostOrderTraverse(bt);
printf("\n非递归后序遍历:");
NRPostOrder(bt);

//层次遍历
printf("\n\n      层次遍历:");
LevelOrder(bt);
printf("\n");
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: