萌新#5~#7WA求助
查看原帖
萌新#5~#7WA求助
632619
DrPhilips楼主2023/2/18 20:50

找了很久不知道错误在哪里。。 有没有大佬能帮忙看一下代码orz

#include<iostream>
#include<stack>
using namespace std;

int RD() {
    int out = 0, flag = 1; char c = getchar();
    while (c < '0' || c >'9') { 
        if (c == '-')flag = -1; c = getchar(); 
    }
    while (c >= '0' && c <= '9') { 
        out = out * 10 + c - '0'; c = getchar(); 
    }
    return flag * out;
}

template <typename T>
class node {
public:
    T key;
    int height;
    node<T>* left;
    node<T>* right;
    node<T>(T k) {
        height = 1;
        key = k;
        left = NULL;
        right = NULL;
    }
};

template <typename T>
class AVL {
public:
    node<T>* root = NULL;
    int num;
    void insert(T x) {
        root = insertUtil(root, x);
    }

    void remove(T x) {
        root = removeUtil(root, x);
    }

    node<T>* const search(T x) {
        return searchUtil(root, x);
    }

    void const inorder() {
        inorderUtil(root);
        cout << endl;
    }

    void const toFindNumber(T x, node<T>* head, int& number) {//3.查找x的排名
        if (head == NULL) {
            return;
        }
        if (number > 0)toFindNumber(x, head->left, number);
        if (head->key == x) {
            cout << number << endl;
            number = -1;
            return;
        }
        if (number > 0)number++;
        if (number > 0)toFindNumber(x, head->right, number);
    }

    void const toFindNumber2(T x, node<T>* head, int& number) {//4.查找排名为x的数字
        if (head == NULL) {
            return;
        }
        if (number > 0)toFindNumber2(x, head->left, number);
        if (number == x) {
            cout << head->key << endl;
            number = -100;
            return;
        }
        if (number > 0)number++;
        if (number > 0) toFindNumber2(x, head->right, number);
    }

    void const pre(T x) { //5.前驱
        node<T>* head = root;
        int dis, minDis = -1e14, minVal = x;//dis保存两个数之间的差值
        while (head != NULL) {
            dis = head->key - x;
            if (dis < 0 && dis > minDis) {
                minDis = dis, minVal = head->key;
                head = head->right;
            }
            else {
                head = head->left;
            }
        }
        cout << minVal << endl;
    }

    void const succ(T x) {  //6.后继
        node<T>* head = root;
        int dis, minDis = 0x7fffffff, minVal = head->key;
        while (head != NULL) {
            dis = head->key - x;
            if (dis > 0 && dis < minDis) {
                minDis = dis, minVal = head->key;
                head = head->left;
            }
            else {
                head = head->right;
            }
        }
        cout << minVal << endl;
    }
private:
    int height(node<T>* head) {
        if (head == NULL) return 0;
        return head->height;
    }

    node<T>* rightRotation(node<T>* head) {
        node<T>* newhead = head->left;
        head->left = newhead->right;
        newhead->right = head;
        head->height = 1 + max(height(head->left), height(head->right));
        newhead->height = 1 + max(height(newhead->left), height(newhead->right));
        return newhead;
    }

    node<T>* leftRotation(node<T>* head) {
        node<T>* newhead = head->right;
        head->right = newhead->left;
        newhead->left = head;
        head->height = 1 + max(height(head->left), height(head->right));
        newhead->height = 1 + max(height(newhead->left), height(newhead->right));
        return newhead;
    }

    // Traverse and print AVL tree
    void inorderUtil(node<T>* head) { //中序遍历
        if (head == NULL) return;
        inorderUtil(head->left);
        cout << head->key << " ";
        inorderUtil(head->right);
    }

