树及二叉树

2024-01-14 19:20
文章标签 二叉树 树及

本文主要是介绍树及二叉树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 树的概念和结构
    • 树的概念
    • 树的相关概念
  • 二叉树的概念和结构
    • 概念
    • 特殊的二叉树
    • 二叉树的性质
    • 二叉树的存储结构
      • 顺序存储
      • 链式存储
  • 二叉树的顺序结构及实现
    • 二叉树的顺序结构
    • 堆的概念及结构
  • 二叉树链式结构的实现
    • 二叉树的遍历

树的概念和结构

树的概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
在这里插入图片描述

树的相关概念

  • 节点的度:一个节点含有的子树的个数称为该节点的度;
  • 叶节点或终端节点:度为0的节点称为叶节点;
  • 非终端节点或分支节点:度不为0的节点;
  • 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
  • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点;
  • 树的度:一棵树中,最大的节点的度称为树的度;
  • 树的高度或深度:树中节点的最大层次;
  • 堂兄弟节点:双亲在同一层的节点互为堂兄弟;
  • 节点的祖先:从根到该节点所经分支上的所有节点;
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
  • 森林:由m(m>0)棵互不相交的树的集合称为森林;

二叉树的概念和结构

概念

一棵二叉树是结点的一个有限集合,该集合:

  1. 为空 , 即为空树
  2. 由一个根节点加上两棵别称为左子树和右子树的二叉树组成
    在这里插入图片描述在这里插入图片描述
    从上图可以看出:
  3. 二叉树不存在度大于2的结点
  4. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树

特殊的二叉树

  • 满二叉树
    一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。
    在这里插入图片描述
  • 完全二叉树
    完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。
    在这里插入图片描述

二叉树的性质

1: 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有 个结点.
2:若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 .
3: 对任何一棵二叉树, 如果度为0其叶结点个数为 , 度为2的分支结点个数为 ,则有 = +1
4: 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= . (ps: 是log以2为底,n+1为对数)
5: 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

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

二叉树的存储结构

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。

顺序存储

顺序结构结构存储就是使用 数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
在这里插入图片描述

链式存储

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,目前我们使用二叉链。
在这里插入图片描述

二叉树的顺序结构及实现

二叉树的顺序结构

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

堆的概念及结构

如果有一个关键码的集合K = { , , ,…, },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足: <= 且 <= ( >= 且 >= ) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

堆的相关知识

二叉树链式结构的实现

二叉树的遍历

在这里插入图片描述

  1. 先序遍历
    遍历顺序:根 -> 左子树 -> 右子树

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

//前序遍历
void BinaryPrevOrder(BTNode* root)
{if (root == NULL){return;}//根->左子树->右子树printf("%c ", root->data);BinaryPrevOrder(root->left);BinaryPrevOrder(root->right);
}
  1. 中序遍历
    遍历顺序:遍历顺序:左子树 -> 根 -> 右子树

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

void BinaryInOrder(BTNode* root)
{if (root == NULL){return;}//左子树->根->右子树BinaryInOrder(root->left);printf("%c ", root->data);BinaryInOrder(root->right);
}
  1. 后序遍历
    遍历顺序:左子树 -> 右子树 -> 根

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

//后序遍历
void BinaryPostOrder(BTNode* root)
{if (root == NULL){return;}//左子树->右子树->根BinaryPostOrder(root->left);BinaryPostOrder(root->right);printf("%c ", root->data);
}
  1. 层序遍历

层序遍历,自上而下,从左往右逐层访问树的结点的过程就是层序遍历。在这里插入图片描述

void BinaryTreeLevelOrder(BTNode* root)
{Queue q;QueueInit(&q);assert(root);QueuePush(&q, root);while(!QueueEmpty(&q)){BTNode *temp= QueueFront(&q);printf("%c ",temp->_data);if(temp->_left){QueuePush(&q,temp->_left);}if(temp->_right){QueuePush(&q,temp->_right);}QueuePop(&q);}QueueDestory(&q);
}

二叉树的相关函数

