#include<stdio.h>
#include<stdlib.h>
//链二叉树
typedef struct elementtype
{
int tyint;
char tychar;
}ElementType;
typedef struct tree
{
int lTag;//用于线索化标记,为0则lChild为左孩子,为1,则lChild为前驱节点
int rTag;//同上同理
ElementType data;
struct tree* lChild;
struct tree* rChild;
}Tree;
Tree* pre=NULL;//定义全局变量pre,用于线索化
Tree* CreatNode(ElementType data)
{
Tree* newtree=(Tree*)malloc(sizeof(Tree));
newtree->data=data;
newtree->lTag=0;
newtree->rTag=0;
newtree->lChild=NULL;
newtree->rChild=NULL;
return newtree;
}
void insertNode(Tree* parentNode,Tree* lChild,Tree* rChild)
{
parentNode->lChild=lChild;
parentNode->rChild=rChild;
}
void showCurData(Tree* myNode)
{
if (myNode==NULL)
{
return;
}
printf("|%d %c|",myNode->data.tyint,myNode->data.tychar);
}
//递归遍历
void preOrder(Tree* root)
{
if(root!=NULL)
{
showCurData(root);
preOrder(root->lChild);
preOrder(root->rChild);
}
}
void midOrder(Tree* root)
{
if(root!=NULL)
{
midOrder(root->lChild);
showCurData(root);
midOrder(root->rChild);
}
}
void lastOrder(Tree* root)
{
if(root!=NULL)
{
lastOrder(root->lChild);
lastOrder(root->rChild);
showCurData(root);
}
}
void destory(Tree* root)
{
if(root!=NULL)
{
lastOrder(root->lChild);
lastOrder(root->rChild);
free(root);
}
}
//栈遍历
void preOrderByStack(Tree* root)
{
if(root==NULL)
{
return;
}
Tree* pmove=root;
struct tree* stack[100];
int stackTop=-1;
while (stackTop!=-1||pmove!=NULL)
{
while(pmove)//左走
{
showCurData(pmove);
stack[++stackTop]=pmove;
pmove=pmove->lChild;
}
if(stackTop!=-1)
{
pmove=stack[stackTop];
stackTop--;
pmove=pmove->rChild;
}
}
}
void midOrderByStack(Tree* root)
{
if(root==NULL)
{
return;
}
Tree* pmove=root;
struct tree* stack[100];
int stackTop=-1;
while (stackTop!=-1||pmove!=NULL)
{
while(pmove)//左走
{
stack[++stackTop]=pmove;
pmove=pmove->lChild;
}
if(stackTop!=-1)
{
pmove=stack[stackTop];
showCurData(pmove);
stackTop--;
pmove=pmove->rChild;
}
}
}
void lastOrderByStack(Tree* root)
{
if(root==NULL)
{
return;
}
Tree* pmove=root,* lastvist=NULL;
struct tree* stack[100];
int stacktop=-1;
while(lastvist!=root)//只要没访问过根节点
{
while(pmove)//先左寻到底
{
stack[++stacktop]=pmove;
pmove=pmove->lChild;
}
while(stacktop!=-1)
{
pmove=stack[stacktop--];
if(pmove->rChild==NULL||pmove->rChild==lastvist)//返回时判断右节点是否访问过
{//访问过就输出
showCurData(pmove);
lastvist=pmove;
}
else{//没访问过就进入右节点左寻
stack[++stacktop]=pmove;
pmove=pmove->rChild;
while(pmove)
{
stack[++stacktop]=pmove;
pmove=pmove->lChild;
}
}
}
}
}
//层次遍历
void floorOrder(Tree* root)
{
if(root==NULL)
{
return;
}
int fornt,rear;
Tree* queue[100],*pmove;
fornt=rear=0;
rear=(rear+1)%100;
queue[rear]=root;
while(fornt!=rear)
{
fornt=(fornt+1)%100;
pmove=queue[fornt];
showCurData(pmove);
if(pmove->lChild!=NULL)
{
rear=(rear+1)%100;
queue[rear]=pmove->lChild;
}
if(pmove->rChild!=NULL)
{
rear=(rear+1)%100;
queue[rear]=pmove->rChild;
}
}
}
//线索化
void midThread(Tree* p)//中序线索化
{
if(p!=NULL)
{
midThread(p->lChild);
if(p->lChild==NULL)//左走到底,左空节点链至前节点
{
p->lChild=pre;
p->lTag=1;
}
if(pre!=NULL&&pre->rChild==NULL)//又走到底,将当前节点链至前节点的又节点
{
pre->rChild=p;
pre->rTag=1;
}
pre=p;
midThread(p->rChild);
}
}
void midOrderread(Tree* root)//中序线索化访问
{
if(root!=NULL)
{
Tree* p=root;
while(p!=NULL)//在没到底前
{
while(p->lTag==0)//左节点不是线索就一直向左访问
{
p=p->lChild;
}
showCurData(p);
while(p->rTag==1&&p->rChild!=NULL)//右节点是后继节点且,不到底时,访问后继节点
{
p=p->rChild;
showCurData(p);
}
p=p->rChild;
}
}
}
void preThread(Tree* p)//前序线索化
{
if(p!=NULL)
{
if(p->lChild==NULL)//左走到底,左空节点链至前节点
{
p->lChild=pre;
p->lTag=1;
}
if(pre!=NULL&&pre->rChild==NULL)//又走到底,将当前节点链至前节点的又节点
{
pre->rChild=p;
pre->rTag=1;
}
pre=p;
if(p->lTag==0) //若左节点是孩子则递归访问,防止访问线索化过的节点,打转
preThread(p->lChild);
if(p->rTag==0)
preThread(p->rChild);
}
}
void preOrderread(Tree* root)//前序线索化访问
{
if(root!=NULL)
{
Tree* p=root;
while(p!=NULL)//在没到底前
{
while(p->lTag==0)//左节点不是线索就一直向左访问
{
showCurData(p);
p=p->lChild;
}
showCurData(p);//向左遇到线索就向右访问
p=p->rChild;
}
}
}
void lastThread(Tree* p)//后序线索化
{
if(p!=NULL)
{
lastThread(p->lChild);
lastThread(p->rChild);
if(p->lChild==NULL)//左走到底,左空节点链至前节点
{
p->lChild==pre;
p->lTag=1;
}
if(pre!=NULL&&pre->rChild==NULL)//又走到底,将当前节点链至前节点的又节点
{
pre->rChild=p;
pre->rTag=1;
}
pre=p;
}
}
// 后序线索化访问,在建
int main()
{
ElementType A={1,'a'};
ElementType B={2,'b'};
ElementType C={3,'c'};
ElementType D={4,'d'};
ElementType E={5,'e'};
ElementType F={6,'f'};
ElementType G={7,'g'};
Tree* a=CreatNode(A);
Tree* b=CreatNode(B);
Tree* c=CreatNode(C);
Tree* d=CreatNode(D);
Tree* e=CreatNode(E);
Tree* f=CreatNode(F);
Tree* g=CreatNode(G);
insertNode(a,b,c);
insertNode(b,d,NULL);
insertNode(d,NULL,g);
insertNode(c,e,f);
midOrder(a);
puts("\n");
midThread(a);
midOrderread(a);
}
【C语言学习】树的操作模板
最新推荐文章于 2023-01-26 11:46:57 发布