王道数据结构——树

33 篇文章 5 订阅

先中后序遍历 递归和非递归

层次遍历

二叉树的中序线索化

中序线索二叉树的中序序列(找后继)和逆中序序列(找前驱)

#include<stdio.h>
#include<stdlib.h>

#define Maxsize 100

typedef struct BiNode
{
	int data;
	struct BiNode *lchild;
	struct BiNode *rchild;
} BiNode,*BiTree;

typedef struct
{
	BiNode* data[Maxsize];
	int top;
}SqStack;

typedef struct
{
	BiNode* data[Maxsize];
	int front,rear;
}SqQueue;

typedef struct ThreadNode
{
	int data;
	struct ThreadNode *lchild;
	struct ThreadNode *rchild;
	int ltag;
	int rtag;
}ThreadNode,*ThreadTree;


ThreadNode *pre=NULL;//全局变量pre,指向当前访问结点的前驱 

//以下是顺序栈的操作的代码 
void InitStack(SqStack &S)
{
	S.top=-1;
}

bool IsEmpty(SqStack S)
{
	if(S.top==-1) return true;
	else return false;
}

bool Push(SqStack &S,BiNode* x)
{
	if(S.top==Maxsize-1) return false;
	S.data[++S.top]=x;
	return true;
}

void Pop(SqStack &S,BiNode* &x)
{
	if(S.top==-1)
	{
		printf("栈空!\n");
	}
	x=S.data[S.top];
	S.top--;
}

void GetTop(SqStack S,BiNode* &y)
{
	y=S.data[S.top];
}

void InitTree(BiTree &T)
{
	T->data=1;
	T->lchild=NULL;
	T->rchild=NULL;
}

//以下是顺序循环队列操作的代码


void InitQueue(SqQueue &Q)
{
	Q.front=1;
	Q.rear=1;
}

bool IsEmpty(SqQueue Q)
{
	if(Q.front==Q.rear) return true;
	else return false;
}

void Push(SqQueue &Q,BiNode* x)
{
	if(Q.front==(Q.rear+1)%Maxsize)
	{
		printf("队满了\n");
	}
	
	Q.data[Q.rear]=x;
	Q.rear=(Q.rear+1)%Maxsize;
}

void Pop(SqQueue &Q,BiNode* &y)
{
	if(Q.front==Q.rear)
	{
		printf("队空了\n");
	}
	y=Q.data[Q.front];
	Q.front=(Q.front+1)%Maxsize;
}

void GetTop(SqQueue Q,BiNode* &z1)
{
	z1=Q.data[Q.front];
}

void GetTail(SqQueue Q,BiNode* &z2)
{
	z2=Q.data[Q.rear-1];
}

int LenQueue(SqQueue Q)
{
//	int len;
//	len=(Q.rear-Q.front+Maxsize)%Maxsize;
//	return len;
	
	return (Q.rear+Maxsize-Q.front)%Maxsize;
}

//以下是树的操作的代码 

void PreOrder1(BiTree T)
{
	if(T!=NULL)
	{
		printf("%d ",T->data);
		PreOrder1(T->lchild);
		PreOrder1(T->rchild);
	}
}

void PreOrder2(BiTree T)
{
	SqStack(S);
	InitStack(S);
	BiNode *p=T;
	while(p||!IsEmpty(S))
	{
		if(p)
		{
			printf("%d ",p->data);
			Push(S,p);
			p=p->lchild;
		}
		else
		{
			Pop(S,p);
			p=p->rchild;
		}
	}
}

void InOrder1(BiTree T)
{
	if(T!=NULL)
	{
		InOrder1(T->lchild);
		printf("%d ",T->data);
		InOrder1(T->rchild);
	}
}

void InOrder2(BiTree T)
{
	SqStack(S);
	InitStack(S);
	BiNode *p=T;
	while(p||!IsEmpty(S))
	{
		if(p)
		{
			Push(S,p);
			p=p->lchild;
		}
		else
		{
			Pop(S,p);
			printf("%d ",p->data);
			p=p->rchild;
		}
	}
}

void PostOrder1(BiTree T)
{
	if(T!=NULL)
	{
		PostOrder1(T->lchild);
		PostOrder1(T->rchild);
		printf("%d ",T->data);
	}
}

void PostOrder2(BiTree T)
{
	SqStack(S);
	InitStack(S);
	BiNode *p=T;
	BiNode *r=NULL;
	while(p||!IsEmpty(S))
	{
		if(p)
		{
			Push(S,p);
			p=p->lchild;
		}
		else
		{
			GetTop(S,p);
			if(p->rchild&&p->rchild!=r)
			{
				p=p->rchild;
			}
			else
			{
				Pop(S,p);
				printf("%d ",p->data);
				r=p;
				p=NULL;
			}
		}
	}
}

