当前位置: 首页 > news >正文

怎么建设境外网站泸州网站建设报价

怎么建设境外网站,泸州网站建设报价,深圳营销型网站联系方式,asp网站伪静态文件下载目录 树的概念 二叉树 二叉树性质 二叉树的遍历 前序遍历 中序遍历 后序遍历 层序遍历 二叉树节点个数 二叉树叶子节点个数 二叉树高度 二叉树第k层节点个数 二叉树查找值为x的节点 判断二叉树是否是完全二叉树 二叉树销毁 树的概念 树型结构是一类重要的非线性…

目录

树的概念

二叉树

二叉树性质

二叉树的遍历

前序遍历

中序遍历 

后序遍历

层序遍历

 二叉树节点个数

二叉树叶子节点个数

二叉树高度

二叉树第k层节点个数

二叉树查找值为x的节点

判断二叉树是否是完全二叉树

二叉树销毁


树的概念

树型结构是一类重要的非线性数据结构。其中以树和二叉树最为常用,直观看来,树是以分支关系定义的层次结构。把它叫做“树”是因为它常看起来像一棵倒挂的树,也就是说它常是根朝上,而叶朝下的。

树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树来形象表示。树在计算机领域中也得到广泛应用,如在操作系统中,可用树来表示文件系统的结构。又如在数据库系统中,树形结构也是信息的重要组织形式之一 。

树在不同领域也有不同的定义。

1、在数学中,树是一种无向图,其中不存在环路(即无回路),且任意两个结点之间有且仅有一条简单路径相连 [2]。这种定义主要用于图论和离散数学中,用于研究树的性质和特征。

2、在操作系统中,树是一种用于表示文件系统的结构,其中根目录位于树的顶部,子目录和文件位于根目录下 [3]。这种定义主要用于操作系统设计和文件管理。

3、在数据库中,树是一种用于表示层次关系的数据结构,树结构常用于实现数据库的索引、表示层次数据关系(如组织结构、分类目录)以及优化查询操作。这种定义主要用于数据库设计和数据管理,以提高数据检索效率和结构化数据的存储。

基本术语:

  • 1.结点:包含一个数据元素及若干指向其子树的分支;
  • 2.结点的度:一个结点拥有的子树的数目;
  • 3.叶子或终端结点:度为0的结点;
  • 4.非终端结点或分支结点:度不为0的结点;
  • 5.树的度:树内各结点的度的最大值;
  • 6.孩子结点或子结点:结点的子树的根称为该结点的孩子结点或子结点;
  • 7.双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的双亲结点或父结点;
  • 8.兄弟结点:同一个双亲的孩子之间互称兄弟;
  • 9.祖先结点:从根到该结点所经分支上的所有结点;
  • 10.子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙;
  • 11.结点的层次:从根开始定义起,根为第一层,根的孩子为第二层。若某结点在第 L 层.则其子树的根就在第 L + 1层;
  • 12.堂兄弟结点:其双亲在同一层的结点互为堂兄弟;
  • 13.树的深度或高度:树中结点的最大层次;
  • 14.森林:由m(m > 0)棵互不相交的树的集合称为森林;
  • 15.有序树和无序树:树中结点的各子树从左到右是有次序的,不能互换,称该树为有序树,否则称为无序树;
  • 16.路径和路径长度:路径是由树中的两个结点之间的结点序列构成的。而路径长度是路径上所经过的边的个数

二叉树

学习二叉树结构,最简单的方式就是遍历。所谓二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的结点进行相应的操作,并且每个结点只操作一次。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

二叉树性质

1.若规定根节点的层数为1,则一棵非空二叉树上的第 i 层最多有2^{(i-1)}个节点

2.若规定根节点的层数为1,则深度为 h 的二叉树的最大节点数是2^{h}-1

3.对任何一棵二叉树,如果度为0其叶节点个数为n_{0},度为2的分支结点个数为n_{2},则有n_{0} = n_{2} + 1 

4.若规定根节点的层数为1,具有 n 个节点的满二叉树的深度,h = \log_{2}(N+1)

