浙江大学MOOC-数据结构-树(上)

1 树的基本概念

1.1树的基本术语

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

1.2 二叉树

在这里插入图片描述
二叉树是这样的树旋转之后形成的,Left即到下一层次,Right即从长子节点向下延申。

typedef struct TNode *Position;
typedef Position BinTree; /* 二叉树类型 */
struct TNode{ /* 树结点定义 */
    ElementType Data; /* 结点数据 */
    BinTree Left;     /* 指向左子树 */
    BinTree Right;    /* 指向右子树 */
};
1.3 特殊二叉树

在这里插入图片描述
注意,完全二叉树倒数第二层开始是一个完美二叉树,最后一层的结点可以不完整但是必须向左对齐。
在这里插入图片描述
像这个树就不是完全二叉树,但是将11位置的子树移动到5之下就是完全二叉树。

1.4 二叉树的性质
  1. n层最大的结点数是 2 n − 1 2^{n-1} 2n1
  2. 深度为k的二叉树的最大结点数是 2 k − 1 2^k-1 2k1
  3. n 0 n_0 n0表示叶结点的个数, n 2 n_2 n2表示degree为2的接待您的个数,二者满足 n 0 = n 2 + 1 n_0=n_2 +1 n0=n2+1

2 二叉树的储存结构

2.1 顺序储存
  1. 使用数组,最适用于完全二叉树

在这里插入图片描述

  1. 对于非完全二叉树,将其补充成完全二叉树之后用数组存储,但是会浪费很多空间
2.2 链式存储

链表可以很方便的存储任何二叉树,最常用的就是这种方法。

3 二叉树遍历

3.1 递归的遍历二叉树
  1. 先序遍历
    - 先访问根节点
    - 接着访问左树
    - 最后访问右树
  2. 中序遍历
    - 先访问左树
    - 接着访问根节点
    - 最后访问右树
  3. 后序遍历
    - 先访问左树
    - 接着右树
    - 最后根节点
    上面三种方法代码
void PreorderTraversal( BinTree BT )
{
    if( BT ) {
        printf("%d ", BT->Data );
        PreorderTraversal( BT->Left );
        PreorderTraversal( BT->Right );
    }
}

void InorderTraversal( BinTree BT )
{
    if( BT ) {
        InorderTraversal( BT->Left );
        /* 此处假设对BT结点的访问就是打印数据 */
        printf("%d ", BT->Data); /* 假设数据为整型 */
        InorderTraversal( BT->Right );
    }
}

void PostorderTraversal( BinTree BT )
{
    if( BT ) {
        PostorderTraversal( BT->Left );
        PostorderTraversal( BT->Right );
        printf("%d ", BT->Data);
    }
}
 

可以发现非常简单,仅仅是 p r i n t f printf printf 的位置有所变化。但是递归有着总所周知的缺点,对内存的占用非常之大,需要储存很多步操作。递归是使用stack来完成的,不如直接用堆栈的思想来写这个函数。

3.2 非递归遍历算法
3.2.1 堆栈实现
  • 遇到一个结点就将其压栈,并遍历其左子树
  • 当左子树遍历完成之后,pop出stack顶端的结点并访问它
  • 最后按其右指针遍历其右子树
void InOrderTraversal ()
{
	BinTree T = BT;
	Stack S = CreateStack(MaxSize);
	while (T||!IsEmpty(S))
	{
		while(T)
		{
			//printf("%d",T->Data);放在这里就是先序遍历
			Pop(S,T);
			T = T->Left;
		}
		if (!IsEmpty(S))
		{
			T = Pop(S);
			printf("%d",T->Data);
			T = T->Right;
		}
	}	
}
3.2.2 队列实现层序遍历

就是一层一层遍历,用队列完美实现

void LevelOrderTraversal(BinTree BT )
{
	Queue Q; BinTree T;
	if (BT!))return;
	Q = CreateQueue(MaxSize);
	AddQ(Q,BT);
	while (!IsEmpty(Q))
	{
		T = Delete (Q);
		printf("d%",Q->Data);
		if(T->Left)AddQ(Q,T->Left);
		if(T->Right)AddQ(Q,T->Right);
	}
}
3.2.3 遍历结果确定二叉树

先序和后续任一个中序即可确定
在这里插入图片描述

例:树的同构判断

介绍一种结构:静态链表
用数组存储,但是是链表的思想

#define MaxTree 10
#define Null -1
typedef int Tree
typedef  char ElementType
//定义常量用#define,定义别名用typedef
struct TreeNode
{
	ElementType Name;
	Tree Left;
	Tree Right;
}T1[MaxTree],T2[MaxTree]
//不同结点之间通过下标相互指示

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值