树和二叉树

树的基本概念

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

树的表示法

图形表示法

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

广义表示法

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

左孩子右兄弟表示法

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

二叉树

二叉树基本概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
☆ 在上图中,若 ‘J’ 这个点为右侧的,则此树不是完全二叉树。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
☆ 上述问题的解决方法是:没有结点时,为其补上空结点。如下图所示:
在这里插入图片描述

二叉树的表示

☆ 二叉树的表示方法有:二叉链表示法、三叉链表示法

二叉链表示法:

在这里插入图片描述

在这里插入图片描述

三叉链表示法:

在这里插入图片描述

二叉树的遍历

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
☆ 先序遍历:一般从上往下写。
☆ 中序遍历:从中间——下面——上面。
☆ 后续遍历:从下往上写。

二叉树编程实战——递归遍历

示例 递归遍历:
在这里插入图片描述

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


//二叉树结点
typedef struct BINARYNODE
{
	char ch;
	struct BINARYNODE* lchild;
	struct BINARYNODE* rchild;
}BinaryNode;

//递归遍历
void Recursion(BinaryNode* root)
{
	if (root == NULL)
	{
		return;
	}
	//---------先序遍历---------
	//先访问根结点    
	printf("%c", root->ch);
	//再遍历左子树
	Recursion(root->lchild);
	//再遍历右子树
	Recursion(root->rchild);


	--------中序遍历------------
	先遍历左子树
	//Recrsion(root->lchild);
	再访问根结点    先序遍历
	//printf("%c", root->ch);
	再遍历右子树
	//Recursion(root->rchild);
	
	--------后序遍历---------------
	先遍历左子树
	//Recursion(root->lchild);
	再遍历右子树
	//Recursion(root->rchild);
	再访问根结点    先序遍历
	//printf("%c", root->ch);
}
//创建二叉树
void CreateBinaryTree()
{
	//创建结点
	BinaryNode node1 = { 'A',NULL,NULL };
	BinaryNode node2 = { 'B',NULL,NULL };
	BinaryNode node3 = { 'C',NULL,NULL };
	BinaryNode node4 = { 'D',NULL,NULL };
	BinaryNode node5 = { 'E',NULL,NULL };
	BinaryNode node6 = { 'F',NULL,NULL };
	BinaryNode node7 = { 'G',NULL,NULL };
	BinaryNode node8 = { 'H',NULL,NULL };
	//建立结点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;
	//递归遍历
	Recursion(&node1);
	printf("\n");

}


int main()
{
	CreateBinaryTree();


	return 0;
}

结果:

ABCDEFGH

二叉树编程实战——求叶子结点数目

示例:

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

//二叉树结点
typedef struct BINARYNODE
{
	char ch;
	struct BINARYNODE* lchild;
	struct BINARYNODE* rchild;
}BinaryNode;

int num = 0;
void CaculateLeafNum(BinaryNode* root)
{
	if (root == NULL)
	{
		return;
	}
	if (root->lchild == NULL && root->rchild == NULL)
	{
		num++;
	}
	//左子树叶子节点的数目
	CaculateLeafNum(root->lchild);
	//右子树叶子节点的数目
	CaculateLeafNum(root->rchild);
}


//创建二叉树
void CreateBinaryTree()
{
	//创建结点
	BinaryNode node1 = { 'A',NULL,NULL };
	BinaryNode node2 = { 'B',NULL,NULL };
	BinaryNode node3 = { 'C',NULL,NULL };
	BinaryNode node4 = { 'D',NULL,NULL };
	BinaryNode node5 = { 'E',NULL,NULL };
	BinaryNode node6 = { 'F',NULL,NULL };
	BinaryNode node7 = { 'G',NULL,NULL };
	BinaryNode node8 = { 'H',NULL,NULL };
	//建立结点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;
	
	CaculateLeafNum(&node1);
	printf("叶子结点的数目为:%d\n", num);
}

int main()
{
	CreateBinaryTree();
	return 0;
}

结果:

叶子结点的数目为:3

