算法导论OJ习题— 数据库查询(红黑树实现AVL树实现)

Posted 之墨_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法导论OJ习题— 数据库查询(红黑树实现AVL树实现)相关的知识,希望对你有一定的参考价值。

算法导论OJ习题— 数据库查询

Description
勤奋的小明为了预习下学期的数据库课程,决定亲自实现一个简单的数据库系统。该数据库系统需要处理用户的数据库插入和查询语句,并输出相应的输出。具体来说,用户的输入共包含若干条插入语句和查询语句。其中每条插入语句包含一个主键(唯一标识)idid和一个字符串sid表示在数据库中插入一个主键为id,属性值为sid的条目。每条查询语句包含一个字符串k,表示在数据库总查询是否有条目属性值为k,若存在属性值为k的条目,则输出该条目对应的主键(输入保证至多有一个条目满足要求),否则输出一个-1表示不存在这样的条目。
Input

Output


这题的本意是想让我们用红黑树解决,但c++的容器map就是用红黑树实现的,这里直接使用map不会超时(应该是数据规模比较小)

Map版本:

#include<bits/stdc++.h>
using namespace std;
const long long N = 1e7;
char o[100010];
char id[N];
char stuid[100010];
long  long re[1000000];
long long i = 0;
map<string,long long> stu;
int main()

    while (scanf("%s",o))
    
    	if(o[0]=='E')
    		break;
    	if(o[0]=='F')
		
		scanf("%s",stuid);
	    if(stu[stuid]>0) 
			re[i++]=stu[stuid];
	   	else
  			re[i++]=-1;
  		
    	else
    		scanf("%s%s",id,stuid);
	    	long long iid = atoi(id);
	        stu[stuid]=iid;
		
    
    
    for(long long j=0;j<i;j++)
    	printf("%lld\\n",re[j]);
    return 0;

二叉搜索树版本:

#include<iostream>
#include<stdio.h>
#include<string.h>

#define N 2000

using namespace std;

class BSTNode 
public:
	int key;
	BSTNode* lchild, * rchild, * parent;

	BSTNode(int value) :key(value) 
		lchild = NULL;
		rchild = NULL;
		parent = NULL;
	

	BSTNode(int value, BSTNode* l, BSTNode* r, BSTNode* p) :key(value), lchild(l), rchild(r), parent(p) 
;

class BSTree 
private:
	BSTNode* root;

public:
	
	BSTree() 
		root = NULL;
	
	~BSTree();

	void insert(const int& value);
	//void InOrder();
	BSTNode* FindKey(const int& value);
	BSTNode* Predecessor(BSTNode* p);

private:
	void insert(BSTNode* p, BSTNode* node);
	//void InOrder(BSTNode* p);
	BSTNode* FindKey(BSTNode* p,const int& value);
;

void BSTree::insert(const int& value) 
	BSTNode* node = new BSTNode(value);
	node->key = value;
	node->lchild = node->rchild = node->parent = NULL;
	if (node == NULL) 
		printf("无内存可用!\\n");
	

	if (root == NULL) 
		root = node;
	
	else 
		insert(root, node);
	


void BSTree::insert(BSTNode* p, BSTNode* node) 
	BSTNode* q = p;
	while (p != NULL) 
		q = p;	//用q来记录p的parent,虽然有指向parent的指针,但循环的条件为判断p是否为空,
				//当循环结束时p为NULL,此时无指向parent的指针
		if (node->key < p->key) 
			p = p->lchild;
		
		else 
			p = p->rchild;
		
	

	if (node->key < q->key) 
		q->lchild = node;
	
	else 
		q->rchild = node;
	
	node->parent = q;



//void BSTree::InOrder() 
//	if (root != NULL) 
//		//BSTNode* p = root;
//		InOrder(root);
//	
//	
//
//
//void BSTree::InOrder(BSTNode* p) 
//	if (p != NULL) 
//		InOrder(p->lchild);
//		printf("%d ", p->key);
//		InOrder(p->rchild);
//	
//

BSTNode* BSTree::FindKey(const int& value) 
	if (root != NULL) 
		return FindKey(root, value);
	
	return NULL;


BSTNode* BSTree::FindKey(BSTNode* p, const int& value) 
	if (value == p->key) 
		return p;
	
	BSTNode* q = p;
	while (p && value != p->key) 
		q = p;
		if (value < p->key) 
			p = p->lchild;
		
		else 
			p = p->rchild;
		
	
	if (p != NULL) 	// 找到了
		return p;
	
	else	//没找到,返回比value小的最大结点
		if (value > q->key) 
			return q;
		
		else 
			return Predecessor(q);	// 返回q的前驱节点
		
	


BSTNode* BSTree::Predecessor(BSTNode* p) 
	if (root != NULL) 
		if (p->lchild != NULL) 
			p = p->lchild;
			while (p->rchild != NULL) 
				p = p->rchild;
			
			return p;
		
		else 
			BSTNode* q = p->parent;
			
			while (q != NULL && q->lchild == p) 
				p = q;
				q = p->parent;
			
			return q;
		
	
	return NULL;


