二叉查找树递归定义:

二叉查找树是空树或不是空树
二叉查找树的左二叉查找树的值一定小于二叉查找树的值或左二叉查找树为空树
二叉查找树的右二叉查找树的值一定大于二叉查找树的值或右二叉查找树为空树

不维护父亲域的,坑爹啊。

放上代码:

#include <iostream>
#include <string>
using namespace std; #define NEW(d) new BST(d) struct BST {
BST *lc, *rc;
int data;
BST() : lc(0), rc(0) {}
BST(int d) : lc(0), rc(0), data(d) {}
}*root = NULL; typedef BST* tree; void insert(int d) {
if(root == NULL) { root = NEW(d); return;}
tree t, now = root;
//二分找到合适的位置,t是指向这个合适的位置的指针
while(now != NULL) {
t = now;
if(now-> data > d) now = now-> lc;
else now = now-> rc;
}
//插入新值到左边(或右边)
if(t-> data > d) t-> lc = NEW(d);
else t-> rc = NEW(d);
}
//没有父亲域的这个就是巨坑
void del(int d) {
tree t, q = root, rt = root;
while(rt != NULL && rt-> data != d) {
q = rt;
if(rt-> data > d) rt = rt-> lc;
else rt = rt-> rc;
}
//如果删除的是root
if(q == root) {delete root; root = NULL; return;}
//如果不存在
if(rt == NULL) return;
//如果有一边是空的,那么将另一棵子树拉上来即可,在这里,已经包含了当两边都是空树时
if(rt-> lc == NULL) {
if(q-> lc == rt) q-> lc = rt-> rc;
else q-> rc = rt-> rc;
delete rt;
return;
}
if(rt-> rc == NULL) {
if(q-> lc == rt) q-> lc = rt-> lc;
else q-> rc = rt-> lc;
delete rt;
return;
}
t = rt;
q = rt-> rc;
while(q-> lc) {
t = q;
q = q-> lc;
}
rt-> data = q-> data;
if(t != rt) t-> lc = q-> rc;
else t-> rc = q-> rc;
delete q;
} tree search(int d) {
tree ret = root;
while(ret != NULL && ret-> data != d) {
if(ret-> data > d) ret = ret-> lc;
else ret = ret-> rc;
}
return ret;
} tree max(){
if(root == NULL) return NULL;
tree ret = root;
while(ret-> rc) ret = ret-> rc;
return ret;
} tree min(){
if(root == NULL) return NULL;
tree ret = root;
while(ret-> lc) ret = ret-> lc;
return ret;
} void out(string str) {
cout << str;
} int main() {
out("1: insert\n2: del\n3: search\n4: max\n5: min\n");
int c, t;
tree a;
while(cin >> c) {
switch(c) {
case 1: cin >> t;
insert(t);
break;
case 2: cin >> t;
del(t);
break;
case 3: cin >> t;
if(search(t) == NULL) out("Not here\n");
else out("Is here!\n");
break;
case 4: a = max();
if(a != NULL) cout << a-> data << endl;
else out("Warn!\n");
break;
case 5: a = min();
if(a != NULL) cout << a-> data << endl;
else out("Warn!\n");
break;
default:
break;
}
}
return 0;
}

因为有些坑爹,所以还是写递归版的del

void del(tree& rt, int d) {
if(rt == NULL) return;
if(rt-> data > d) del(rt-> lc, d);
else if(rt-> data < d) del(rt-> rc, d);
else {
tree q, t;
if(rt-> lc == NULL) {
q = rt;
rt = rt-> rc;
delete q;
return;
}
if(rt-> rc == NULL) {
q = rt;
rt = rt-> lc;
delete q;
return;
}
q = rt-> rc, t = rt;
//找后继
while(q-> lc != NULL) {
t = q;
q = q-> lc;
}
rt-> data = q-> data;
//当后继就是右子女,那么要将后继的右子女接到节点右边
if(rt == t) t-> rc = q-> rc;
//否则就要给后继的父亲的左子女赋值为后继的右子女
else t-> lc = q-> rc;
delete q;
}
}

写个简洁的把,,,维护个父亲域。。旋转也好写了= =。

