15、二叉排序树的查找+插入+删除+层次遍历操作

/*
二叉排序树插入:
  1、该树为空,直接将结点插入即可
  2、否则,继续在树上进行查找操作
    a.树中已有,不再执行插入操作
    b.树中没有,查找至某个结点的左子树或右子树为空时,插入作为左子树或右子树
二叉排序树生成操作:
  进行查找和生成操作,知道序列生成完为止
*/
/*
    1、建立一棵有序的二叉排序树BiSTree
                        root(根节点)
                       /            \
        leftchild(左子树)     rightChild(右子树)
        其中左子树上的元素都 < 根节点,右子树上的元素都 >= 根节点
        性质:对二叉排序树进行中序遍历,元素从小大大
    2、查找二叉树中的元素key
    (1)BiSTree是空树
        返回空指针
    (2)BiSTree是非空树
        将key和根节点进行比较
            a.key < root: 和左子树进行比较
            b.key > root: 和右子树进行比较
            c.key = root; 返回指向根节点的指针
*/

// 1、建立一棵有序的二叉排序树BiSTree
// a.二叉树结点结构
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct BiSTreeNode
{
  int data;
  BiSTreeNode *leftchild;
  BiSTreeNode *rightchild;
};
// b.二叉树--找到根节点就建立起了二叉树
typedef BiSTreeNode *BiSTree;
// c.初始化二叉树
void InitBiSTree(BiSTree &b);

// 2、查找二叉树中的元素key
BiSTree Search_BiSTree(BiSTree &root, int key);

// 3、二叉树的插入操作
void Insert_BiSTree(BiSTree &root, int key);

// 4、二叉树生成操作
void Create_BiSTree(BiSTree &root, vector<int> v);

// 5、二叉树的删除操作
void Del_BiSTree(BiSTree &root, int key);

// 6、层次遍历二叉树---检查二叉树是否正确
void LevelOreder_BiSTree(BiSTree &root);

int main()
{
  BiSTree b = nullptr;
  // InitBiSTree(b);
  // Insert_BiSTree(b, 55);
  Create_BiSTree(b, {55, 58, 88, 33, 45});
  // cout << Search_BiSTree(b, 88)->data << endl;
  // Del_BiSTree(b, 55);
  LevelOreder_BiSTree(b);

  return 0;
}
// c.初始化二叉树
/*
        62
       /  \
      58   88
*/
void InitBiSTree(BiSTree &b)
{
  BiSTreeNode *n1 = new BiSTreeNode({62, nullptr, nullptr});
  BiSTreeNode *n2 = new BiSTreeNode({58, nullptr, nullptr});
  BiSTreeNode *n3 = new BiSTreeNode({88, nullptr, nullptr});
  b = n1;
  n1->leftchild = n2;
  n1->rightchild = n3;
}

BiSTree Search_BiSTree(BiSTree &root, int key)
{
  // 查找失败,返回空树
  if (!root)
    return nullptr;
  else
  {
    // 树不空 递归查找
    //       root->data < key 去root的左子树查找
    //       root->data > key 去root的右子树查找
    //       root->data = key 查找成功 结束
    if (key == root->data)
    {
      cout << "查找成功!" << endl;
      return root;
    }
    else if (key < root->data)
      return Search_BiSTree(root->leftchild, key);
    else
      return Search_BiSTree(root->rightchild, key);
  }
}

// 3、二叉树的插入操作
void Insert_BiSTree(BiSTree &root, int key)
{
  // 节点已经存在---不用插入
  // 插入-空节点的位置-查找失败的位置
  if (!root)
  {
    root = new BiSTreeNode({key, nullptr, nullptr});
    return; // 递归出口
  }
  else
  {
    if (key < root->data)
      return Insert_BiSTree(root->leftchild, key);
    else if (key > root->data)
      return Insert_BiSTree(root->rightchild, key);
    return;
  }
}

// 4、二叉树生成操作
void Create_BiSTree(BiSTree &root, vector<int> v)
{
  int s = v.size();
  for (int i = 0; i < s; ++i)
  {
    Insert_BiSTree(root, v[i]);
  }
}

// 5、二叉树的删除操作
void Del_BiSTree(BiSTree &root, int key)
{
  // 1、没有找到该节点,不做任何操作
  if (!root)
    return;
  // 2、key < root->data: 从左子树上寻找结点
  if (key < root->data)
    Del_BiSTree(root->leftchild, key);
  // 3、key > root->data: 从右子树上寻找结点
  else if (key > root->data)
    Del_BiSTree(root->rightchild, key);
  // 4、key = root->data: 找到该结点
  else{//怎么删除该节点呢?
    //寻找其双亲节点,不现实,需要重新遍历-----找某个结点值代替它 释放某个结点
    //a.叶子结点,可以直接进行删除操作
    BiSTree tmp = root;
    if (!root->leftchild && !root->rightchild)
    {
      root = nullptr;
      cout << tmp->data;
      delete tmp;
      cout << "删除成功!" << endl;
      return;
    }
    //b.该节点没有左子树
    else if (!root->leftchild)
    {
      //寻找右子树上的最小值---代替为找到的节点的值---删除该节点
      tmp = root;
      BiSTree pre = root;
      BiSTree cur = root->rightchild;
      while (cur)
      {
        pre = cur;
        cur = cur->leftchild;
      }
      tmp->data = pre->data;
      Del_BiSTree(root->rightchild, pre->data);
    }
    //c.改结点没有右子树或者有左子树和右子树
    else 
    {
      //寻找左子树上的最大值---代替为找到的节点的值---删除该节点
      tmp = root;
      BiSTree pre = root;
      BiSTree cur = root->leftchild;
      while (cur)
      {
        pre = cur;
        cur = cur->rightchild;
      }
      root->data = pre->data;
      Del_BiSTree(root->leftchild, pre->data);
    }
  }
}

// 6、层次遍历二叉树---检查二叉树是否正确
void LevelOreder_BiSTree(BiSTree &root)
{
  // 1、二叉树为空,不做操作直接返回
  if (!root)
    return;
  // 2、不为空:根节点入队---根节点出队---根节点的孩子节点入队
  else{
    queue<BiSTree> q;
    q.push(root);
    BiSTree tmp = nullptr;
    while (!q.empty())
    {
      tmp = q.front();
      q.pop();
      cout << tmp->data << "出队" << endl;
      if (tmp->leftchild)
        q.push(tmp->leftchild);
      if (tmp->rightchild)
        q.push(tmp->rightchild);
    } 
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值