void LevelOrder(BiTree T)
{
	SqQueue(Q);
	InitQueue(Q);
	BiNode *p;
	Push(Q,T);
	while(!IsEmpty(Q))
	{
		Pop(Q,p);
		printf("%d ",p->data);
		if(p->lchild!=NULL) Push(Q,p->lchild);
		if(p->rchild!=NULL) Push(Q,p->rchild);
	}
}


//以下是中序线索化的代码

void InitThreadTree(ThreadTree &T)
{
	T->data=1;
	T->lchild=NULL;
	T->rchild=NULL;
}

void visit(ThreadNode *q)//线索化就是让没有指向孩子的指针指向前驱或后继并修改ltag和rtag 
{
	if(q->lchild==NULL)//左指针域为空 
	{
		q->lchild=pre;
		q->ltag=1; 
	}
	if(pre!=NULL&&pre->rchild==NULL)左指针域不为空,右指针域为空
	{
		pre->rchild=q;
		pre->rtag=1;
	}
	pre=q; 
}

void InThread(ThreadTree T)//中序遍历,在visit里线索化 
{
	if(T!=NULL)
	{
		InThread(T->lchild);
		visit(T);
		InThread(T->rchild);
	}
}

void CreateInThread(ThreadTree T)
{
	pre=NULL;
	if(T!=NULL)
	{
		InThread(T);
		if(pre->rchild==NULL)//如果到了最右下的结点,在中序序列中就是最后一个结点 
		{
			pre->rtag=1;
		}
	}
}

//中序线索二叉树的逆中序序列
ThreadNode *LastNode(ThreadNode *p)
{
	while(p->rtag==0) p=p->rchild;
	return p;
}

ThreadNode *PreNode(ThreadNode *p)
{
	if(p->ltag==0) return LastNode(p->lchild);
	else return p->lchild;
}

void RevInOrder(ThreadNode *T)
{
	for(ThreadNode *p=LastNode(T);p!=NULL;p=PreNode(p))
	{
		printf("%d ",p->data);
	}
}

//中序线索二叉树的中序序列

ThreadNode *FirstNode(ThreadNode *p)
{
	while(p->ltag==0) p=p->lchild;
	return p;
}

ThreadNode *NextNode(ThreadNode *p)
{
	if(p->rtag==0) return FirstNode(p->rchild);
	else return p->rchild;
}

void InOrder3(ThreadNode *T)
{
	for(ThreadNode *p=FirstNode(T);p!=NULL;p=NextNode(p))
	{
		printf("%d ",p->data);
	}
}

int main()
{
	BiTree T=(BiNode*)malloc(sizeof(BiNode));
//	BiNode *T;

	InitTree(T);

	BiNode *p1=(BiNode*)malloc(sizeof(BiNode));
	p1->data=2;
	p1->lchild=NULL;
	p1->rchild=NULL;
	
	T->lchild=p1;
	
	BiNode *p2=(BiNode*)malloc(sizeof(BiNode));
	p2->data=3;
	p2->lchild=NULL;
	p2->rchild=NULL;
	
	T->rchild=p2;
	
	printf("递归先序序列为:");
	PreOrder1(T);
	printf("\n");
	
	printf("非递归先序序列为:");
	PreOrder2(T);
	printf("\n");
	
	printf("递归中序序列为:");
	InOrder1(T);
	printf("\n");
	
	printf("非递归中序序列为:");
	InOrder2(T);
	printf("\n");
	
	printf("递归后序序列为:");
	PostOrder1(T);
	printf("\n");
	
	printf("非递归后序序列为:");
	PostOrder2(T);
	printf("\n");
	
	printf("层次遍历序列为:");
	LevelOrder(T);
	printf("\n");
	
	
	
	ThreadTree TT=(ThreadNode*)malloc(sizeof(ThreadNode));
	InitThreadTree(TT);
	ThreadNode *p11=(ThreadNode*)malloc(sizeof(ThreadNode));
	p11->data=2;
	p11->lchild=NULL;
	p11->rchild=NULL;
	
	TT->lchild=p11;
	
	ThreadNode *p22=(ThreadNode*)malloc(sizeof(ThreadNode));
	p22->data=3;
	p22->lchild=NULL;
	p22->rchild=NULL;
	
	TT->rchild=p22;
	
	CreateInThread(TT);
	
	printf("中序线索二叉树的逆中序序列为:\n");
	RevInOrder(TT);
	printf("\n");
	
	printf("中序线索二叉树的逆中序序列为:\n");
	InOrder3(TT);
	printf("\n");
	
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值