C++ - 创建二叉搜索树类,旋转后一个节点消失

发布于 2024-12-13 06:37:39 字数 3203 浏览 3 评论 0原文

我正在尝试创建一个自定义的二叉搜索树,除了旋转函数之外,我已经完成了所有操作,该函数似乎没有移动节点。仅当搜索并找到节点并且该节点有右子节点时才会调用旋转函数。为了简单起见,我将只添加在此使用的函数,以使其更短:

#include <iostream>

using namespace std;

template <typename T>
class MRBST {
public:
    MRBST();
    ~MRBST();

    void push(const T &);
    bool search(const T &);
    void PrintPreorder();
private:
    struct Node {
        T data;
        Node *left;
        Node *right;

        Node (const T & theData, Node *lt, Node *rt) 
        : data(theData), left(lt), right(rt) {}
    };
    Node *root;

    void push(const T &, Node * &) const;
    void remove(const T &, Node * &) const;
    Node* findMin(Node *t) const {
        if (t == NULL) {
            return NULL;
        }
        if (t->left == NULL) {
            return t;
        }
        return findMin(t->left);
    }
    void preorder(Node * &);
    bool search(const T &, Node *);
    Node* findNode(const T & x, Node * t) {
        if (t == NULL) {
            return NULL;
        }
        if (x < t->data) {
            return findNode(x, t->left);
        } else if (x > t->data) {
            return findNode(x, t->right);
        } else if (x == t->data) {
            return t;
        }
        return NULL;
    }
    void rotate(Node *);
};

template <typename T>
void MRBST<T>::PrintPreorder() {
    preorder(root);
    cout << endl;
}

template <typename T>
void MRBST<T>::preorder(Node * & t) {
    if (t != NULL) {
        cout << t->data << endl;
        preorder(t->left);
        preorder(t->right);
    }
}

template <typename T>
bool MRBST<T>::search(const T & x) {
    if (search(x, root)) {
        Node *temp = findNode(x, root);
        rotate(temp);
        return true;            
    } else {
        return false;
    }
}

template <typename T>
void MRBST<T>::rotate(Node * k1) {
    if (k1->right == NULL) {
        return;
    } else {
        Node *temp = k1->right;
        k1->right = temp->left;
        temp->left = k1;
    }
}


template <typename T>
bool MRBST<T>::search(const T & x, Node *t) {
    if (t == NULL) {
        return false;
    } else if (x < t->data) {
        return  search(x, t->left);
    } else if (x > t->data) {
        return search(x, t->right);
    } else {
        return true;
    }
}

我有一个简单的测试文件,只需向树中添加一些数字,然后进行搜索,然后在预排序中打印出来。

#include <iostream>
#include "MRBST.h"

using namespace std;

int main() {
    MRBST<int> binaryTree;
    binaryTree.push(5);
    binaryTree.push(20);
    binaryTree.push(3);
    binaryTree.push(3);
    binaryTree.push(4);
    binaryTree.push(22);
    binaryTree.push(17);
    binaryTree.push(18);
    binaryTree.push(8);
    binaryTree.push(9);
    binaryTree.push(1);
    binaryTree.PrintPreorder();
    cout << endl;
    binaryTree.search(17);
    binaryTree.PrintPreorder();
    cout << endl;

}

输出看起来像这样:

5 3 1 4 20 17 号 8 9 18 22

5 3 1 4 20 17 号 8 9 22

如果有人能够深入了解我的旋转功能出了什么问题,那将是一个很大的帮助。

I am trying to create a custom Binary Search Tree, and I have everything done except for the rotate function, which seems to be not moving a node over. The rotate function only gets called when a node is searched and found, and if the node has a right child. For simplicity I will only add the functions that are used in this, to make it shorter:

#include <iostream>

using namespace std;

template <typename T>
class MRBST {
public:
    MRBST();
    ~MRBST();

    void push(const T &);
    bool search(const T &);
    void PrintPreorder();
private:
    struct Node {
        T data;
        Node *left;
        Node *right;