BTNode* BuyNode(BTDataType x)
{BTNode* node = (BTNode*)malloc(sizeof(BTNode));assert(node);node->_data = x;node->_left = NULL;node->_right = NULL;return node;
}// 二叉树节点个数
int BinaryTreeSize(BTNode* root)
{if(root==NULL){return 0;}if(root->_left==NULL&&root->_right==NULL){return 1;}return BinaryTreeSize(root->_left)+BinaryTreeSize(root->_right)+1;
}// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if(root==NULL){return NULL;}if(root->_data==x){return root;}return  BinaryTreeFind(root->_left, x);return BinaryTreeFind(root->_right,x);}// 二叉树第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);
}// 二叉树叶子节点个数
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);
}// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{if(root==NULL){return 1;}Queue q;QueueInit(&q);QueuePush(&q,root);while(!QueueEmpty(&q)){BTNode *temp= QueueFront(&q);QueuePop(&q);if(temp==NULL){break;}QueuePush(&q,temp->_left);QueuePush(&q,temp->_right);}while(!QueueEmpty(&q)){BTNode *temp= QueueFront(&q);QueuePop(&q);if(temp!=NULL){printf("不是完全二叉树\n");return 0;}}printf("是完全二叉树\n");return 1;
}
//求二叉树的高度
int BinaryTreeHeight(BTNode*root)
{if(root==NULL){return 0;}if(root->_right==NULL&&root->_left==NULL){return 1;}return (BinaryTreeHeight(root->_left)>=BinaryTreeHeight(root->_right) ? BinaryTreeHeight(root->_left)+1 :BinaryTreeHeight(root->_right)+1);
}

这篇关于树及二叉树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/606246

相关文章

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

在二叉树中找到两个节点的最近公共祖先(基于Java)

如题  题解 public int lowestCommonAncestor(TreeNode root, int o1, int o2) {//记录遍历到的每个节点的父节点。Map<Integer, Integer> parent = new HashMap<>();Queue<TreeNode> queue = new LinkedList<>();parent.put(roo

数据结构--二叉树(C语言实现,超详细!!!)

文章目录 二叉树的概念代码实现二叉树的定义创建一棵树并初始化组装二叉树前序遍历中序遍历后序遍历计算树的结点个数求二叉树第K层的结点个数求二叉树高度查找X所在的结点查找指定节点在不在完整代码 二叉树的概念 二叉树(Binary Tree)是数据结构中一种非常重要的树形结构,它的特点是每个节点最多有两个子节点,通常称为左子节点和右子节点。这种结构使得二叉树在数据存储和查找等方面具

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

222.完全二叉树的节点个数

(写给未来遗忘的自己) 题目: 代码: class Solution {public:int countNodes(TreeNode* root) {queue<TreeNode*>node_que;if(root==nullptr) return 0;node_que.push(root);int result;while(!node_que.empty()){int layer_s

代码随想录 -- 二叉树 -- 平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode) 思路:仍然是递归调用 1. 定义一个递归函数 count 用来计算二叉树的层数 2. isBalanced 函数:如果传入根节点为空返回真;如果根节点 | 左子树的层数 - 右子树的层数 | 大于1,返回假;最后返回根节点左子树、右子树是否是平衡二叉树。 class Solution(object):def count(self,root

【数据结构】你真的学会了二叉树了吗,来做一做二叉树的算法题及选择题

文章目录 1. 二叉树算法题1.1 单值二叉树1.2 相同的树1.3 另一棵树的子树1.4 二叉树的遍历1.5 二叉树的构建及遍历 2. 二叉树选择题3. 结语 1. 二叉树算法题 1.1 单值二叉树 https://leetcode.cn/problems/univalued-binary-tree/description/ 1.2 相同的树 https://leet

二叉树的层次遍历(10道)

(写给未来遗忘的自己) 102.二叉数的层序遍历(从上到下) 题目: 代码: class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> result; queue<TreeNode*> node; if (root == nullptr) {

求二叉树的深度——(力扣c语言)

题目如下: 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root = [3,9,20,null,null,15,7]输出:3 示例 2: 输入:root = [1,null,2]输出:2 题目解析: 上题就是要利用递归对目标进行访问找到叶子节点之后记录并返回到根节点之后对左右两个