二叉树的基本操作

目录

1.二叉树的定义

2.二叉树的性质

3.二叉树的构建

先序和中序

中序和后序

4.二叉树的遍历

先序

中序

后序


1.二叉树的定义

    二叉树(Binary Tree)是另一种树形结构,它的特点是每个结点至多只有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

    满二叉树:一棵深度为k且有2^{k}-1个结点的二叉树称为满二叉树。

    完全二叉树:深度为k,有n个结点,并且每一个结点都与深度为k的满二叉树中编号从1-n的结点一一对应,称为完全二叉树。

 

2.二叉树的性质

    性质1:二叉树的第i层至多有2^{i-1}个结点(i\geq 1

    性质2:深度为k的二叉树至多有2^{k}-1个结点(k\geqslant1

    性质3:对任何一棵二叉树T,如果其终端结点(叶子结点,即没有左右子树0)数为n_{0},度为2的结点数为n_{2},则n_{0}= n_{2}+1

    性质4:具有n个结点的完全二叉树的深度为\left \lfloor \log{_{2}}n \right \rfloor+1

3.二叉树的构建

    二叉树的二叉链表存储结构

 typedef struct BiTNode
 {
      int val;
      struct TreeNode *left;
      struct TreeNode *right;
  }BiTNode,*BiTree;

先序和中序

    由二叉树的先序遍历和中序遍历结果,构建出此二叉树

例  给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

 

 

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
leetcode题库105
 

struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize)
{
    if(preorderSize == 0 || inorderSize == 0)
        return NULL;
    
    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    int index;
    root -> val = preorder[0];
    for(index = 0;index < inorderSize;index++)//寻找根结点在中序遍历的位置inorder
        if(inorder[index] == preorder[0])
            break;
    root -> left = buildTree(preorder + 1,index,inorder,index);
    root -> right = buildTree(preorder + index + 1,preorderSize - index - 1,inorder + index + 1,preorderSize - index - 1);
    return root;
}

例  先序ABEIDJ  中序EBIADJ      输出   后续遍历结果为EIBDJA

c++版

c++中find()函数和substr()函数(截取字符串)的用法

int main()
{

	string s1 = "sldbxu";
	cout << s1.find('d') << endl;8//打印s1字符串中字符d的下标
	cout << s1.substr(2) << endl;//由下标2的字符开始,打印至\0
	cout<< s1.substr(2, 3) << endl;//由下标2的字符开始,打印3个
	return 0;
}


结果为
2
dbxu
dbx

完整代码

#include<iostream>
using namespace std;


void print(string s1,string s2)
{
	if (s1 == "\0" || s2 == "\0")
		return;
	//根结点
	int x = s2.find(s1[0]);
	//左子树
	print(s1.substr(1,x ),s2.substr(0,x));
	//右子树
	print(s1.substr(x + 1), s2.substr(x + 1));

	cout << s1[0];
}

int main()
{
	string s1, s2;
	cin >> s1 >> s2;
	print(s1, s2);
	return 0;
}

中序和后序

   给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

   输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
   输出:[3,9,20,null,null,15,7]
leetcode题库106
 

struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize)
{
    
    if(inorderSize == 0 || postorderSize == 0)
        return NULL;
    
    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    int index;
    root -> val = postorder[postorderSize-1];
    for(index = 0;index < inorderSize;index++)//寻找根结点在中序遍历的位置inorder
        if(inorder[index] == postorder[postorderSize-1])
            break;
    root -> left = buildTree(inorder,index,postorder,index);
    root -> right = buildTree(inorder + index +1,inorderSize - index -1,postorder + index,postorderSize - index - 1);
    return root;

}

   

4.二叉树的遍历

    按编号顺序依次输入root = [5,6,7,null,1,2] 

    先序输出:[5,6,1,7,2]  中序输出:[6,1,5,2,7]  后序输出:[1,6,2,7,5]

先序

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 
void preOrder(struct TreeNode* root, int* res, int* resSize){   //前序遍历函数
    if(root == NULL)                                            //树为空返回
        return ;
    res[*resSize] = root->val;                                  //遍历根结点
    (*resSize)++;
    preOrder(root->left, res, resSize);                         //前序遍历左子树
    preOrder(root->right, res, resSize);                        //前序遍历右子树
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* res = (int*)malloc(sizeof(int) * 1000);                //存放遍历结果
    *returnSize = 0;
    preOrder(root, res, returnSize);
    return res;
}

中序

 void inorder(struct TreeNode* root, int* res, int* resSize){   //前序遍历函数
    if(root == NULL)                                            //树为空返回
        return ;
    
    inorder(root->left, res, resSize);                         //前序遍历左子树
     res[*resSize] = root->val;                                  //遍历根结点
    (*resSize)++;
    inorder(root->right, res, resSize);                        //前序遍历右子树
}

int* inorderTraversal(struct TreeNode* root, int* returnSize){
  int* res = (int*)malloc(sizeof(int) * 1000);                //存放遍历结果
    *returnSize = 0;
    inorder(root, res, returnSize);
    return res;
}

后序

 void postorder(struct TreeNode* root, int* res, int* resSize){   //前序遍历函数
    if(root == NULL)                                            //树为空返回
        return ;
   
    postorder(root->left, res, resSize);                         //前序遍历左子树
    postorder(root->right, res, resSize);                        //前序遍历右子树
    res[*resSize] = root->val;                                  //遍历根结点
    (*resSize)++;
}

int* postorderTraversal(struct TreeNode* root, int* returnSize){
 int* res = (int*)malloc(sizeof(int) * 1000);                //存放遍历结果
    *returnSize = 0;
    postorder(root, res, returnSize);
    return res;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种非常重要的数据结构,它的基本操作包括创建、销毁、遍历、查找等。下面是二叉树基本操作的实现方法: 1. 创建二叉树:通过前序遍历的数组构建二叉树,其中 '#' 表示空节点。具体实现方法可以参考引用中的 BinaryTreeCreate 函数。 2. 销毁二叉树:遍历二叉树,依次释放每个节点的内存空间。具体实现方法可以参考引用中的 BinaryTreeDestory 函数。 3. 遍历二叉树二叉树的遍历包括前序遍历、中序遍历、后序遍历和层序遍历。具体实现方法可以参考引用中的 BinaryTreePrevOrder、BinaryTreeInOrder、BinaryTreePostOrder 和 BinaryTreeLevelOrder 函数。 4. 查找二叉树节点:在二叉树中查找值为 x 的节点,具体实现方法可以参考引用中的 BinaryTreeFind 函数。 5. 计算二叉树节点个数:计算二叉树中节点的个数,具体实现方法可以参考引用[2]中的 BinaryTreeSize 函数。 6. 计算二叉树叶子节点个数:计算二叉树中叶子节点的个数,具体实现方法可以参考引用中的 BinaryTreeLeafSize 函数。 7. 计算二叉树第 k 层节点个数:计算二叉树中第 k 层节点的个数,具体实现方法可以参考引用中的 BinaryTreeLevelKSize 函数。 8. 判断二叉树是否是完全二叉树:判断二叉树是否是完全二叉树,具体实现方法可以参考引用中的 BinaryTreeComplete 函数。 9. 计算二叉树的深度:计算二叉树的深度,具体实现方法可以参考引用中的 BinaryTreeDeep 函数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值