二叉树的建立(二叉链表)和遍历及求二叉树的深度

二叉树的建立和遍历及求二叉树的深度

首先就说一说二叉树的建立(二叉链表)
我们需要一个先建立一个结构体来做为其结点的数据结构,其数据域用来存放结点的数值,俩个指针域分别存放其左孩子和右孩子。接下来是建立方式,我们使用先序扩展序列来建立,后台输入为一串字符,字符满足要建二叉树的先序序列,其中孩子为空的地方我们用#来表示,代码如下:

BiTree CreateBiTree()
{
	BiTree bt = NULL;
	char ch;
	ch = getchar();
	if (ch == '#') 
		bt = NULL;
	else
	{
		bt = (BiTree)malloc(sizeof(BiTNode));
		bt->data = ch;
		bt->LChild = CreateBiTree();
		bt->RChild = CreateBiTree();
	}
	return bt;
}

接下来我们说一说如何遍历这个二叉树
二叉树的遍历一般来说有三种,分为前中后序遍历,每种遍历又可以分为俩种方式来遍历,递归或者非递归。递归比较简单易懂,我就直接上代码块,如下:

void PreOrder(BiTree root)
{
	if (root)
	{                               
		printf("%c", root->data);
		PreOrder(root->LChild);     //前序
		PreOrder(root->RChild);
	}
}

void InOrder(BiTree root)
{
	if (root)
	{
		InOrder(root->LChild);
		printf("%c", root->data);     //中序
		InOrder(root->RChild);
	}
}

void PostOrder(BiTree root)
{
	if (root)
	{
		PostOrder(root->LChild);
		PostOrder(root->RChild);      //后序
		printf("%c", root->data);
	}
}

我们主要来讲一讲非递归实现遍历的方法,我们以后序非递归为例,我们需要用栈这个数据结构来对树的结点进行回溯,算法思路就是首先拿到根节点,然后一直向左孩子方向压栈,直到左子树的左孩子为空为止,然后判断栈是否为空,如果不为空,然后取出栈顶元素,判断栈顶的右孩子是否为空,如果为空则访问当前节点,如果右孩子不为空,则将当前节点指向它的右孩子,然后再进行下一次循环,我们会发现这样的代码会产生一个问题,就是假如你刚刚把右孩子访问完,再退会上一层,那它右孩子肯定不为空,又会进入它的右孩子,所以我们应该在代码中加一个变量,用变量来记录它是否进入过右孩子,这样可以防止重复访问的问题,下面我们来看看代码

void PostOrderTwo(BiTree root)
{
	SeqStack s = start();
	BiTree p,q;
	p = root;
	q = NULL;
	while(p!=NULL || isEmpty(s))
	{
		
		while(p!=NULL)
		{
			Push(s,p);
			p = p->LChild;
		}
		if(isEmpty(s))
		{
			p = Top(s);
			if(p->RChild==NULL || p->RChild==q)
			{
				p = Pop(s);
				visit(p);
				q=p;
				p=NULL;
			}
			else
				p=p->RChild;
		}
	}
}

完整的建立和先中后序遍历代码如下:

在这里插入代码#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define max 1000
typedef struct cat  
{
	char data;
	struct cat *LChild;
	struct cat *RChild;
} BiTNode,*BiTree;

typedef struct dog
{
    BiTree p[max];
    int top;
}*SeqStack,stack;

SeqStack start()
{
	SeqStack s;
	s = (SeqStack)malloc(sizeof(stack));
	s->top = -1;
	return s;
}

BiTree Pop(SeqStack s)
{
	BiTree a = s->p[s->top];
    s->top--;
    return a;
}

int isEmpty(SeqStack s)
{
	if(s->top==-1){
		return 0;
	}else{
		return 1;
	}
}

BiTree Top(SeqStack s)
{
    return s->p[s->top];
}

void visit(BiTree b)
{
    printf("%c",b->data);
}

void Push(SeqStack s,BiTree b)
{
    (s->top)++;
    s->p[s->top] = b;
}

BiTree CreateBiTree()
{
	BiTree bt = NULL;
	char ch;
	ch = getchar();
	if (ch == '#') 
		bt = NULL;
	else
	{
		bt = (BiTree)malloc(sizeof(BiTNode));
		bt->data = ch;
		bt->LChild = CreateBiTree();
		bt->RChild = CreateBiTree();
	}
	return bt;
}

void PreOrder(BiTree root)
{
	if (root)
	{
		
		printf("%c", root->data);
		PreOrder(root->LChild);
		PreOrder(root->RChild);
	}
}

void InOrder(BiTree root)
{
	if (root)
	{
		InOrder(root->LChild);
		printf("%c", root->data);
		InOrder(root->RChild);
	}
}

void PostOrder(BiTree root)
{
	if (root)
	{
		PostOrder(root->LChild);
		PostOrder(root->RChild);
		printf("%c", root->data);
	}
}

void PostOrderTwo(BiTree root)
{
	SeqStack s = start();
	BiTree p,q;
	p = root;
	q = NULL;
	while(p!=NULL || isEmpty(s))
	{
		
		while(p!=NULL)
		{
			Push(s,p);
			p = p->LChild;
		}
		if(isEmpty(s))
		{
			p = Top(s);
			if(p->RChild==NULL || p->RChild==q)
			{
				p = Pop(s);
				visit(p);
				q=p;
				p=NULL;
			}
			else
				p=p->RChild;
		}
	}
}

int main()
{
	BiTree bt = NULL;
	bt = CreateBiTree();
	PreOrder(bt);
	printf("\n");
	InOrder(bt);
	printf("\n");
	PostOrderTwo(bt);
	return 0;
}

下面我们说一说求二叉树深度的方法
其实求深度还是相当于是要遍历这个二叉树,只不过是把每次访问计数为M,然后俩颗子树各自的M的最大值加一即为该二叉树的深度,之所以加一是它的根结点也算一层。
实现代码如下:

在这里插入代码片#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct cat  
{
	char data;
	struct cat *LChild;
	struct cat *RChild;
} BiTNode,*BiTree;

BiTree CreateBiTree()
{
	BiTree bt = NULL;
	char ch;
	ch = getchar();
	if (ch == '#') 
		bt = NULL;
	else
	{
		bt = (BiTree)malloc(sizeof(BiTNode));
		bt->data = ch;
		bt->LChild = CreateBiTree();
		bt->RChild = CreateBiTree();
	}
	return bt;
}

int PreOrder(BiTree root)
{
	if (root)
	{
		int a = PreOrder(root->LChild);
		int b = PreOrder(root->RChild);
		if(a>b){
			return a+1;
		}else{
			return b+1;
		}
	}
	return 0; 
}

int main()
{
	BiTree bt = NULL;
	bt = CreateBiTree();
	int max = PreOrder(bt);
	printf("%d",max);
	return 0;
}

如果对代码有疑问或者发现bug请联系作者qq1748708966.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

囿于之间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值