二叉搜索树 I

本文介绍了二叉搜索树的概念,重点讨论了如何在二叉搜索树中插入新节点并保持其特性,以及如何通过中序和预序遍历打印键值。提供了一个C++程序示例来演示这些操作。
摘要由CSDN通过智能技术生成

题面

搜索树是支持动态集合操作的数据结构,包括插入、搜索、删除等。 因此,搜索树既可以用作字典,也可以用作优先级队列。

二叉搜索树是一种基本的搜索树。 二叉搜索树中的键总是以满足以下二叉搜索树属性的方式存储:

设 x 是二叉搜索树中的一个节点。 如果 y 是 x 左子树中的一个节点,则 y.key≤x.key。 如果 y 是 x 右子树中的一个节点,则 x.key≤y.key。

例如,属于包含 80 的节点的左子树的节点的键值小于或等于 80,属于右子树的节点的键值大于或等于 80。 二叉搜索树允许我们通过中序树遍历按排序顺序打印出树中的所有键。

二叉搜索树应该以这样的方式实现,即二叉搜索树的属性在通过插入和删除修改后继续保持。二叉搜索树可以用链接数据结构表示,其中每个节点都是一个对象。除了关键字段和卫星数据之外,每个节点还包含字段 left、right 和 p,分别指向对应于其左子节点、右子节点和父节点的节点。

要将新值 v 插入到二叉搜索树 T 中,我们可以使用如下伪代码所示的过程插入。插入过程传递一个节点 z,其中 z.key=v、z.left=NIL 和 z.right=NIL。该过程以将 z 插入到树中的适当位置的方式修改 T 和 z 的某些字段。

insert(T, z)
    y = NIL // parent of x
    x = 'the root of T'
    while x ≠ NIL
        y = x // set the parent
        if z.key < x.key
            x = x.left // move to the left child
        else 
            x = x.right // move to the right child
   z.p = y
   if y == NIL // T is empty
       'the root of T' = z
   else if z.key < y.key
       y.left = z // z is the left child of y
   else 
       y.right = z // z is the right child of y

编写一个程序,对二叉搜索树 T 执行以下操作。

insert k:将一个包含k作为key的节点插入到T中。
print:分别通过中序树遍历和预序树遍历打印二叉搜索树的键值。
你应该使用上面的伪代码来实现插入操作。 T在初始状态为空。

输入

在第一行中,给出了操作数 m。 在接下来的 m 行中,给出了由 insert k 或 print 表示的操作。

输出

对于每个打印操作,分别打印一行中序树遍历和预序树遍历得到的键列表。 在每个键之前放置一个空格字符。

约束

操作次数≤500,000
打印操作次数≤10。
−2,000,000,000≤key≤2,000,000,000
如果使用上述伪代码,二叉树的高度不会超过 100。
二叉搜索树中的键都是不同的。

输入样例

 

8 insert 30 insert 88 insert 12 insert 1 insert 20 insert 17 insert 25 print

输出样例

 

1 12 17 20 25 30 88 30 12 1 20 17 25 88

#include<bits/stdc++.h>
using namespace std;
#define N 1000005
#define NIL -1
struct node{
    int data,parent,biao;
    int lchild,rchild;
}tree[N];
int root;
void insert(int z,int u){
    int y=0;
    int x=root;
    if(!root){
        root=z;
        return ;
    }
    while(x!=NIL){
        y=x;
        if(tree[x].data<u){
            x=tree[x].rchild;
        }else{
            x=tree[x].lchild;
        }
    }tree[z].parent=y;
    if(u<tree[y].data){
        tree[y].lchild=z;
    }else{
        tree[y].rchild=z;
    }
}
void middle(int u){
    if(tree[u].lchild!=NIL){
        middle(tree[tree[u].biao].lchild);
    }cout<<tree[u].data<<' ';
    if(tree[u].rchild!=NIL){
        middle(tree[tree[u].biao].rchild);
    }
}
void first(int u){
    cout<<tree[u].data<<' ';
    if(tree[u].lchild!=NIL){
        first(tree[tree[u].biao].lchild);
    }if(tree[u].rchild!=NIL){
        first(tree[tree[u].biao].rchild);
    }
}
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        tree[i].lchild=tree[i].data=tree[i].rchild=NIL;
    }
    int sum=0;
    while(n--){
        string a;
        cin>>a;
        int x;
        if(a=="insert"){
            cin>>x;
            sum++;    
            tree[sum].data=x;
            tree[sum].biao=sum;
            insert(sum,x);    
        }else{
            middle(root);
            cout<<endl;
            cout<<' ';
            first(root);
        }
    } 
    return 0;
}

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值