IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二叉树的基本性质与遍历 -> 正文阅读

[数据结构与算法]二叉树的基本性质与遍历

二叉树:

就是一棵树中每个结点最多只有两个结点,可以没有结点,也可以只有一个结点,也可以为空结点

下面说一下二叉树的常见形态:

????????

满二叉树与完全二叉树的区别:

? ? ? ? 满二叉树就是除了叶子结点之外,每一个结点都有两个孩子

? ? ? ? 完全二叉树就是每一个结点不一定有两个孩子,但是如果出现在同一层,完全二叉树结点的i位置与满二叉树结点的?i位置编号相同,就是完全二叉树。

? ? ? ? 所以,满二叉树一定是完全二叉树,但是完全二叉树不一定是满二叉树

然后来说一下二叉树的性质:

????????1.在二叉树的i层最多有2^i-1个结点(i>0)

????????2.深度为k的二叉树最多有2^k - 1个结点(k>0)

????????3.对于任何一棵二叉树,若度为2的结点数有n2个,则叶子数n0必定为n2+1(n0=n2+1)

? ? ? ? 4.具有n个结点的完全二叉树深度必为

? ? ? ? ?5.对于完全二叉树,从上到下,从左到右,则编号为i的结点,其左孩子必为2i,右孩子编号为2*i + 1,其双亲的编号必为i/2(i=1时候为根)

二叉树的遍历:

? ? ? ? 大概会分为三种情况,这三种情况的讨论,就是根据到底是先遍历根,还是在中间遍历根,还是说在最后遍历根,也就分为了先序遍历(DLR),中序遍历(LDR),后序遍历(LRD)

? ? ? ? D:根 L: 左结点 R:右结点

? ? ? ? 先来看一个二叉树:

????????

? ? ? ? 先来说一下先序遍历(DLR)

? ? ? ????????? 先根在左在右:比如一个函数r(从A传入结点),然后先把A打印,毕竟是先序嘛,然后去遍历左边,也就是走下面遍历

????????????????

? ? ? ? ? ? ? ? 这边函数栈就是

?????????????????

?????????

话不多说,直接上代码:

????????

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct _binary_node binary_node;

struct _binary_node
{
	char ch;
	binary_node *lchild;
	binary_node *rchild;
};

void recursion_print(binary_node *node)
{
	if (node == NULL) {
		return;
	} 

	printf("%c ", node->ch);
	recursion_print(node->lchild);
	recursion_print(node->rchild);
}

int main()
{
	//靠靠靠靠靠靠靠
	binary_node node_a = { 'A', NULL, NULL };
	binary_node node_b = { 'B', NULL, NULL };
	binary_node node_c = { 'C', NULL, NULL };
	binary_node node_d = { 'D', NULL, NULL };
	binary_node node_e = { 'E', NULL, NULL };
	binary_node node_f = { 'F', NULL, NULL };


	node_a.lchild = &node_b;
	node_a.rchild = &node_c;

	node_b.rchild = &node_e;
	node_b.lchild = &node_d;

	node_c.rchild = &node_f;

	//靠靠
	recursion_print(&node_a);
	return 1;
}

?运行结果:

????????

? 当然了,二叉树肯定不至于递归,所以,比如计算二叉树叶子的数目,二叉树的高度,又比如拷贝一棵二叉树,下面上完整代码:

binary_tree.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct _binary_node binary_node;

struct _binary_node
{
	char ch;
	binary_node *lchild;
	binary_node *rchild;
};

void recursion_print(binary_node *node)
{
	if (node == NULL) {
		return;
	} 

	printf("%c ", node->ch);
	recursion_print(node->lchild);
	recursion_print(node->rchild);
}

void calc_leaf_num(binary_node *node,int *p)
{
	//程序的结束条件
	if(node == NULL) {
		return ;
	}
	//left and right is null
	if(node->lchild == NULL && node->rchild == NULL) {
		(*p)++;
	}
	calc_leaf_num(node->lchild,p);//传入计算数量变量的地址
	calc_leaf_num(node->rchild,p);
}


//计算树高度
int get_tree_high(binary_node *node)
{
	if(node == NULL) {
		return 0;
	}
	//递归计算左右两边树的高度
	int left_high = get_tree_high(node->lchild);
	int right_high = get_tree_high(node->rchild);
	return left_high > right_high ? left_high + 1 : right_high + 1;
}

//拷贝二叉树就是在堆上面开辟一个空间
//来存放二叉树的每一个结点
//最后返回头部结点
binary_node* copy_tree(binary_node *node)
{
	if(node == NULL){
		return NULL;
	}
	
	//还是要遍历左树,在遍历右树
	binary_node* lnode = copy_tree(node->lchild);
	binary_node* rnode = copy_tree(node->rchild);
	//每一个结点都要干一件事儿
	binary_node *new_node = (binary_node*)malloc(sizeof(binary_node));
	if(new_node != NULL) {
		new_node->ch = node->ch;
		new_node->lchild = lnode;
		new_node->rchild = rnode;
	}
	return new_node;
}

//释放拷贝的这棵树
void free_tree(binary_node *node)
{
	if(node == NULL) {
		return;
	}
	free_tree(node->lchild);
	free_tree(node->rchild);
	//在此之前看一下被释放的结点
	printf("%c被释放了\n",node->ch);
	free(node);//释放这个结点
}
	
	
int main()
{
	binary_node node_a = { 'A', NULL, NULL };
	binary_node node_b = { 'B', NULL, NULL };
	binary_node node_c = { 'C', NULL, NULL };
	binary_node node_d = { 'D', NULL, NULL };
	binary_node node_e = { 'E', NULL, NULL };
	binary_node node_f = { 'F', NULL, NULL };


	node_a.lchild = &node_b;
	node_a.rchild = &node_c;

	node_b.rchild = &node_e;
	node_b.lchild = &node_d;

	node_c.rchild = &node_f;

	recursion_print(&node_a);

	int leaf_num = 0;

	calc_leaf_num(&node_a,&leaf_num);	
	
	printf("叶子结点数目为:%d\n",leaf_num);

	int tree_high = get_tree_high(&node_a);

	printf("叶子数目为:%d\n",tree_high);

	//拷贝二叉树
	binary_node *node = copy_tree(&node_a);

	//然后递归遍历一下这个二叉树
	printf("\n-------------\n");
	recursion_print(node);
	printf("\n-----\n");
	//释放拷贝的每一个结点
	
	//二叉树非递归遍历
	
	free_tree(node);
	return 1;
}

????????

?????

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 17:03:41  更:2022-06-26 17:04:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:44:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码