数据结构之二叉树篇总结

树结构是一种比线性结构(例如:线性表、栈、队列等)复杂的数据结构,但是树结构在计算机领域中有着广泛的应用。二叉树是一种最简单的树结构,下面分析以二叉树为研究对象。

结点的度、树的度:某个结点拥有子树的个数,我们称之为某结点的度;而在一棵树中的某结点有最多的子树,该结点的度我们称之为树的度。

结点的层数、树的深度(高度)、树的宽度:记根结点的层数为1,结点的层数通过从根结点开始计数得到;树中所有结点的最大层数称之为树的深度(高度);树中某一层结点的个数的最大值称之为树的宽度。

满二叉树:在二叉树中,所有分支的结点都有左右子树,而且所有叶子结点都分布在同一层,我们称之为满二叉树。

完全二叉树:深度为k的完全二叉树在k-1层是满二叉树,叶子结点只出现在最下两层,并且最下层叶子要分布在左侧连续的位置,如下图所示。

二叉树的一些重要性质:

1.在二叉树中,叶子结点的个数记为 n,度为2的结点个数记为 m,则满足等式:n=m+1

2.二叉树的第 i 层有 2^{i-1} 个结点;

3.深度为 k 的二叉树,最多有 2^{k}-1 个结点;

4.具有 n 个结点的完全二叉树的深度为 [log_2{n}]+1

二叉树的遍历(前序遍历、中序遍历、后序遍历、层序遍历)

可以用一个结构体来描述二叉树中的结点信息,程序如下所示。

template <typename datatype>
struct bi_node
{
	datatype data;
	bi_node<datatype>* rchild;
	bi_node<datatype>* lchild;
};

1.前序遍历

//前序遍历的递归形式遍历
template <typename datatype>
void preorder(bi_node<datatype>* bt)
{
	if (bt == NULL)
		return;
	else
	{
		cout << bt->data << " ";
		preorder(bt->lchild);
		preorder(bt->rchild);
	}
}
//前序遍历的非递归形式遍历
template <typename datatype>
void preorder(bi_node<datatype>* root)//输入二叉链表的根指针
{
	bi_node<datatype>* bt = root;
	bi_node<datatype>* s[20];//定义顺序栈,最多20个结点指针
	int top = -1;//顺序栈初始化,指向栈顶
	while (bt != NULL || top != -1)
	{
		while (bt != NULL)
		{
			cout << bt->data << " ";
			s[++top] = bt;
			bt = bt->lchild;
		}
		if (top != -1)//栈非空
		{
			bt = s[top--];
			bt = bt->rchild;
		}
	}
}

2.中序遍历

//中序遍历的递归形式遍历
template <typename datatype>
void midorder(bi_node<datatype>* bt)
{
	if (bt == NULL)
		return;
	else
	{
		midorder(bt->lchild);
		cout << bt->data << " ";
		midorder(bt->rchild);
	}
}
//中序遍历的非递归形式遍历
template <typename datatype>
void midorder(bi_node<datatype>* root)//输入二叉链表的根指针
{
	bi_node<datatype>* bt = root;
	bi_node<datatype>* s[20];//定义顺序栈,最多20个结点指针
	int top = -1;//顺序栈初始化,指向栈顶
	while (bt != NULL || top != -1)
	{
		while (bt != NULL)
		{
			s[++top] = bt;
			bt = bt->lchild;
		}
		if (top != -1)//栈非空
		{
			bt = s[top--];
			cout << bt->data << " ";
			bt = bt->rchild;
		}
	}
}

3.后序遍历

//后序遍历的递归形式遍历
template <typename datatype>
void postorder(bi_node<datatype>* bt)
{
	if (bt == NULL)
		return;
	else
	{
		postorder(bt->lchild);
		postorder(bt->rchild);
		cout << bt->data << " ";
	}
}
template <typename datatype>
struct element
{
	bi_node<datatype>* ptr;
	int flag;
};
//后序遍历的非递归形式遍历
template <typename datatype>
void postorder(bi_node<datatype>* root)//输入二叉链表的根指针
{
	bi_node<datatype>* bt = root;
	element s[20];//定义顺序栈,最多20个元素
	int top = -1;//顺序栈初始化,指向栈顶
	while (bt != NULL || top != -1)
	{
		while (bt != NULL)
		{
			++top;
			s[top].ptr = bt;//bt连同标志flag入栈
			s[top].flag = 1;
			bt = bt->lchild;
		}
		if (top != -1 && s[top].flag == 2)
		{
			bt = s[top--].ptr;
			cout << bt->data << " ";
		}
		if (top != -1)
		{
			s[top].flag = 2;
			bt = s[top].ptr->rchild;
		}
	}
}

4.层序遍历

template <typename datatype>
void levelorder(bi_node<datatype>* root)
{
	bi_node<datatype>* Queue[20], * q = NULL;
	int front = -1, rear = -1;//队列进行初始化
	if (root == NULL)
		return;
	Queue[++rear] = root;//根指针入队
	while (front != rear)//当队列非空时
	{
		q = Queue[++front];//出队
		cout << q->data << " ";
		if (q->lchild != NULL)
			Queue[++rear] = q->lchild;
		if (q->rchild == NULL)
			Queue[++rear] = q->rchild;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值