专题知识点-二叉树-(非常有意义的一篇文章)


过往的时光早已不再,好好珍惜现在

二叉树的基础知识

知识点一

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(二叉树性质 )

在这里插入图片描述
在这里插入图片描述

树与二叉树的相互转换

在这里插入图片描述

二叉树的遍历

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

层次优先遍历

在这里插入图片描述

树的深度和广度优先遍历

在这里插入图片描述
在这里插入图片描述

中序线索二叉树

在这里插入图片描述
在这里插入图片描述

二叉树相关遍历代码

顺序存储和链式存储

typedef struct Branch//顺序存储结构
{
	int cldx;  
	Branch* next;   
}Branch;   
typedef struct   
{
	int data;    
	Branch* first;    
}Tnode;    
链式存储结构    


二叉树的链式存储结构    
typedef struct BTnode    
{
	char data;    
	struct BTnode* lchild;    
	struct BTnode* rchild;    
}BTnode;    

二叉树的遍历

void xianxubianli(BTnode* p)
{
	if (p != NULL)
	{
		visit(p);
		xianxubianli(p->lchild);
		xianxubianli(p->lchild);
	}
}


递归进行中序遍历
void zhongxubainli(BTnode* p)
{
	if (p != NULL)
	{
		zhongxubainli(p->lchild);
		visit(p);
		zhongxubianli(p->rchild);
	}
}BTnode*p  


后序遍历进行递归操作  
void houxubianli(BTnode* bt)  
{
	if (p != NULL)  
	{
		houxubianli(p->lchild);  
		houxubianli(p->rchild);  
		visit(p);  
	}
}

二叉树的相关例题

左右两边表达式求值

在这里插入图片描述

int comp(BTnode* p)
{
	int A, B;
	if (p != NULL)
	{
		if (p->lchikd != NULL && p->rchild != NULL)
		{
			A = comp(p->lchild);//这个是不断的求左边的树,一直到不行的时候,然后返回,
			//到上一个根的右边的树,然后看看求右边的树的值,并且也是递归,求右边树的数据的问题,
			//然后分别不断的求出左右两边的值,然后一起进行ji算
			B = comp(p->rchild);
			return op(A, B, p->data);//这个是求的是树左右两边的数据的求值
		}
		else
			return p->data - '0';//这个是这个根的数据的返回
	}
	else
		return 0;//这是没有数据,直接就是返回0

}//有一些问题,比如说返回的值为什么是int,A表示的是什么意思,不是指针,难道是
深度的表达,因为是整型嘛

int comp(BTnode* p) 
{
	int A, B;  
	if (p != NULL)  
	{
		if (p->lchild != NULL && p->rchild != NULL)  
		{
			A = comp(p->lchild);  
			B = comp(p->rchild);  
			return op(A, B, p->data);  
		}
		else  
			return p->data - '0';  
	}
	else  
		retunrn 0;  
}

求树的深度

在这里插入图片描述

求树的深度,先分别进行求出树的左子树的最长的深度以及右子树最长的深度,然后进行比较得出最大的深度数


然后进行求出的数字加一  
int getdeth(BTnode* p)  
{
	int LD, RD;  
	if (p == NULL)  
		return 0;  
	else  
	{
		LD = getdeth(p->lchild);  
		RD = getdeth(p->rchild);  
		return (LD > RD ? LD : RD) + 1;  
	}
}

找数

例题,对于二叉树的数据域进行分别进行查找,找一个数据域是否等于一个KEY的数,
如果等于KEY的数字则讲这个指针赋值到q里面,其实就是对于数的分一个分支进行分别的访问和

查找
void search(BTnode* p, BTnode*& q, int key)//类型还是树的指针类型
{
	if (p != NULL)//这是前提条件
	{
		if (p->data == key)//这是直接测试p的数据域的直接的访问
			q = p;//然后就是指针的赋值
		else
		{
			search(p->lchild, q, key);//否者,如果不成立条件的话,那么进行左边的访问数据的问题
			search(p->rchild, q, key);//如果左边的不行,那么就访问右边的树
		}
	}
}





void search(BTnode* q, int key, BTnode* q)   
{
	if (p != NULL)   
	{
		if (p->data == key)   
			q = p;   
		else   
		{
			saerch(p->lchild, q, key);   
			search(p->rchild, q, key);   
		}
	}
}

找第k个数

题目进行输出二叉树中第k个指针的值

#include<stdio.h>
int main()
{
	int n = 0;
	void trave(BTnode * bt, int k);
	return 0;
}//上面的代码就是父母,直接就是一个框架而已
void  trave(BTnode* bt, int k)//下面就是函数的问题
{
	int n = 0;
	if (p != NULL)//这是关于p不是空的前提条件
	{
		++n;//这是动的加,递进就是数据的
		if (n == k)//这是输出的条件问题,就是递归访问的条件
		{
			//输出这一点的指针的数据域
			printf("%d\n", p->data);
			return 0;
		}
		trvae(p->lchild);
		trave(p->rchild);

	}
}

上面这一种形式是先序的输出方式
下面还有中序和后序的输出方式
void trave(BTnode* p, int k)
{
	if (p != NULL)
	{
		trave(p->lchild, k);
		++n;
		if (k == n)
		{
			《输出所在点的数据域》;
			return;
		}
		trave(p->rchild, k);
	}
}


递归后序的表达方式  
void trave(BTnode* p, int k)     
{
	if (p != NULL)      
	{
		trave(p->lchild, k);      
		trave(p->rchild, k);      
		++n;      
		if (k == n)      
		{
			《输出所在点的数据域》      
				return;      
		}
	}
}

二叉树非递归遍历代码

二叉树的层次优先遍历

