二叉搜索树的实现(数据结构中的“hello,world”)

来源:互联网 发布:一键卸妆 知乎 编辑:程序博客网 时间:2024/06/05 20:31

自己实现的二叉搜索树,可能不是什么优秀的实现版本,但是好歹是自己通过学习二叉搜索树的原理,然后摸索出的自己的实现版本。

这里还用到了C++中的引用,虽然不是什么大事,但一度困扰了我。

BST的原理可以在任何一本有关数据结构的教科书中找到,关键是如何用代码实现。每个人的实现版本都不太一样。

接下来,我要找一些简洁高效而又正确的实现版本,提升自己的能力。

/*二叉搜索树模版成员函数一、查找函数 Node * Find(tree_node &root, int key)功能:在根结点为root的BST中查找关键值为key的结点二、插入函数 void Insert(tree_node &root, int key)功能:在根结点为root的BST中插入关键值为key的结点三、删除函数 void DeleteNode(tree_node &root, tree_node u)功能:在根结点为root的BST中删除结点u*/#include <cstdio>#include <cstdlib>struct Node {    int key;    Node *left, *right;}*root = NULL;typedef struct Node *tree_node;//在根为root的二叉搜索树中找键值为key的结点Node * Find(tree_node &root, int key) {    tree_node u = root;    while (u != NULL && u->key != key) {        if (key < u->key)            u = u->left;        else            u = u->right;    }    return u;}//在根为root的二叉搜索树中插入键值为key的结点void Insert(tree_node &root, int key){    Node *z = (Node *)malloc(sizeof(Node));    Node *f = NULL, *x = root;    z->left = z->right = NULL;    z->key = key;    // 寻找结点f,其中f为待插入结点z的父结点    while (x != NULL) {        f = x;        if (z->key < x->key)            x = x->left;        else            x = x->right;    }    if (f != NULL) {        if (z->key < f->key)            f->left = z;        else            f->right = z;    } else        root = z;  //根结点root为空,插入结点就是根结点    return;}//删除指定结点void DeleteNode(tree_node &root, tree_node u){    bool L = false;//判断结点u是否在它的父结点的左边,是 L为true,否则为false    tree_node father = NULL, x = root;    //寻找结点u的父结点father    while (x != u) {        father = x;        if (u->key < x->key)            x = x->left;        else            x = x->right;    }    if (father != NULL && u->key < father->key) L = true;    //分类一: 结点u是叶子结点    if (u->left == NULL && u->right == NULL) {        free(u);        if (father != NULL) {            if (L) father->left = NULL;            else father->right = NULL;        } else            root = NULL; // father为NULL,说明被铲除的是根结点root    }    //分类二(1): 结点u只有右子树    else if (u->left == NULL && u->right != NULL) {        //如果u就是根结点root        if (u == root) {            root = u->right;            free(u);        } else {            //u不是根结点            if (L)                father->left = u->right;            else                father->right = u->right;            free(u);        }    }    //分类二(2): 结点u只有左子树,原理同u只有左子树相同    else if (u->left != NULL && u->right == NULL) {        if (u == root) {            root = u->left;            free(u);        } else {            if (L)                father->left = u->left;            else                father->right = u->left;            free(u);        }    } else {    //分类三: 结点u的左右子树均存在        tree_node r = u->right, f = u;        //r存放结点u右子树中最小的结点,f存放r的父结点        while (r->left != NULL) {            f = r;            r = r->left;        }        u->key = r->key;        if (f != u)             //最小结点在结点u->right的左子树中时            f->left = r->right;        else                    //最小结点就是u->right            f->right = r->right;        free(r);    }    return;}//前序遍历的递归实现void Preorder(Node *u){    if (u == NULL)        return;    printf(" %d", u->key);    Preorder(u->left);    Preorder(u->right);}//中序遍历的递归实现void Inorder(Node *u){    if (u == NULL)        return;    Inorder(u->left);    printf(" %d", u->key);    Inorder(u->right);}//后序遍历的递归实现void Postorder(Node *u){    if (u == NULL)        return;    Postorder(u->left);    Postorder(u->right);    printf(" %d", u->key);}int main(){    int x;    char cmd[10];    while (scanf("%s", cmd) == 1) {        if (cmd[0] == 'f') {            scanf("%d", &x);            tree_node t = Find(root, x);            if (t != NULL) printf("yes\n");            else printf("no\n");        } else if (cmd[0] == 'i') {            scanf("%d", &x);            Insert(root, x);        } else if (cmd[0] == 'd') {            scanf("%d", &x);            tree_node u = Find(root, x);            DeleteNode(root, u);        } else if (cmd[0] == 'p') {            Inorder(root);            printf("\n");            Preorder(root);            printf("\n");            Postorder(root);            printf("\n");        } else            break;    }    return 0;}


0 0
原创粉丝点击