int main() 
	BSTree* BST = new BSTree();

	int result[N], n = 0;

	char c[7] =  0 ;
	char c1[7] =  'I','N','S','E','R','T';
	char c2[5] =  'F','I','N','D' ;
	char c3[5] =  'E','X','I','T' ;
	int num;
	scanf_s("%s", c, 7);
	while (true) 
		if (strcmp(c, c3) == 0) 
			break;
		
		scanf_s("%d", &num);
		if (strcmp(c, c1) == 0) 
			BST->insert(num);
		
		else 
			result[n] = BST->FindKey(num)->key;
			++n;
		
		
		scanf_s("%s", c, 7);
	

	for (int i = 0; i < n; ++i) 
		printf("%d\\n", result[i]);
	

AVLTree版本:

#include<iomanip>
#include<iostream>
#include<string.h>
#define N 2000
using namespace std;

template<class T>
class AVLTreeNode

public:
    T key;    // 关键字(键值)
    int height;    // 高度
    AVLTreeNode* left;    // 左孩子
    AVLTreeNode* right;    // 右孩子
    AVLTreeNode* parent;

    AVLTreeNode(T value, AVLTreeNode* l, AVLTreeNode* r, AVLTreeNode* p) :
        key(value), left(l), right(r), parent(p) 
;

template<class T>
class AVLTree

private:
    AVLTreeNode<T>* root;    // 根结点

public:
    AVLTree();
    ~AVLTree();

    int height();
    AVLTreeNode<T>* iterativeSearch(T key);
    AVLTreeNode<T>* predecessor(AVLTreeNode<T>* x) const;
    T minimum();
    T maximum();
    void insert(T key);

private:
    int height(AVLTreeNode<T>* tree);
    AVLTreeNode<T>* iterativeSearch(AVLTreeNode<T>* x, T key) const;

    AVLTreeNode<T>* minimum(AVLTreeNode<T>* tree);
    AVLTreeNode<T>* maximum(AVLTreeNode<T>* tree);
    AVLTreeNode<T>* insert(AVLTreeNode<T>*& tree, T key);

    // LL:左左对应的情况(左单旋转)
    AVLTreeNode<T>* leftLeftRotation(AVLTreeNode<T>* k2);
    // RR:右右对应的情况(右单旋转)
    AVLTreeNode<T>* rightRightRotation(AVLTreeNode<T>* k1);
    // LR:左右对应的情况(左双旋转)
    AVLTreeNode<T>* leftRightRotation(AVLTreeNode<T>* k3);
    // RL:右左对应的情况(右双旋转)
    AVLTreeNode<T>* rightLeftRotation(AVLTreeNode<T>* k1);
;

template<class T>
AVLTree<T>::AVLTree() : root(NULL)



template<class T>
AVLTree<T>::~AVLTree()

    destroy(root);


template<class T>
int AVLTree<T>::height(AVLTreeNode<T>* tree)

    if (tree != NULL)
        return tree->height;
    return 0;


template<class T>
int AVLTree<T>::height()

    return height(root);


template<class T>
AVLTreeNode<T>* AVLTree<T>::leftLeftRotation(AVLTreeNode<T>* k2)

    AVLTreeNode<T>* k1;

    k1 = k2->left;  k1->parent = k2->parent;
    k2->left = k1->right;
    if (k2->left) 
        k2->left->parent = k2;
    
    k1->right = k2;     k2->parent = k1;

    k2->height = max(height(k2->left), height(k2->right)) + 1;
    k1->height = max(height(k1->left), k2->height) + 1;

    return k1;


template<class T>
AVLTreeNode<T>* AVLTree<T>::rightRightRotation(AVLTreeNode<T>* k1)

    AVLTreeNode<T>* k2;

    k2 = k1->right;     k2->parent = k1->parent;
    k1->right = k2->left;
    if (k1->right) 
        k1->right->parent = k1;
    
    k2->left = k1;  k1->parent = k2;

    k1->height = max(height(k1->left), height(k1->right)) + 1;
    k2->height = max(k1->height, height(k2->right)) + 1;

    return k2;


template <class T>
AVLTreeNode<T>* AVLTree<T>::leftRightRotation(AVLTreeNode<T>* k3)

    k3->left = rightRightRotation(k3->left);

    return leftLeftRotation(k3);


template <class T>
AVLTreeNode<T>* AVLTree<T>::rightLeftRotation(AVLTreeNode<T>* k1)

    k1->right = leftLeftRotation(k1->right);

    return rightRightRotation(k1);


template<class T>
AVLTreeNode<T>* AVLTree<T>::insert(AVLTreeNode<T>*& tree, T key)

    if (tree == NULL)
    
        // 新建结点 
        tree = new AVLTreeNode<T>(key, NULL, NULL, NULL);
        if (tree == NULL)
        
            cout << "ERROR: create avltree node failed!" << endl;
            return NULL;
        
    
    else if (key < tree->key)
    
        AVLTreeNode<T>* p = insert(tree->left, key);
        tree->left = p;
        p->parent = tree;
        // 插入结点后,若AVL树失去平衡,则进行相应的调节
        if (height(tree->left) - height(tree->right) == 2)
        
            if (key < tree->left->key)
                tree = leftLeftRotation(tree);
            else
                tree = leftRightRotation(t

以上是关于算法导论OJ习题— 数据库查询(红黑树实现AVL树实现)的主要内容,如果未能解决你的问题,请参考以下文章

AVL树

算法导论 红黑树 实现

《算法导论》动态规划—最优二分搜索树

红黑树-Java红黑树,算法导论实现版

二叉查找树,AVL,红黑树的Python实现

红黑树初探(算法导论)