5.对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所以结点从0开始编号,则对于序号为 i 的结点有:

  1. 若 i > 0, i  位置结点的双亲序号:(i - 1) / 2;  i = 0,   i 为根节点编号,无双亲结点。
  2. 若 2i+ 1 < n ,左孩子序号 2i+ 1, 2i+ 1 >= n 则为左孩子
  3. 若 2i+ 2 < n,右孩子序号:2i+ 2,2i+ 1 >= n 则无右孩子

二叉树的遍历

前序遍历

前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。

//前序
void Preorder(BTNode* root)
{if (root == NULL){printf("N ");return;}printf("%d ", root->data);Preorder(root->left);Preorder(root->right);
}
中序遍历 

中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。

//中序
void Inorder(BTNode* root)
{if (root == NULL){printf("N ");return;}Inorder(root->left);printf("%d ", root->data);Inorder(root->right);
}
后序遍历

后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。

//后序
void Posorder(BTNode* root)
{if (root == NULL){printf("N ");return;}Posorder(root->left);Posorder(root->right);printf("%d ", root->data);
}

层序遍历

层序遍历(也称为广度优先遍历)是二叉树遍历的一种方法,其基本思想是从根节点开始,按照从上到下、从左到右的顺序访问二叉树的每一层节点‌。‌

层序遍历通常使用队列来实现:

  1. 将根节点放入队列中。
  2. 当队列不为空时,循环执行以下操作:
    • 从队列中弹出一个节点,访问该节点。
    • 如果该节点有左子节点,将左子节点加入队列。
    • 如果该节点有右子节点,将右子节点加入队列。
  3. 继续执行步骤2,直到队列为空。
void TreeLevelOrder(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){//上一层带下一层BTNode* front = QueueFront(&q);QueuePop(&q);printf("%d ", front->data);if (front->left)QueuePush(&q, front->left);if (front->right)QueuePush(&q, front->right);}QueueDestory(&q);
}

 二叉树节点个数

int BinaryTreeSize(BTNode* root)
{static int size = 0;if (root == NULL)return 0;else++size;BinaryTreeSize(root->left);BinaryTreeSize(root->right);return size;
}

不能这样写,这样写每次调用这个函数都会累加

可以这样写

int size = 0;
int BinaryTreeSize(BTNode* root)
{if (root == NULL)return 0;else++size;BinaryTreeSize(root->left);BinaryTreeSize(root->right);return size;
}

但是每次调用这个函数的时候,都要重置一下size。

最好的方法 分治递归

int BinaryTreeSize(BTNode* root)
{return root == NULL ? 0 :BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

二叉树叶子节点个数

int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL)return 0;if (root->left == NULL && root->right == NULL)return 1;return BinaryTreeLeafSize(root->left) +BinaryTreeLeafSize(root->right);
}

 什么是叶子结点呢?通常来讲在一棵树里面,如果一个结点没有左子树和右子树,那么它就是叶子。左子树和右子树为空,那么叶子结点个数加1,返回给上一层。

二叉树高度

int BinaryTreeHeight(BTNode* root)
{if (root == NULL)return 0;return BinaryTreeHeight(root->left) > BinaryTreeHeight(root->right) ?BinaryTreeHeight(root->left) + 1 : BinaryTreeHeight(root->right) + 1;
}

 上面这种方法存在效率问题,原因是递归返回后函数栈帧会销毁,没有记录,

int BinaryTreeHeight(BTNode* root)
{if (root == NULL)return 0;int left = BinaryTreeHeight(root->left);int right = BinaryTreeHeight(root->right);return left > right ? left + 1 : right + 1;
}//int BinaryTreeHeight(BTNode* root)
//{
//	if (root == NULL)
//		return 0;
//	return fmax(BinaryTreeHeight(root->left), BinaryTreeHeight(root->right)) + 1;
//}

二叉树第k层节点个数

int BinaryTreeLevelKSize(BTNode* root, int k)
{if (root == NULL)return 0;if (k == 1)return 1;return BinaryTreeLevelKSize(root->left, k - 1) +BinaryTreeLevelKSize(root->right, k - 1);
}

求第k层结点个数,需要转化成当前问题和子问题。比如说,求第3层结点的个数,那么对这棵树的第一层来说,从它开始,求它向下的3层。然后k减1。对于第二层来说,求从它开始向下的第2层,k减1。对于第三层来说,就是求从它开始向下的第1层,为第1层时,返回1给上一层。

