二叉线索树+二叉搜索树

线索树利用中序遍历来维护

其中树中删除操作分别讨论
1)无儿子
2)有一个儿子–>分四种情况讨论
3)有两个儿子–>与将左子树最右的结点互换值,转化为问题(1)和(2)

/*
二叉搜索树+二叉线索树的合并
搜索树插入与删除同时维护了前序和后序 

样例 
8
8 6 7 5 10 9 12 11
 
*/
#include<iostream>

using namespace std;

template<class Item>
class binary_tree_node {
public:
    //TYPEDEF
    typedef Item value_type;

    //CONSTRUCTOR
    binary_tree_node(
            const Item &init_data = Item(),
            binary_tree_node *init_left = NULL,
            binary_tree_node *init_right = NULL,
            binary_tree_node *init_parent = NULL,
            bool init_left_flag = 0,
            bool init_right_flag = 0
    ) {
        data_field = init_data;
        left_field = init_left;
        right_field = init_right;
        left_flag = init_left_flag;
        right_flag = init_right_flag;
        parent_field = init_parent;
    }

    //MODIFICATION MEMBER FUNCTIONS
    Item &data() { return data_field; }

    bool &LeftFlag() { return left_flag; }

    bool &RightFlag() { return right_flag; }

    binary_tree_node *left() { return left_field; }

    binary_tree_node *right() { return right_field; }

    binary_tree_node *parent() { return parent_field; }

    void set_data(const Item &new_data) { data_field = new_data; }

    void set_left_flag(const bool &new_flag) { left_flag = new_flag; }

    void set_right_flag(const bool &new_flag) { right_flag = new_flag; }

    void set_left(binary_tree_node *new_left) { left_field = new_left; }

    void set_right(binary_tree_node *new_right) { right_field = new_right; }

    void set_parent(binary_tree_node *new_parent) { parent_field = new_parent; }

private:
    Item data_field;
    binary_tree_node *parent_field;
    binary_tree_node *left_field;
    binary_tree_node *right_field;
    bool left_flag;
    bool right_flag;
};

template<class Item>
class binary_search_tree {
public:
    binary_search_tree(binary_tree_node<Item> *init_head = NULL) {
        head = init_head;
    }

    void insert_node(Item data);//二叉树插入结点,并维护已有的中序线索 

    binary_tree_node<Item> *find(Item data);//二叉树查询一个元素,并返回指向该元素的指针 

    void erase(Item data);//清除一个元素 

    binary_tree_node<Item> *in_findpre(binary_tree_node<Item> *ptr);//查找该指针指向元素的前序 

    binary_tree_node<Item> *in_findnext(binary_tree_node<Item> *ptr);//查找该指针指向元素的后序 

    void In_Traverse();//进行中序遍历 

    void tree_clear(binary_tree_node<Item> *root = NULL);//清除树 

private:
    binary_tree_node<Item> *head;
};

/*二叉树插入结点,并维护已有的中序线索*/
template<class Item>
void binary_search_tree<Item>::insert_node(Item data) {
    if (head == NULL) {
        head = new binary_tree_node<Item>(data);
        return;
    }
    binary_tree_node<Item> *root = head;
    while (1) {
        while (data > root->data() && root->RightFlag() == 0 && root->right() != NULL)
            root = root->right();
        if (data > root->data()) {
            binary_tree_node<Item> *node = new binary_tree_node<Item>(data);

            node->set_right(root->right());
            node->RightFlag() = root->RightFlag();
            node->set_left(root);
            node->LeftFlag() = 1;

            root->set_right(node);
            node->set_parent(root);
            root->RightFlag() = 0;
            break;
        }
        while (data <= root->data() && root->LeftFlag() == 0 && root->left() != NULL)
            root = root->left();
        if (data <= root->data()) {
            binary_tree_node<Item> *node = new binary_tree_node<Item>(data);

            node->set_left(root->left());
            node->LeftFlag() = root->LeftFlag();
            node->set_right(root);
            node->RightFlag() = 1;

            root->set_left(node);
            node->set_parent(root);
            root->LeftFlag() = 0;
            break;
        }
    }
    return;
}

/*二叉树查找某一个结点并返回指向它的指针*/
template<class Item>
binary_tree_node<Item> *binary_search_tree<Item>::find(Item data) {
    binary_tree_node<Item> *root = head;
    while (1) {
        while (data > root->data() && root->RightFlag() == 0 && root->right() != NULL)
            root = root->right();
        if (data > root->data()) {
            cout << "This node is not in the tree" << endl;
            break;
        }
        while (data < root->data() && root->LeftFlag() == 0 && root->left() != NULL)
            root = root->left();
        if (data < root->data()) {
            cout << "This node is not in the tree" << endl;
            break;
        }
        if (data == root->data()) break;
    }
    if (data == root->data()) return root;
    else return NULL;
}