#include <iostream>
#include <string>
using namespace std; #define NEW(d) new BST(d) struct BST {
BST *lc, *rc, *pa;
int data;
BST() : lc(0), rc(0), pa(0) {}
BST(int d) : lc(0), rc(0), pa(0), data(d) {}
//BST operator= (BST& a) { lc = a.lc; rc = a.rc; pa = a.pa; data = a.data; return *this; }
}*root = NULL; typedef BST* tree; void insert(int d) {
if(root == NULL) { root = NEW(d); return;}
tree t, now = root;
//二分找到合适的位置,t是指向这个合适的位置的指针
while(now != NULL) {
t = now;
if(now-> data > d) now = now-> lc;
else now = now-> rc;
}
//插入新值到左边(或右边)
if(t-> data > d) t-> lc = NEW(d), t-> lc-> pa = t;
else t-> rc = NEW(d), t-> rc-> pa = t;
} tree search(int d) {
tree ret = root;
while(ret != NULL && ret-> data != d) {
if(ret-> data > d) ret = ret-> lc;
else ret = ret-> rc;
}
return ret;
} void del(int d) {
tree rt = search(d), t, q;
if(rt == root) { delete root; root = NULL; return; }
if(rt == NULL) return;
if(rt-> lc == NULL) {
if(rt-> pa-> lc == rt) rt-> pa-> lc = rt-> rc;
else rt-> pa-> rc = rt-> rc;
delete rt;
return;
}
if(rt-> rc == NULL) {
if(rt-> pa-> lc == rt) rt-> pa-> lc = rt-> lc;
else rt-> pa-> rc = rt-> lc;
delete rt;
return;
}
q = rt-> rc, t = rt;
while(q-> lc) {
t = q;
q = q-> lc;
}
rt-> data = q-> data;
if(t != rt) t-> rc = q-> rc;
else t-> lc = q-> rc;
delete q;
} tree max(){
if(root == NULL) return NULL;
tree ret = root;
while(ret-> rc) ret = ret-> rc;
return ret;
} tree min(){
if(root == NULL) return NULL;
tree ret = root;
while(ret-> lc) ret = ret-> lc;
return ret;
} void out(string str) {
cout << str;
} int main() {
out("1: insert\n2: del\n3: search\n4: max\n5: min\n");
int c, t;
tree a;
while(cin >> c) {
switch(c) {
case 1: cin >> t;
insert(t);
break;
case 2: cin >> t;
del(t);
break;
case 3: cin >> t;
if(search(t) == NULL) out("Not here\n");
else out("Is here!\n");
break;
case 4: a = max();
if(a != NULL) cout << a-> data << endl;
else out("Warn!\n");
break;
case 5: a = min();
if(a != NULL) cout << a-> data << endl;
else out("Warn!\n");
break;
default:
break;
}
}
return 0;
}

  

 

BST & Treap的更多相关文章

  1. hihocoder-平衡树·SBT

    http://hihocoder.com/problemset/problem/1337 #1337 : 平衡树·SBT 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 ...

  2. 模板库 ~ Template library

    TOC 建议使用 Ctrl+F 搜索 . 目录 小工具 / C++ Tricks NOI Linux 1.0 快速读入 / 快速输出 简易小工具 无序映射器 简易调试器 文件 IO 位运算 Smart ...

  3. fhq treap最终模板

    新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...

  4. COGS 2421.[HZOI 2016]简单的Treap 题解

    题目大意: 给定n个数及其优先级,求对应的符合最小堆性质的Treap的先序遍历. n<=500000. 解法: 目前为止我只想到了三种解法,其中第三种是正解. 1.暴力1 以优先级为关键字排序, ...

  5. Treap树的基础知识

    原文 其它较好的的介绍:堆排序  AVL树 树堆,在数据结构中也称Treap(事实上在国内OI界常称为Traep,与之同理的还有"Tarjan神犇发明的"Spaly),是指有一个随 ...

  6. Treap和名次树

    Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体.BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添 ...

  7. 斜堆,非旋转treap,替罪羊树

    一.斜堆 斜堆是一种可以合并的堆 节点信息: struct Node { int v; Node *ch[]; }; 主要利用merge函数 Node *merge(Node *x, Node *y) ...

  8. 查找——图文翔解Treap(树堆)

    之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会非常大,Treap树就是一种解决二叉搜索树可能深度过大的还有一种数据结构. T ...

  9. 数据结构录 之 BST的高级应用。

    BST就是二叉检索树,或者是二叉排序树,或者叫二叉搜索树等等. BST的平衡问题可以去学习AVL树或者Treap或者Splay这些平衡树. BST的一些高级应用: 1,求BST中比k小的数的个数: 只 ...

随机推荐

  1. Linux MySQL差异备份技巧

    MSSQL差异备份使用技巧 15 Apr 2013 所谓的差异备份,就是只备份最近一次备份之后到此次备份之前所增加的那一部分数据.打个比方我第N次备份后数据库存放的内容是ABCD,然后我第N+1次 备 ...

  2. Find Leaves of Binary Tree

    Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves ...

  3. RadioButtonList单选和RequiredFieldValidator验证是否选中

    <asp:RadioButtonList ID="Radio2" RepeatDirection="Horizontal" runat="ser ...

  4. maven项目 Java compiler level does not match the version of the installed Java project facet

    因工作的关系,Eclipse开发的Java项目拷来拷去,有时候会报一个很奇怪的错误.明明源码一模一样,为什么项目复制到另一台机器上,就会报“java compiler level does not m ...

  5. JS 保留小数点后面2位小数

    1. 最笨的办法....... [我就怎么干的.........] function get(){    var s = 22.127456 + "";    var str = ...

  6. c++关键字之#define typedef const

    [#define] #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查. [typedef] typedef只是为了增加可读性而为标识符另起的新名称 在自己的作用域内给一个已经存 ...

  7. Linux下配置Hadoop 1.2.1

    首先要下载hadoop的包,版本选择1.2.1的,下载地址为:http://mirrors.cnnic.cn/apache/hadoop/common/hadoop-1.2.1/ 这里可以下载hado ...

  8. 【VirtualBox】端口转发,ssh

    端口转发 VirualBox的设置 - 网络 - 端口转发 里面有主机IP.主机端口.子系统IP.子系统端口 设置后的含义是:当外部访问主机IP:主机端口后,将会把访问映射到虚拟机的子系统IP和子系统 ...

  9. iOS通过设置info.plist参数使用iTunes导入导出Documents目录下的文件

    参考网址: http://my.oschina.net/hmj/blog/112592 http://www.cnblogs.com/taintain1984/archive/2013/05/27/3 ...

  10. [Android Pro] Android签名与认证详细分析之二(CERT.RSA剖析)

    转载自: http://www.thinksaas.cn/group/topic/335449/ http://blog.csdn.net/u010571535/article/details/899 ...