《算法笔记》读书记录DAY_30

本文深入探讨了树的定义和性质,包括空树、节点的度、深度和高度等概念。接着介绍了二叉树的递归定义,以及满二叉树和完全二叉树的区别。此外,还讲解了二叉树的存储结构、节点查找与修改、插入操作的方法。最后,通过示例展示了如何创建二叉树。
摘要由CSDN通过智能技术生成

CHAPTER_9  提高篇(3)——数据结构(2)

9.1.1 树的定义与性质

在计算科学中,树(tree)是一种抽象数据类型或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。其中树根的节点我们称作根节点(root),然后向下延伸若干边到达子节点(child),以子节点为树根的树称作子树(subtree)。下图展示了三种不同形态的树:

由于机考的性质,我们不需掌握太多树的理论知识。下面只给出几个实用的性质,这些是应该被记住的:

(1)树可以没有节点,这种树称作空树(empty tree)

(2)树的层次(layer)从根节点算起,根节点为第一层,根节点子树的根节点为第二层,依次向下           类推。

(3)把节点的子树个数称作节点的度(degree),而树中节点的最大度称为树的度,也叫树的宽               度。

(4)因为一条边连接两个节点,且树中没有环,所以n个节点的树一定有n-1条边。反过来说,满           足连通、边数等于顶点数减一的结构一定是一棵树。

(5)没有子树的节点称作叶子节点,叶子节点的度为0。当一棵树只有根节点时,那个节点既是             根节点也是叶子节点。

(6)节点的深度(depth)是指从根节点(深度为1)开始计算,逐层向下累加至该节点的深度值。树             的深度是指树中节点的最大深度。节点的高度(height),是指从最底层叶子节点(高度为1),           开始计算,逐层向上累加至该节点的高度值。树的高度是指树中节点的最大高度。

(7)多棵树组合在一起称作森林(forest),即森林是树的集合。

9.1.2 二叉树的递归定义

下面给出二叉树的定义:

(1)要么二叉树没有根节点,为空树;

(2)要么二叉树由根节点、左子树、右子树构成,并且左右子树都是二叉树。

二叉树采用了递归的方式来定义。我们可以看到,一颗二叉树可以没有左右子树,也可以有左右子树,但左右子树必须严格按照二叉树的定义,要么为空,要么只有它的根节点和它的左右两个子树。其中二叉树严格区分左右,即左子树和右子树是不能交换的。

下图是几种不同形态的二叉树:

 

这里还要说一下几种特殊的二叉树:

(1)满二叉树,二叉树的每一层节点都达到了当层最大数目。上图的E就是一颗满二叉树。

(2)完全二叉树,除了最下面一层,其他层的节点都达到了其最大数目,并且最下层的只从左至           右连续存在若干结点。上图的DE都是完全二叉树。

 

9.1.3 二叉树的存储与基本操作

二叉树的存储结构 

用结构体的方式来定义每个结点,结点设置左指针和右指针分别指向其左右子节点,通过这种方式从根节点出发将每个节点链接成树。其定义方式如下:

typedef struct Node {
	typename data;   //数据域 
	node *lchild;    //左指针 
	node *rchild;    //右指针 
}node;

需要注意的是,当某节点没有左子树时,需要将lchild置为NULL,没有右子树则将lchild置为NULL。

新建二叉树节点 

在建立二叉树时,我们首先需要新建一个根节点指针,并将其置为空。

node *root=NULL;

新建二叉树的过程就是一个一个的新建节点,并往二叉树中逐个插入的过程。我们先讲解如何新建一个节点。

node* newNode(int x) {
    node *n=new node;      //申请一个节点空间
    n->data=x;             //存入数据
    n->lchild=NULL;
    n->rchild=NULL;
    return n;
}

二叉树节点的查找与修改

查找操作是在给定数据域的条件下,在二叉树中找到所有数据域为给定数据域的节点,并可以将它们的数据域修改为给定数据域。

查找思路如下:先判断当前节点是否是需要查找的节点,如果是,则可以对其进行修改,如果不是,则分别往左子树和右子树递归查询,直到当前节点为NULL停止。

void search(node* root,int x,int newdata) {     //root为当前树根节点,x为给定数据域,newdata为新数据 
	if(root==NULL)
		return;
	if(root->data==x) {
		root->data=newdata;         //修改数据操作,这一步往往根据题目需要用合适操作
	}
	else {
		search(root->lchild,x,newdata);
		search(root->rchild,x,newdata);
	}
	 
}

二叉树节点的插入

节点的插入需要根据题目具体的方案来确定。一般情况下,节点的插入位置就是数据域在二叉树中查找失败的位置。因此插入和查找的流程大致相同,由此代码如下:

void insert(node* &root,int x) {
	if(root==NULL) {                   //查找失败的位置为NULL,即为插入位置 
		root=newNode(x);
		return;
	}
	if(根据题目要求,往左子树查找) {   //根据具体情况,当插入的位置在左子树时,往左边查找 
		insert(root->lchild,x);
	}
	else {                             //根据具体情况,当插入的位置在右子树时,往右边查找 
		insert(root->rchild,x);		
	}
}

二叉树的创建

二叉树的建立就是节点的插入过程。插入所需要的数据由题目给出,一般我们将这些数据存储在数组中,再将他们根据题目要求用insert()一个个找到位置插入,最后返回根节点指针root。

node* create(int data[],int n) {
	node *root=NULL;
	for(int i=0;i<n;i++) {
		insert(root,x);
	}
	return root;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值