数据结构之二叉树的基本操作(深度拷贝、求与二叉树有关值、查找)

上篇博客,写到了对二叉树进行销毁的地方,这篇博客主要是二叉树的深度拷贝和查找、求出二叉树的相关内容。

求二叉树相关内容

//求二叉树节点个数

size_t _TreeSize(TreeNode* root, size_t* count)
{
    if(count == NULL) {
        return -1;
    }
    if(root == NULL) {
        return *count;
    }
    (*count)++;//递归几次就有多少节点,所以计数器++
    _TreeSize(root->lchild, count);
    _TreeSize(root->rchild, count);
    return *count;
}

size_t TreeSize(TreeNode* root)
{
    if(root == NULL) {
        return 0;   
    }
    size_t count = 0;//定义计数器
    return _TreeSize(root, &count);
}
//求二叉树叶子节点个数

//这里转化思想,要求二叉树叶子节点个数
//转化为求二叉树左子树叶子节点个数与右子树叶子节点个数
//递归调用,如果是叶子节点返回1
//同样,这里我们也可以用上面求二叉树节点个数的方式
//定义计数器,这里不做赘述

size_t TreeLeafSize(TreeNode* root)
{
    if(root == NULL) {
        return 0;
    }
    if(root->lchild == NULL && root->rchild == NULL) {
        return 1;
    }
    return TreeLeafSize(root->lchild) + TreeLeafSize(root->rchild);
}
//求二叉树第K层节点个数

//这里仍旧用到了转化思想
//要求第K层节点个数,那么就求第K-1层节点
//直至K=1,递归结束

size_t TreeKLevelSize(TreeNode* root, int K)
{
    if(root == NULL) {
        return 0;
    }
    if(K == 1) {
        return 1;
    }
    return TreeKLevelSize(root->lchild, K-1) + TreeKlevelSize(root->rchild, K-1);
}
//求二叉树的高度
//要求二叉树高度,可以转换为求二叉树左子树的高度
//再求二叉树右子树的高度
//最后比较

size_t TreeHeight(TreeNode* root)
{
    if(root == NULL) {
        return 0;
    }
    size_t lheight = TreeHeight(root->lchild);//这里定义两个高度,是为了在后面比较的时候可以直接比较内容,节省效率。
    size_t rheight = TreeHeight(root->rchild);
    return 1 + (lheight > rheight ? lheight : rheight);
}

深度拷贝二叉树

我们的拷贝分为深度拷贝与浅度拷贝。浅度拷贝相当于定义一个指针指向要拷贝的内容。节省时间但是并不是真正意义上的拷贝。而深度拷贝,是开辟空间,将源内容拷贝至目标空间。

//深度拷贝二叉树

TreeNode* TreeClone(TreeNode* root) 
{
    if(root == NULL) {
        return NULL;
    }
    TreeNode* new_node = CreatTreeNode(root->data);
    new_node->lchild = TreeClone(root->lchild);
    new_node->rchild = TreeClone(root->rchild);

    return new_node;
}

二叉树的查找

//查找二叉树

TreeNode* TreeFind(TreeNode* root, TreeNodeType to_find)
{
    if(root == NULL) {
        return NULL;
    }

    SeqQueue queue;//我们这里利用层序遍历的方式进行查找
    SeqQueueType front;//因为层序遍历利用的循环
    SeqQueueInit(&queue);//这样可以帮助我们提高效率

    while(1) {
        SeqQueueGetFront(&queue, &front);
        if(front->data = to_find) {
            return front;
        }
        if(front->lchild != NULL) {
            SeqQueuePush(front->lchild);
        }
        if(front->rchild != NULL) {
            SeqQueuePush(front->rchild);
        }
        SeqQueuePop(&queue);
    }
}
//查找某个节点的父节点
//这里思路与上面的查找相同,只是判断条件不同

TreeNode* Parent(TreeNode* root, TreeNode* node)
{
  if(root == NULL) {
    return NULL;
  }
  if(root == node) {
    return NULL;
  }

  SeqQueue queue;
  SeqQueueType front;
  SeqQueueInit(&queue);
  SeqQueuePush(&queue,root);

  while(1) {
    SeqQueueGetFront(&queue, &front);
    if(front->lchild == node || front->rchild == node) {
      return front;
    }
    if(front->lchild == NULL && front->rchild == NULL) {
      return NULL;
    }
    if(front->lchild != NULL) {
      SeqQueuePush(&queue, front->lchild);
    }
    if(front->rchild != NULL) {
      SeqQueuePush(&queue, front->rchild);
    }
    SeqQueuePop(&queue);
  }
  return NULL;
}

欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/liuchenxia8/article/details/80136743
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