        Node (const T & theData, Node *lt, Node *rt) 
        : data(theData), left(lt), right(rt) {}
    };
    Node *root;

    void push(const T &, Node * &) const;
    void remove(const T &, Node * &) const;
    Node* findMin(Node *t) const {
        if (t == NULL) {
            return NULL;
        }
        if (t->left == NULL) {
            return t;
        }
        return findMin(t->left);
    }
    void preorder(Node * &);
    bool search(const T &, Node *);
    Node* findNode(const T & x, Node * t) {
        if (t == NULL) {
            return NULL;
        }
        if (x < t->data) {
            return findNode(x, t->left);
        } else if (x > t->data) {
            return findNode(x, t->right);
        } else if (x == t->data) {
            return t;
        }
        return NULL;
    }
    void rotate(Node *);
};

template <typename T>
void MRBST<T>::PrintPreorder() {
    preorder(root);
    cout << endl;
}

template <typename T>
void MRBST<T>::preorder(Node * & t) {
    if (t != NULL) {
        cout << t->data << endl;
        preorder(t->left);
        preorder(t->right);
    }
}

template <typename T>
bool MRBST<T>::search(const T & x) {
    if (search(x, root)) {
        Node *temp = findNode(x, root);
        rotate(temp);
        return true;            
    } else {
        return false;
    }
}

template <typename T>
void MRBST<T>::rotate(Node * k1) {
    if (k1->right == NULL) {
        return;
    } else {
        Node *temp = k1->right;
        k1->right = temp->left;
        temp->left = k1;
    }
}


template <typename T>
bool MRBST<T>::search(const T & x, Node *t) {
    if (t == NULL) {
        return false;
    } else if (x < t->data) {
        return  search(x, t->left);
    } else if (x > t->data) {
        return search(x, t->right);
    } else {
        return true;
    }
}

I have a simple testing file that just adds some numbers to the tree, and then searches, followed by a print out in Preordering.

#include <iostream>
#include "MRBST.h"

using namespace std;

int main() {
    MRBST<int> binaryTree;
    binaryTree.push(5);
    binaryTree.push(20);
    binaryTree.push(3);
    binaryTree.push(3);
    binaryTree.push(4);
    binaryTree.push(22);
    binaryTree.push(17);
    binaryTree.push(18);
    binaryTree.push(8);
    binaryTree.push(9);
    binaryTree.push(1);
    binaryTree.PrintPreorder();
    cout << endl;
    binaryTree.search(17);
    binaryTree.PrintPreorder();
    cout << endl;

}

With the output looking a something like this:

5
3
1
4
20
17
8
9
18
22

5
3
1
4
20
17
8
9
22

If anyone could give some insight into what is going wrong with my rotate function, that would be a great help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

朦胧时间 2024-12-20 06:37:40

为什么要在搜索中进行旋转?它应该是只读的。

因此你会丢失节点。

看看你的旋转

    Node *temp = k1->right;
    k1->right = temp->left;
    temp->left = k1;

假设k1=x有right=y和left=z,逐步查看:

    Node *temp = k1->right;

temp =k1->right = y, k1 = x, k1->left = z

    k1->right = temp->left;

k1->右=?,k1->左= z,temp=y

    temp->left = k1;

k1->右=?,k1->左= z,temp->左= x。

现在——Y 去哪儿了?你失去了它。

Why are you doing rotate on search? It should be read-only.

You're losing the node because of that.

Look at your rotate:

    Node *temp = k1->right;
    k1->right = temp->left;
    temp->left = k1;

Assume k1=x has right=y and left=z, look step by step:

    Node *temp = k1->right;

temp =k1->right = y, k1 = x, k1->left = z

    k1->right = temp->left;

k1->right = ?, k1->left = z, temp = y

    temp->left = k1;

k1->right = ?, k1->left = z, temp->left = x.

Now - where did Y go? You lost it.

遗失的美好 2024-12-20 06:37:40

一步步仔细观察您的rotate() 函数,看看它是否按照您的要求执行。

Look closely at your rotate() function, step by step, to see whether it does what you want it to do or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文