/*二叉树删除某一个结点*/
template<class Item>
void binary_search_tree<Item>::erase(Item data) {
    binary_tree_node<Item> *node = find(data);
    if (node == NULL) return;
    binary_tree_node<Item> *pre = in_findpre(node);
    binary_tree_node<Item> *next = in_findnext(node);
    binary_tree_node<Item> *father = node->parent();
    if (node->LeftFlag() == 0 && node->RightFlag() == 0 && node->left() != NULL && node->right() != NULL) {//有两个儿子结点
        node->data() = pre->data();
        node = pre;
        pre = in_findpre(node);
        next = in_findnext(node);
    }
    if ((node->LeftFlag() == 1 && node->RightFlag() == 1) ||
        (node->LeftFlag() == 1 && node->right() == NULL) ||
        (node->left() == NULL && node->RightFlag() == 1))//无任何儿子结点
    {
        if (pre->RightFlag() == 1) {
            pre->set_right(next);
        } else {
            if (pre->right() == node) {
                pre->set_right(next);
                pre->RightFlag() = 1;
            }
        }
        if (next->LeftFlag() == 1) {
            next->set_left(pre);
        } else {
            if (next->left() == node) {
                next->set_left(pre);
                next->LeftFlag() = 1;
            }
        }
        if (node->parent() == NULL) head = NULL;
    } else {//有一个儿子结点
        if (father->right() == node) {
            if (node->LeftFlag() == 0 && node->left() != NULL) {
                father->set_right(node->left());
                if ((node->left())->RightFlag() == 1) {
                    (node->left())->set_right(next);
                }
            } else if (node->right() != NULL && node->RightFlag() == 0) {
                father->set_right(node->right());
                if ((node->right())->LeftFlag() == 1) {
                    (node->right())->set_left(father);
                }
            }
        } else if (father->left() == node) {
            if (node->LeftFlag() == 0 && node->left() != NULL) {
                father->set_left(node->left());
                if ((node->left())->RightFlag() == 1) {
                    (node->left())->set_right(father);
                }
            } else if (node->right() != NULL && node->RightFlag() == 0) {
                father->set_left(node->right());
                if ((node->right())->LeftFlag() == 1) {
                    (node->right())->set_left(next);
                }
            }
        }
        if (node->parent() == NULL) {
            if (node->left() != NULL && node->LeftFlag() == 0) {
                head = node->left();
            } else if (node->right() != NULL && node->RightFlag() == 0) {
                head = node->right();
            }
        }
    }
    delete node;
    node = NULL;
    return;
}

/*中序线索二叉树找前驱*/
template<class Item>
binary_tree_node<Item> *binary_search_tree<Item>::in_findpre(binary_tree_node<Item> *ptr) {
    if (ptr->LeftFlag() == 1) return ptr->left();
    else {
        binary_tree_node<Item> *p = ptr->left();
        while (p->RightFlag() == 0 && p->right() != NULL) {
            p = p->right();
        }
        return p;
    }
}

/*中序线索二叉树找后继*/
template<class Item>
binary_tree_node<Item> *binary_search_tree<Item>::in_findnext(binary_tree_node<Item> *ptr) {
    if (ptr->RightFlag() == 1) return ptr->right();
    else {
        binary_tree_node<Item> *p = ptr->right();
        while (p->LeftFlag() == 0 && p->left() != NULL) {
            p = p->left();
        }
        return p;
    }
}

/*二叉树中序遍历*/
template<class Item>
void binary_search_tree<Item>::In_Traverse() {
    cout << "inorder_traverse:" << endl;
    if (head == NULL) {
        cout << "There are no nodes in this tree" << endl;
        return;
    }
    binary_tree_node<Item> *root = head;
    while (root->LeftFlag() == 0 && root->left() != NULL) {
        root = root->left();
    }
    cout << root->data() << endl;
    while (root->right() != NULL) {
        if (root->RightFlag() == 0) {
            root = root->right();
            while (root->LeftFlag() == 0) {
                root = root->left();
            }
        } else {
            root = root->right();
        }
        cout << root->data() << endl;
    }
}


/*清除树*/
template<class Item>
void binary_search_tree<Item>::tree_clear(binary_tree_node<Item> *root) {
    if (root == NULL) root = head, head = NULL;
    if (root == NULL) return;
    if (root != NULL) {
        if (root->LeftFlag() == 0 && root->left() != NULL)
            tree_clear(root->left());
        if (root->RightFlag() == 0 && root->right() != NULL)
            tree_clear(root->right());
        delete root;
        root = NULL;
    }
}

int main() {

    int n;
    cin >> n;
    binary_search_tree<int> tre;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        tre.insert_node(x);
    }
    tre.In_Traverse();//中序输出
    cout<<"Delete element 10"<<endl; 
    tre.erase(10);//删除数字10
    tre.In_Traverse(); //再次中序输出
    tre.tree_clear();//清除树
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值