山东大学数据结构实验11 搜索树

描述

创建带索引的二叉搜索树类。存储结构使用链表,提供操作:插入、删除、按名次删除、查找、按名次查找、升序输出所有元素。

格式

输入格式

输入第一行一个数字m (m<=1000000),表示有m个操作。
接下来m行,每一行有两个数字a,b:

  • 当输入的第一个数字 a 为 0 时,输入的第二个数字 b 表示向搜索树中插入 b
  • 当输入的第一个数字 a 为 1 时,输入的第二个数字 b 表示向搜索树中查找 b
  • 当输入的第一个数字 a 为 2 时,输入的第二个数字 b 表示向搜索树中删除 b
  • 当输入的第一个数字 a 为 3 时,输入的第二个数字 b 表示查找搜索树中名次为 b 的元素
  • 当输入的第一个数字 a 为 4 时,输入的第二个数字 b 表示删除搜索树中名次为 b 的元素

输出格式

对于输入中的每一种操作,输出执行操作的过程中依次比较的元素值的异或值。

注意

  • 查询与删除操作中,待查询的元素也需要异或入答案中
  • 查找(删除)操作中,如果未找到,或者插入操作,已存在,输出 0(不插入),不需要输出异或和
  • 查找(删除)第b大,如果不存在,输出 0
  • 删除操作中,如果当前元素有两个孩子,替换的为 右子树中最小的,如果只有一个孩子,直接用该孩子替换当前元素,如果没有孩子,直接删除
  • 删除操作的替换过程中所有比较操作不计入答案

样例1

输入

13
0 6
0 7
0 4
0 5
0 1
1 5
0 7
3 3
2 4
1 5
3 4
4 3
0 4

输出

0
6
6
2
2
7
0
7
2
3
1
6
3

样例2

输入

14
0 43
0 17
0 55
0 62
0 57
0 66
0 67
4 5
0 67
0 70
3 6
4 7
0 20
2 43

输出

0
43
43
28
34
34
96
34
0
29
29
91
58
43

限制

1s, 10240KiB for each test case.

提示

  • 查找和删除第k大的元素时,可以先把第k的元素找到,再按照该元素查找和删除
#include <iostream>
#include<cstring>
#include<algorithm>

using namespace std;

template<class K>
struct BSTNode {
    BSTNode *leftChild;
    BSTNode *rightChild;
    K key;
    int index;

    BSTNode() {};

    BSTNode(K theKey) {
        key = theKey;
        leftChild = NULL;
        rightChild = NULL;
        index = 0;
    }

    BSTNode(BSTNode *bst) {
        bst->rightChild = this->rightChild;
        bst->leftChild = this->leftChild;
        bst->key = this->key;
        bst->index = this->index;
    }

    BSTNode(const K &theElement, BSTNode<K> *theLeft, BSTNode<K> *theRight, int LeftTreeSize) {
        key = theElement;
        leftChild = theLeft;
        rightChild = theRight;
        index = LeftTreeSize;
    }

};

template<class K>
class BSTWithIndex {
public:
    BSTWithIndex() {
        root =NULL;
        Treesize=0;
    };

    //插入、删除、按名次删除、查找、按名次查找、升序输出所有元素。
    int insert(K theKey);

    int erase(K theKey);

    int eraseWithIndex(int theIndex);

    int find(K theKey);

    int findWithIndex(int theIndex);

    void out();

private:
    int Treesize;
    BSTNode<K> *root;

};

template<class K>
int BSTWithIndex<K>::insert(K theKey) {
    BSTNode<K> *currentNode = root;
    BSTNode<K>  *parent = NULL;
    int sum = 0;

    while (currentNode != NULL) {
        if (theKey < currentNode->key) {
            sum ^= currentNode->key;
            parent = currentNode;
            currentNode = currentNode->leftChild;
        } else if (theKey > currentNode->key) {
            sum ^= currentNode->key;
            parent = currentNode;
            currentNode = currentNode->rightChild;
        } else if (theKey == currentNode->key){
            return 0;
        }
    }
    BSTNode<K> *newNode = new BSTNode<K>(theKey);
    if (parent != NULL) {
        if (parent->key > theKey)
            parent->leftChild = newNode;
        else
            parent->rightChild = newNode;
    } else {
        root = newNode;
    }
    Treesize++;
    currentNode = root;
    while (currentNode->key != theKey) {
        if (currentNode->key < theKey) {
            currentNode = currentNode->rightChild;
        } else if (currentNode->key > theKey) {
            currentNode->index++;
            currentNode = currentNode->leftChild;
        }
    }
    return sum;
}