void level(BTnode* bt)
{
	if (bt != NULL)
	{
		int front, near;
		BTnode* que[maxsize];//对于队列进行初始化que
		front = rear = 0;//循环队列进行开始的赋值
		BTnode* p;
		rear = (rear + 1) % maxsize;//先进行尾节点加一,然后进行赋值操作
		que[rear] = bt;//这就是进队列了
		while (front != rear)//这是队列只要是不为空时候都是可以进行的
		{
			front = (front + 1) % maxsize;//出队前进行赋值操作
			p = que[front];//先出队才可以访问里面的数据   
			visit(p);   
			//先要判断他里面的左右孩子是否存在,如果存在则   
			//进行入队的操作   
			if (p->lchild != NULL)   
			{
				rear = (rear + 1) % maxsize;//进行入队的操作   
				que[rear] = p->lchild;   
			}
			if (p->rchild != NULL)   
			{
				rear = (rear + 1) % maxsize;   
				que[rear] = p->rchild;   
			}
		}
	}
}

二叉树非递归前序中序后续遍历

//二叉树非递归进行代码处理
// 其实就是引用了栈的应用,先

void shuchushu(BTnode* bt)//先序的存储进行取得
{
	if (bt != NULL)
	{
		BTnode* stack[maxsaize];//进行定义栈的大小(类型就是本身就是树的类型处理)
		int top = -1;//底部进行开始空的时候数组的赋值
		BTnode* p = NULL;//开始的指针的大小为空
		stack[++top] = bt;//对于栈进行赋值操作
		while (top != -1)//进行循环的操作,取,也是存的道理都是一样的
		{
			p = satck[top--];//开始进行取
			visit(p);
			if (p->rchild != NULL)
				stack[++top] = p->lchild;
			if (p->lchild != NULL)
				stack[++top] = p->rchild;
		}
	}
}shu
 





中序输出的非递归的方式进行
void zhongxushuchu(BTnode* bt)
{
	if (bt != NULL)
	{
		BTnode* stack[maxsize];
		int top = -1;
		BTnode* p = NULL;
		p = bt;
		while (top != -1 || p != NULL)
		{
			while (p != NULL)
			{
				stack[++top] = p;
				p = p->lchild;
			}
			if (top != -1)
			{
				p = stack[--top];
				visit(p);
				p = p->rchild;
			}
		}

	}
}



后序遍历的非递归形式的表达方式
void houxubianli(BTnode* bt)
{
	if (bt != NULL)
	{
		BTnode* stack1[maxsize]; int top1 = -1;
		BTnode* stack2[maxsize]; int top2 = -1; 
		BTnode* p = NULL; 
		stack[++top1] = bt; 
		while (top != -1)    
		{
			p = stack1[top1--];    
			stack2[++top2] = p;    
			if (p->lchild != NULL)    
				stack1[++top1] = p->lchild;    
			if (p->rcchild != NULL)    
				stack1[++top!] = p->rchild;    
		}
		while (top2 != -1)    
		{
			p = stack2[--top];    
			visit(p);    
		}
	}
}

##二叉树遍历扩展

typedef struct Branch
{
	int cldx;//这个其实就是子孩子的节点下标
	Branch* next;//这个是指向的是字孩子节点的后一个孩子节点
}Branch;
typedef struct
{
	int data;
	Branch* first;//这个是指向的节点的指针,其实是孩子节点,第一个开始的时候就需要用到这个,就是因为开始的根节点也是孩子节点
}Tnode;
Tnode tree[6];//定义树节点的多少,这个其实就是指针数组,里面的全是指针节点
Branch* q = tree[0]->first;//开始的时候就是需要指向的first,指向的就是数组里面的指针,所以需要用到first,并且用指针的形式表示出来
tree[q->cldx];//这个就是这个节点的下标
void shuchuxingshi(Tnode* p, Tnode tree[])
{
	if (p != NULL)
	{
		visit(p);
		//下面就是访问他的子节点的情况了
		Branch* q;
		q = p->first;//这个就是子节点的指针情况了
		while (q != NULL)
		{
			shuchuxingshi(tree[q->cldx], tree);//这个就是调用的子节点的情况里面进行调用了
			//这个子节点的情况调用完之后就是下一个子节点的情况,然后重新依次的进行调用
			//里面子节点的情况
		}
	}
}

树的广度层次优先遍历的代码演示
void level(Tnode* tn, Tnode tree[])
{
	int front, rear;
	Tnode* que[maxsize];
	front = rear = 0;
	Tnode* p;
	if (tn != NULL)
	{
		rear = (rear + 1) % maxszie;
		que[rear] = tn;
		while (front != rear)
		{
			front = (front + 1) % maxszie;
			p = que[front];
			visit(p);
			Branch* q = p->first;//这个就是分析子节点的问题了,和之前的情况是一样的
			while (q != NULL)
			{
				rear = (rear + 1) % maxszie;
				que[rear] = tree[q->cldx];
				q = q->next;
			}
		}
	}
}



中序线索遍历二叉树的代码演示
typedef struct BTnode
{

	int data;
	int lTag;
	int rTag;
	TBnode* lchild;
	TBnode* rchild;
}TBnode;
void inthread(BTnode* p, TBnode* pre)//pre表示的是p的前驱节点//	前驱节点本来就是NULL的,只不过是需要不断的变化的
{
	if (p != NULL)
	{
		inthread(p->lchild, pre);//一直表示到底部的空节点了
		if (p->lchild == NULL)
		{
			p->lchild = pre;
			p->lTag = 1;
		}
		if (pre != NULL && pre->rchild == NULL)
		{
			pre->rchild = p;
			pre->rTag = 1;
		}
		pre = p;//如果上述条件都没有成立,那么前驱节点就需要改变了
		inthread(p->rchild, pre);
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一直爱莲子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值