二叉树编程实战——求树的高度

示例:

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

//二叉树结点
typedef struct BINARYNODE
{
	char ch;
	struct BINARYNODE* lchild;
	struct BINARYNODE* rchild;
}BinaryNode;

int CaculateHeight(BinaryNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	else
	{
		//计算左子树的高度和右子树的高度
		int lHeight = CaculateHeight(root->lchild);
		int rHeight = CaculateHeight(root->rchild);
		//返回二者较大者加1
		if (lHeight > rHeight)
		{
			return(lHeight + 1);
		}
		else
		{
			return(rHeight + 1);
		}
	}
}
//创建二叉树
void CreateBinaryTree()
{
	//创建结点
	BinaryNode node1 = { 'A',NULL,NULL };
	BinaryNode node2 = { 'B',NULL,NULL };
	BinaryNode node3 = { 'C',NULL,NULL };
	BinaryNode node4 = { 'D',NULL,NULL };
	BinaryNode node5 = { 'E',NULL,NULL };
	BinaryNode node6 = { 'F',NULL,NULL };
	BinaryNode node7 = { 'G',NULL,NULL };
	BinaryNode node8 = { 'H',NULL,NULL };
	//建立结点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;
	
	int height = CaculateHeight(&node1);
	printf("此二叉树的高度:%d\n", height);
	
}
int main()
{
	CreateBinaryTree();
	return 0;
}

结果:

此二叉树的高度:4

二叉树的拷贝和释放

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

//二叉树结点
typedef struct BINARYNODE
{
	char ch;
	struct BINARYNODE* lchild;
	struct BINARYNODE* rchild;
}BinaryNode;

void Recursion(BinaryNode* root)
{
	if (root == NULL)
		return;
	printf("%c", root->ch);
	Recursion(root->lchild);
	Recursion(root->rchild);
}
//拷贝二叉树
BinaryNode* CopyBinaryTree(BinaryNode* root)
{
	if (root == NULL)
	{
		return NULL;
	}
	//拷贝左子树
	BinaryNode* lchild = CopyBinaryTree(root->lchild);
	//拷贝右子树
	BinaryNode* rchild = CopyBinaryTree(root->rchild);
	//创建结点
	BinaryNode* newnode = (BinaryNode*)malloc(sizeof(BinaryNode));
	newnode->ch = root->ch;
	newnode->lchild =lchild;//拷贝的是结点的数值而不是指针  所以不能写成 =root->lchild
	newnode->rchild =rchild;
	return newnode;

}


//释放二叉树的内存
void FreeSpaceBinaryTree(BinaryNode* root)
{
	if (root == NULL)
		return;
	//释放左子树
	FreeSpaceBinaryTree(root->lchild);
	//释放右子树
	FreeSpaceBinaryTree(root->rchild);
	//释放当前结点
	free(root);
}
//创建二叉树
void CreateBinaryTree()
{
	//创建结点
	BinaryNode node1 = { 'A',NULL,NULL };
	BinaryNode node2 = { 'B',NULL,NULL };
	BinaryNode node3 = { 'C',NULL,NULL };
	BinaryNode node4 = { 'D',NULL,NULL };
	BinaryNode node5 = { 'E',NULL,NULL };
	BinaryNode node6 = { 'F',NULL,NULL };
	BinaryNode node7 = { 'G',NULL,NULL };
	BinaryNode node8 = { 'H',NULL,NULL };
	//建立结点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;
	BinaryNode* root=CopyBinaryTree(&node1);
	Recursion(root);
	FreeSpaceBinaryTree(root);
}

int main()
{
	CreateBinaryTree();
	

	return 0;
}

结果:

ABCDEFGH