二叉树查找值为x的节点

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL)return NULL;if (root->data == x)return root;BTNode* ret1 = BinaryTreeFind(root->left, x);if (ret1)return ret1;BTNode* ret2 = BinaryTreeFind(root->right, x);if (ret2)return ret2;return NULL;
}

如果走到叶子节点的下一个,即root为空,就返回空。如果在左子树找到了,那么在右子树就没必要找了,就直接返回这个节点。但是一定要记录这个节点,因为递归返回会销毁函数栈帧,你不返回给上层这个找到的节点的记录,上层不知道你找到没有,就认为没有找到。继续返回给它的上层。 如果左子树没有找到,右子树也没有找到,就返回空。

判断二叉树是否是完全二叉树

需要用到层序遍历 

bool BinaryTreeComplete(BTNode* root)
{Queue q;QueueInit(&q);if (root)QueuePush(&q, root);while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);//遇到第一个空,就可以开始判断,如果队列中还有非空,那就不是完全二叉树if (front == NULL)break;  // 跳出循环,不再进行层序遍历QueuePush(&q, front->left);QueuePush(&q, front->right);}//开始判断队列中已有的数据while (!QueueEmpty(&q)){BTNode* front = QueueFront(&q);QueuePop(&q);//遇到非空,不是完全二叉树if (front){QueueDestory(&q);return false;}}QueueDestory(&q);return true;
}

首先定义一个队列,初始化队列,如果树不为空,那么让树的根结点入队列。通过一个while循环,可以把二叉树的所有节点全部遍历一遍,让它的节点入队列和出队列。这个while循环结束后吗,二叉树中的所有结点全部过了一遍,就算有 没有入队列的结点,也没有关系,因为这时只需要判断现在的队列中,是否还存在数据,如果存在,则说明不是完全二叉树,返回false。反之,说明为完全二叉树,返回true。这一层判断通过一个while循环完成。

二叉树销毁

void BinaryTreeDestory(BTNode** root)
{if (*root == NULL)return;BinaryTreeDestory((*root)->left);BinaryTreeDestory((*root)->right);free(*root);
}

二叉树的销毁可以看成一个后序遍历,先左子树销毁,然后右子树销毁,最后根节点销毁。

http://www.dtcms.com/a/555584.html

相关文章:

  • 网站后台上传文字图片泰安齐鲁人才网最新招聘网
  • 美食网站制作模板长春专用网站建设
  • 搜狗站长工具平台做网站的优势有哪些
  • 在线网站制作工具松岗网站建设
  • 做视频网站可行吗品牌网站建设荐选蝌蚪
  • ​极限挑战之一命速通并查集
  • 做网站三河南宁优化推广服务
  • asp网站后台产品管理中增加一个功能怎样修改做网站怎么开后台
  • 如何使用 Promise.all() 处理异步并发操作?
  • 网站维护要什么奇迹网站建设多少钱
  • 网站备案需要ftp吗公司网站 建设
  • 网站对公司有什么好处公司建设网站的案例分析
  • 深圳建设局网站注册结构师培训附件怎样推广一个产品
  • 少儿图书销售网站开发背景网站建设与维护流程
  • 在家做网站或ps挣钱接活烟台网站开发
  • 网站怎么添加二级域名wordpress xampp 本地 慢
  • 国内专门做情侣的网站商城出入合肥最新通知今天
  • 南宁网站推广v1青海住房和城乡建设厅网站首页
  • 挣钱网站一小时两百衡阳网站建设公司哪家好
  • 北京大龙建设集团有限公司网站首页wordpress安装linux
  • 怎么制作自己的网站网页企业网站的优劣势
  • 网站推送阳江招聘临时工
  • 网站建设高端网站一些好看的网页
  • 什么样的网站流量容易做wordpress开发复杂网站
  • 竞价单页 网站企业门户网站在信息系统架构中属于哪个层次
  • 无锡模板网站什么是网站版式
  • 网站用什么程序做的网站建设所需要软件
  • 自建网站的劣势h5网站建设模板
  • 电脑网页浏览器医疗网站优化公司
  • wordpress安卓版教程视频教程网站优化宝