    node<T>* balance(node<T>* head) {//检测是否失衡,进行旋转和更新高度
        if (head == NULL) return NULL;
        if (height(head->left) - height(head->right) == 2) {
            node<T>* temp = head->left;
            if (height(temp->right) - height(temp->left) > 0) {
                head->left = leftRotation(head->left);
            }
            head = rightRotation(head);
        }
        else if (height(head->right) - height(head->left) == 2) {
            node<T>* temp = head->right;
            if (height(temp->left) - height(temp->right) > 0) {
                head->right = rightRotation(head->right);
            }
            head = leftRotation(head);
        }
        head->height = 1 + max(height(head->left), height(head->right));
        return head;
    }

    node<T>* insertUtil(node<T>* head, T x) {
        if (head == NULL) {
            head = new node<T>(x);
            return head;
        }
        node<T>* newnode;
        if (head->key >= x) { //大于时
            head->left = newnode = insertUtil(head->left, x);
        }
        else {//小于
            head->right = newnode = insertUtil(head->right, x);
        }

        if (newnode == NULL) return head;//发现已经有了这个值,提前结束
        //逐步返回,更新插入结点后的结点高度,并在必要处做旋转,保持avl树的平衡
        head = balance(head);
        return head;
    }

    node<T>* removeUtil(node<T>* head, T x) {
        node<T>* tmp;
        if (head == NULL) return head;
        if (head->key == x) {
            if (head->right == NULL && head->left == NULL) {//待删除的是叶子结点
                tmp = head;
                head = NULL;
                delete tmp;
                return head;
            }
            else if (head->left == NULL) {
                tmp = head;
                head = head->right;
                delete tmp;
                return head;
            }
            else if (head->right == NULL) {
                tmp = head;
                head = head->left;
                delete tmp;
                return head;
            }
            else {//两边非空,要删除的居然是head结点
                stack<node<T>*> nodestack;
                node<T>* helpNode = tmp = head;
                int fir = true;
                nodestack.push(head);//用来保存所有的可能被更改了平衡度的结点
                head = head->right;//向右找一位
                while (head->left != NULL) {
                    tmp = head;//tmp用来保存head的父节点
                    fir = false;//后继结点不在根结点的右子结点
                    nodestack.push(head);
                    head = head->left;
                }
                helpNode->key = head->key;//替换二者的值
                if (fir) {//后继节点为当前结点的右子结点
                    helpNode->right = head->right;
                    delete head;
                    head = balance(helpNode);
                    head = balance(head);
                    return head;
                }
                else {
                    tmp->left = head->right;
                    delete head;
                    while (!nodestack.empty()) {
                        head = nodestack.top();
                        nodestack.pop();
                        head = balance(head);
                    }
                    return head;
                }
            }
        }
        else if (head->key < x) {
            head->right = balance(removeUtil(head->right, x));
            head = balance(head);
            return head;
        }
        else {
            head->left = balance(removeUtil(head->left, x));
            head = balance(head);
            return head;
        }
    }

    node<T>* searchUtil(node<T>* head, T x) { //找到了return结点,找不到return NULL
        if (head == NULL) return NULL;
        T k = head->key;
        if (k == x) return head;
        if (k > x) return searchUtil(head->left, x);
        if (k < x) return searchUtil(head->right, x);
    }
};

int main() {
    AVL<int> avl;
    int n;
    int nb;
    cin >> nb;
    int cmd;
    int x;
    while (nb-- > 0) {
        cin >> cmd;
        switch (cmd) {
        case 1:
            x = RD();
            avl.insert(x);
            /*avl.inorder();
            cout << endl;*/
            break;
        case 2:
            x = RD();
            avl.remove(x);
            /*avl.inorder();
            cout << endl;*/
            break;
        case 3:
            x = RD();
            n = 1;
            avl.toFindNumber(x, avl.root, n);
            //avl.inorder();
            //cout << endl;
            break;
        case 4:
            x = RD();
            n = 1;
            avl.toFindNumber2(x, avl.root, n);
            //avl.inorder();
            //cout << endl;
            break;
        case 5:
            x = RD();
            avl.pre(x);
            //avl.inorder();
            //cout << endl;
            break;
        case 6:
            x = RD();
            avl.succ(x);
            //avl.inorder();
            //cout << endl;
            break;
        }
    }
}

2023/2/18 20:50
加载中...