二叉树非递归遍历

  1. 给每个结点都默认添加一个flase标志。
  2. 将根结点入栈,判断栈是否为空,如果不为空,判断元素的标志位,若为flase则弹出元素。
  3. 将弹出的元素的标志改为true,将其与其左右结点一起压入栈中。入栈的顺序与三个遍历(先序、中序、后序遍历)中遍历根、左、右的顺序相反。若左右结点有空,则一起压入栈中,在弹出栈的过程中将空结点抛弃。
  4. 若栈顶的元素标志为true,则输出元素。
  5. 直到栈中无元素为止。
    示例:
  6. 创建 LinkStack.h 头文件
  7. 创建 LinkStack.c 源文件
  8. 创建 05二叉树非递归遍历.c 源文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"LinkStack.h"

#define MY_FALSE 0
#define MY_TRUE 1


//二叉树结点
typedef struct BINARYNODE
{
	char ch;
	struct BINARYNODE* lchild;
	struct BINARYNODE* rchild;
}BinaryNode;

//二叉树非递归遍历
typedef struct BITREESTACKNODE
{
	LinkNode node;
	BinaryNode* root;
	int flag;
}BiTreeStackNode;

//创建栈中的结点
BiTreeStackNode* CreateBiTreeStackNode(BinaryNode* node, int flag)
{
	BiTreeStackNode* newnode = (BiTreeStackNode*)malloc(sizeof(BiTreeStackNode));
	newnode->root = node;
	newnode->flag = flag;
	return newnode;

}
//非递归遍历
void NonRecursion(BinaryNode* root)
{
	//创建栈
	LinkStack* stack = Init_LinkStack();
	//把根结点扔到栈里
	Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(root, MY_FALSE));
	while (Size_LinkStack(stack) > 0)
	{
		//先弹出栈顶元素
		BiTreeStackNode* node=Top_LinkStack(stack);
		Pop_LinkStack(stack);
		//判断弹出的结点是否为空
		if (node->root == NULL)
			continue;
		if (node->flag == MY_TRUE)
		{
			printf("%c", node->root->ch);
		}
		else
		{
			//改变压栈顺序,几可以改变成中序、后序遍历
			//当前结点的右、左结点入栈(先序遍历)
			Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(node->root->rchild, MY_FALSE));
			Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(node->root->lchild, MY_FALSE));
			//当前结点入栈
			node->flag = MY_TRUE;//之前已经将栈顶元素弹出,并记为node
			Push_LinkStack(stack,node);
		}

	}
}

//创建二叉树
void CreateBinaryTree()
{
	//创建结点
	BinaryNode node1 = { 'A',NULL,NULL };
	BinaryNode node2 = { 'B',NULL,NULL };
	BinaryNode node3 = { 'C',NULL,NULL };
	BinaryNode node4 = { 'D',NULL,NULL };
	BinaryNode node5 = { 'E',NULL,NULL };
	BinaryNode node6 = { 'F',NULL,NULL };
	BinaryNode node7 = { 'G',NULL,NULL };
	BinaryNode node8 = { 'H',NULL,NULL };
	//建立结点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;
	
	//二叉树非递归打印
	NonRecursion(&node1);
}
int main()
{
	CreateBinaryTree();

	return 0;

}

结果:

ABCDEFGH

二叉树的创建

中序和先序创建树

根据某一个遍历的结果不能确定一个二叉树
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#号法创建树

在这里插入图片描述
示例:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>


typedef struct BINARYNODE
{
	char ch;
	struct BINARYNODE* lchild;
	struct BINARYNODE* rchild;
}BinaryNode;

void Recursion(BinaryNode* root)
{
	if (root == NULL)
		return;
	printf("%c", root->ch);
	Recursion(root->lchild);
	Recursion(root->rchild);
}
BinaryNode* CreateBinaryTree()
{
	fflush(stdin);
	char ch;
	scanf("%c", &ch);

	BinaryNode* node;
	if (ch == '#')
	{
		node = NULL;
	}
	else
	{
		node = (BinaryNode*)malloc(sizeof(BinaryNode));
		node->ch = ch;
		node->lchild= CreateBinaryTree();
		node->rchild= CreateBinaryTree();
	}
	return node;
}

int main()
{
	//创建树
	BinaryNode* root = CreateBinaryTree();
	//打印树
	Recursion(root);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值