二叉树

二叉树特点

  1. 每个父节点至多有两个子节点
  2. 非空二叉树中的叶子结点的数量等于双分支结点(度为2的结点)的数量加1.
  3. 二叉树的第i层上最多有2^(i-1)(i>=1)个节点。
  4. 高度(或深度)为i的二叉树最多有2^i-1(i>=1)个节点。也可以认为高度为i的二叉树有 2^i-1 个结点,那么该二叉树为满二叉树。

二叉树遍历

  1. 先序遍历(根左右)
  2. 中序遍历(左根右)
  3. 后序遍历(左右根)

代码(C++)

代码中对应的树
在这里插入图片描述

先序、中序、后序递归遍历

#include<iostream>
using namespace std;

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

//先序遍历(根左右)
void preOrder(BinaryNode* root)
{
	if (root == NULL)
	{
		return;
	}

	//输出根结点
	cout << root->ch;
	//遍历左子树
	preOrder(root->lchild);
	//遍历右子树
	preOrder(root->rchild);
}

//中序遍历(左根右)
void midOrder(BinaryNode* root)
{
	if (root == NULL)
	{
		return;
	}

	//遍历左子树
	midOrder(root->lchild);
	//输出根结点
	cout << root->ch;
	//遍历右子树
	midOrder(root->rchild);
}

//后序遍历(左右根)
void postOrder(BinaryNode* root)
{
	if (root == NULL)
	{
		return;
	}

	//遍历左子树
	postOrder(root->lchild);
	//遍历右子树
	postOrder(root->rchild);
	//输出根结点
	cout << root->ch;
}

求叶子结点数目(递归)

void LeafNum(BinaryNode* root, int& num)
{
	if (root == NULL)	return;
	if (root->lchild == NULL && root->rchild == NULL)
	{
		num++;
	}

	//遍历左子树
	LeafNum(root->lchild, num);
	//遍历右子树
	LeafNum(root->rchild, num);
}

求二叉树的高度

//求二叉树高度
int TreeHight(BinaryNode* root)
{
	if (root == NULL)	return 0;

	int leftHight = TreeHight(root->lchild);
	int rightHight = TreeHight(root->rchild);
	TreeHight(root->rchild);
	return leftHight > rightHight ? leftHight + 1 : rightHight + 1;
}

拷贝二叉树

//拷贝二叉树
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));
	if (newnode != NULL)
	{
		newnode->ch = root->ch;
		newnode->lchild = root->lchild;
		newnode->rchild = root->rchild;
	}
	return newnode;
}

释放二叉树

//释放二叉树
void FreeSapce_BinaryTree(BinaryNode* root)
{
	if (root == NULL)
		return;

	FreeSapce_BinaryTree(root->lchild);
	FreeSapce_BinaryTree(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;

	//先序遍历
	preOrder(&node1);
	cout << endl;
	//中序遍历
	midOrder(&node1);
	cout << endl;
	//后序遍历
	postOrder(&node1);
	cout << endl;

	//求叶子结点数目
	int num = 0;
	LeafNum(&node1, num);
	cout << "叶子结点数目:" << num << endl;

	//求二叉树的高度
	int hight = TreeHight(&node1);
	cout << "二叉树的高度:" << hight << endl;

	//拷贝二叉树
	preOrder(&node1);
	cout << endl;
	cout << "拷贝后的二叉树:" << endl;
	preOrder(newnode);
	cout << endl;
	//释放二叉树
	FreeSapce_BinaryTree(newnode);
}

二叉树的非递归遍历(链式栈)

链式栈(用企业链表实现)

LinkStack.h文件

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

//链式栈的结点
typedef struct LINKNODE
{
	LINKNODE* next;
}LinkNode;

//链式栈
typedef struct LINKSTACK
{
	LinkNode head;
	int size;
}LinkStack;

//初始化栈
LinkStack* Init_LinkStack();

//入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data);

//出栈
void Pop_LinkStack(LinkStack* stack);

//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack);

//返回栈中元素个数
int Size_LinkStack(LinkStack* stack);

//清空栈
void Clear_LinkStack(LinkStack* stack);

//销毁栈
void FreeSpace_LinkStack(LinkStack* stack);

LinkStack.cpp文件

#include "LinkStack.h"

//初始化栈
LinkStack* Init_LinkStack()
{
	LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));

	if (stack != NULL)
	{
		stack->head.next = NULL;
		stack->size = 0;
	}

	return stack;
}

//入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data)
{
	if (stack == NULL || data == NULL)
	{
		return;
	}

	data->next = stack->head.next;
	stack->head.next = data;
	
	stack->size++;
}

//出栈
void Pop_LinkStack(LinkStack* stack)
{
	if (stack == NULL || stack->size == 0)	return;

	stack->head.next = stack->head.next->next;
	stack->size--;
}

//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack)
{
	if (stack == NULL || stack->size == 0)	return NULL;

	return stack->head.next;
}

//返回栈中元素个数
int Size_LinkStack(LinkStack* stack)
{
	if (stack == NULL)	return -1;

	return stack->size;
}

//清空栈
void Clear_LinkStack(LinkStack* stack)
{
	if (stack == NULL || stack->size == 0)	return;
	stack->head.next = NULL;
	stack->size = 0;
}

//销毁栈
void FreeSpace_LinkStack(LinkStack* stack)
{
	if (stack == NULL)	return;

	free(stack);
}

非递归遍历测试

#include<iostream>
using namespace std;
#include"LinkStack.h"

#define MY_FALSE 0
#define MY_TRUE 1

//二叉树结点
typedef struct BINARYNODE
{
	char ch;
	BINARYNODE* lchild;
	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));
	if (newnode != NULL)
	{
		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 = (BiTreeStackNode*)Top_LinkStack(stack);
		Pop_LinkStack(stack);
		if (node->root == NULL)
		{
			continue;
		}

		if (node->flag == MY_TRUE)
		{
			cout << 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;
			//将当前结点压入栈
			Push_LinkStack(stack, (LinkNode*)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();
	
	system("pause");
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值