template<class K>
int BSTWithIndex<K>::erase(K theKey) {
    BSTNode<K> *currentNode = root;
    BSTNode<K> *parent = NULL;
    int sum = 0;
    while (currentNode != NULL && currentNode->key != theKey) {
        sum ^= currentNode->key;
        parent = currentNode;
        if (currentNode->key < theKey) {
            currentNode = currentNode->rightChild;
        } else if (currentNode->key > theKey) {
            currentNode = currentNode->leftChild;
        }
    }
    if (currentNode == NULL) {
        return 0;
    }
    sum ^= currentNode->key;
    currentNode = root;
    while (currentNode != NULL && currentNode->key != theKey) {
        if (currentNode->key < theKey) {
            currentNode = currentNode->rightChild;
        } else if (currentNode->key > theKey) {
            currentNode->index--;
            currentNode = currentNode->leftChild;
        }
    }

    if (currentNode->leftChild != NULL && currentNode->rightChild != NULL) {
        BSTNode<K> *ps = currentNode->rightChild;
        BSTNode<K> *s = currentNode;
        while (ps->leftChild != NULL) {
            ps->index--;
            s = ps;
            ps = ps->leftChild;
        }

        BSTNode<K> *newNode = new BSTNode<K>(ps->key, currentNode->leftChild, currentNode->rightChild,
                                             currentNode->index);
        if (parent == NULL)
            root = newNode;
        else if (currentNode == parent->leftChild)
            parent->leftChild = newNode;
        else
            parent->rightChild = newNode;

        if (s == currentNode)
            parent = newNode;
        else
            parent = s;

        delete currentNode;
        currentNode = ps;
    }

    BSTNode<K> *c;
    if (currentNode->leftChild != NULL)
        c = currentNode->leftChild;
    else
        c = currentNode->rightChild;
    if (currentNode == root)
        root = c;
    else {
        if (currentNode == parent->leftChild)
            parent->leftChild = c;
        else
            parent->rightChild = c;
    }
    Treesize--;
    return sum;

}

template<class K>
int BSTWithIndex<K>::eraseWithIndex(int theIndex) {
    BSTNode<K> *currentNode = root;
    BSTNode<K> *parent = NULL;
    int sum = 0;
    while (currentNode != NULL && currentNode->index != theIndex) {
        sum ^= currentNode->key;
        parent = currentNode;
        if (currentNode->index > theIndex) {
            currentNode = currentNode->leftChild;
        } else if (currentNode->index < theIndex) {
            theIndex = theIndex - currentNode->index - 1;
            currentNode = currentNode->rightChild;
        }
    }
    if (currentNode == NULL)
        return 0;
    sum ^= currentNode->key;
    int theElement = currentNode->key;
    currentNode = root;
    while (currentNode != NULL && currentNode->key != theElement) {
        if (currentNode->key < theElement) {
            currentNode = currentNode->rightChild;
        } else if (currentNode->key > theElement) {
            currentNode->index--;
            currentNode = currentNode->leftChild;
        }
    }

    if (currentNode->leftChild != NULL && currentNode->rightChild != NULL) {
        BSTNode<K> *ps = currentNode->rightChild;
        BSTNode<K> *s = currentNode;
        while (ps->leftChild != NULL) {
            ps->index--;
            s = ps;
            ps = ps->leftChild;
        }

        BSTNode<K> *newNode = new BSTNode<K>(ps->key, currentNode->leftChild, currentNode->rightChild, currentNode->index);
        if (parent == NULL)
            root = newNode;
        else if (currentNode == parent->leftChild)
            parent->leftChild = newNode;
        else
            parent->rightChild = newNode;

        if (s == currentNode)
            parent = newNode;
        else
            parent = s;

        delete currentNode;
        currentNode = ps;
    }

    BSTNode<K> *c;
    if (currentNode->leftChild != NULL)
        c = currentNode->leftChild;
    else
        c = currentNode->rightChild;

    if (currentNode == root)
        root = c;
    else {
        if (currentNode == parent->leftChild)
            parent->leftChild = c;
        else
            parent->rightChild = c;
    }
    Treesize--;
    delete currentNode;
    return sum;


}

template <class K>
int BSTWithIndex<K>::find(K theKey)
{
   BSTNode<K>* currentNode = root;
    int sum = 0;
    while (currentNode != NULL && currentNode->key != theKey)
    {
        sum ^= currentNode->key;
        if (currentNode->key > theKey)
        {
            currentNode = currentNode->leftChild;
        }
        else if (currentNode->key < theKey)

        {
            currentNode = currentNode->rightChild;
        }
    }
    if (currentNode == NULL)
        return 0;
    else
    {
        sum ^= currentNode->key;
        return sum;
    }
}


template<class K>
int BSTWithIndex<K>::findWithIndex(int theIndex) {
    BSTNode<K> *p = root;
    int sum = 0;
    while (p != NULL && p->index != theIndex) {
        sum ^= p->key;
        if (p->index > theIndex) {
            p = p->leftChild;
        } else if (p->index < theIndex) {
            theIndex = theIndex - p->index - 1;
            p = p->rightChild;
        }
    }
    if (p == NULL)
        return 0;
    else {
        sum ^= p->key;
        return sum;
    }

}

void inorderHelper(BSTNode<int> *root) {
    if (root == NULL)return;
    inorderHelper(root->leftChild);
    cout << root->key << " ";
    inorderHelper(root->rightChild);
}


int main() {
    int m;
    scanf("%d", &m);
    BSTWithIndex<int> B;
    int a, b;
    while (m--) {
        scanf("%d%d", &a, &b);
        switch (a) {
            case 0:
                cout << B.insert(b) << endl;
                break;
            case 1:
                cout << B.find(b) << endl;
                break;
            case 2:
                cout << B.erase(b) << endl;
                break;
            case 3:
                b--;
                cout << B.findWithIndex(b) << endl;
                break;
            case 4:
                b--;
                cout << B.eraseWithIndex(b) << endl;
                break;


        }
    }


    return 0;
}
posted @   Lyz103  阅读(276)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示