zoukankan      html  css  js  c++  java
  • BST & Treap

    二叉查找树递归定义:

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

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

    放上代码:

    #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
    2: del
    3: search
    4: max
    5: min
    ");
    	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
    ");
    				else out("Is here!
    ");
    				break;
    		case 4: a = max();
    				if(a != NULL) cout << a-> data << endl;
    				else out("Warn!
    ");
    				break;
    		case 5: a = min();
    				if(a != NULL) cout << a-> data << endl;
    				else out("Warn!
    ");
    				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
    2: del
    3: search
    4: max
    5: min
    ");
    	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
    ");
    				else out("Is here!
    ");
    				break;
    		case 4: a = max();
    				if(a != NULL) cout << a-> data << endl;
    				else out("Warn!
    ");
    				break;
    		case 5: a = min();
    				if(a != NULL) cout << a-> data << endl;
    				else out("Warn!
    ");
    				break;
    		default:
    				break;
    		}
    	}
    	return 0;
    }
    

      

     

  • 相关阅读:
    Java实现 洛谷 P1423 小玉在游泳
    Java设置session超时(失效)的时间
    How Tomcat works — 八、tomcat中的session管理
    三种常用的MySQL建表语句
    mysql和oracle的区别(功能性能、选择、使用它们时的sql等对比)
    oracle 基础表 mysql版
    oracle员工表和部门表基本操作
    Oracle
    java生成6位随机数
    用Ajax图片上传、预览、修改图片
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3536663.html
Copyright © 2011-2022 走看看