【树与二叉树】(一)树与二叉树的基础理论

(一)树与二叉树的基础理论

一、基本术语

用一些通俗的话说明

树举例
  1. 结点:图中一个圈就是一个结点
  2. 结点的度:结点下的分支数,比如 A 结点的度为3
  3. 叶子结点 (终端结点):图中最底下的结点,度为0,没有分支
  4. 分支结点 (非终端结点):度不为0的结点,和 叶子结点 (终端结点)相反
  5. 树的度:Max(各结点的度)
  6. 子树:图中 A 有三条子树 : 它们的根分别是 B、C、D 结点
  7. 双亲、孩子:分支的两端,上面是双亲,下面是孩子,比如 A 结点是 B、C、D 结点的双亲,反之,B、C、D 结点是 A 结点的孩子
  8. 兄弟:同一个双亲的孩子互称兄弟,比如 B、C、D 结点
  9. 堂兄弟:G 和 E、F、H、I、J
  10. 祖先:直系,比如 M 结点的祖先是 H、D 或 A 结点
  11. 子孙:以某节点为根的子树中任一结点都称为该结点的子孙,比如 B 的子孙有:E、F、K、L
  12. 深度:就是看树有几层,图中树有 4 层,即深度为 4
  13. 高度:从下往上数,看有几层,有些资料把首层称为0,有些称为1

关于结点节点:用的顺手就好

严蔚敏《数据结构》书 P120中,高度和深度为同一概念,本人认为应该区分开

二、树和二叉树的定义(特点)

书本上的定义有时候让人摸不着头脑,下面是我的理解

  1. :形如左图所示,可以想像成一棵倒着的树(不过说成一串葡萄可能更合理吧,哈哈)

    特点:
    (1)有且只有一个根

    (2)子树没有交集

  2. 二叉树:形如右图所示,是一种特殊的树

    特点:
    (1)每个结点最多有两棵子树,度<=2

    (2)子树有左右之分,是有序树

树举例二叉树树举例

三、二叉树的性质和解释

二叉树的性质是重点!!!

性质1:在第 i 层最多有 2i-1 个结点( i 为正整数)

性质2:深度为 k 的二叉树最多有 2k-1 个结点

性质3:度为0的节点数 = 度为2的节点数+1 即 n0 = n2 +1

证明了解更好

性质1—归纳法证明 书P123

性质2—首项 a1 = 1 ,公比为 q = 2 ,项数 n = k 的等比数列求和问题:等比数列求和公式 Sn=a1*(1-qn)/(1-q)

关于性质3的两种说明
性质3推导1性质3推导2

四、满二叉树和完全二叉树

  1. 满二叉树:所有层数结点数都是满的,假设该二叉树有 k 层,则结点个数有 2k-1个(性质2)
满二叉树举例
  1. 完全二叉树:在满二叉树的基础上在最深层右边连续地减掉一些结点,比如上图减掉 13、14、15 结点所形成的完全二叉树
完全二叉树举例

五、二叉树的存储结构

5.1 顺序存储结构

不是重点,一般用链式存储结构

将一般二叉树转换为满二叉树,顺序映射到一维数组上,如果二叉树比较空,顺序储存结构比较费空间

#include <iostream>
#include <cmath>
using namespace std;

const int MAX_NODE_SIZE = 127; // 2^7 - 1 = 128, 7层 
class SqBiTree
{
	//private:
	public:
		int m_SqBiTree[MAX_NODE_SIZE]; //0号元素存储根节点 
		int m_order;//完全满二叉树的层数
	public:
		void Print()
		{
			if(this->m_order<=0)	return;
			cout << "第1层:" << this->m_SqBiTree[0] << endl; 
			for(int i=2; i<=m_order; i++)
			{	
				cout << "第" << i << "层:";
				for(int j= pow(2,i-1)-1; j<=pow(2,i)-2; j++)
				{
					cout << this->m_SqBiTree[j] << " ";
				}
				cout << endl;
			}	
		} 
};

int main()
{
	int last = 14;
	SqBiTree bt;
	for(int i=0; i<=last; i++)
	{
		bt.m_SqBiTree[i] = i;
	}
	bt.m_order = ceil(log2(last+2));
	
	bt.Print();
	
//	cout << ceil(log2(last+2)) << endl;
	
	return 0;
}

5.2 链式存储结构

二叉链表和三叉链表的区别是指针域有无指向双亲的指针

链式存储
  • 二叉链表节点结构体定义

    struct Node{
    	//数据域 
    	int date;
    	//指针域
    	Node* left;
    	Node* right;
    	//Node* parent;//没有指向双亲的指针
    	
    	//构造函数
    	Node(int v):date(v),left(NULL),right(NULL){}; 
    	 
    };
    
  • 三叉链表节点结构体定义

    struct Node{
    	//数据域 
    	int date;
    	//指针域
    	Node* left;
    	Node* right;
    	Node* parent;
    	
    	//构造函数
    	Node(int v):date(v),left(NULL),right(NULL),parent(NULL){};  
    };
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值