二叉树(查询和删除)

来源:互联网 发布:js在win7下不能运行 编辑:程序博客网 时间:2024/06/14 02:19

一,插入数据

这里写图片描述

二叉树的插入过程
这里写图片描述

数据结构

typedef struct TreeNode {    int data;    struct TreeNode *leftchild;    struct TreeNode *rightChild;    struct TreeNode *parent;}TreeNode;

1, 第一步判断二叉树是否有根节点

//判断根节点是否为空    if (root == NULL) {        //创建根节点        root = (TreeNode *)malloc(sizeof(TreeNode));        //赋值        root->data = data;        root->leftchild = NULL;        root->rightChild = NULL;        return root;    }

2, 如果有节点就记录当前的根节点,遍历比较节点的数据大小, 添加节点

//遍历比较    TreeNode *parent = NULL;    TreeNode *node = root;    //遍历遍历比较大小 , 查询找到插入的位置    for (; node != NULL; ) {        parent = node;        //比较值        if (data < parent->data)             node = parent->leftchild;        else if (data > parent->data)            node = parent->rightChild;        else             return node;    }    //创建节点    TreeNode* newNode = (TreeNode *)malloc(sizeof(TreeNode));    //赋值操作    newNode->data = data;    newNode->leftchild = NULL;    newNode->rightChild = NULL;    if (data < parent->data) {        parent->leftchild = newNode;    }    else {        parent->rightChild = newNode;    }    //child指针父节点parent    newNode->parent = parent;

二,前序,中序, 后续遍历

提一下遍历的定义:

  1. 前序遍历: DLR , 先根,在左, 再右
  2. 中序遍历:LDR,先左,在根, 再右
  3. 后序遍历:LRD, 先左, 在右,在根

前序遍历

LRD

void modleOrderTraverse(TreeNode *node) {    if (node == NULL)        return;    printf("%d\t", node->data);    modleOrderTraverse(node->leftchild);    modleOrderTraverse(node->rightChild);}

中序遍历

LDR

void midOrderTraverse(TreeNode* node) {    if (node == NULL)        return;    midOrderTraverse(node->leftchild);    printf("%d\t", node->data);    midOrderTraverse(node->rightChild);}

后序遍历

若二叉树为空则结束返回,
否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点

LRD

void maxOrderTraverse(TreeNode* node) {    if (node == NULL)        return;    midOrderTraverse(node->leftchild);    midOrderTraverse(node->leftchild);    printf("%d\t", node->data);}

这里写图片描述

三,删除一个节点的操作

删除一个节点分为: 四种情况

1. 没有左右孩子节点的树的情况
2. 有左孩子的节点的树的情况
3. 有右孩子的节点的树的情况
4. 有左右孩子的节点的树的情况

1,第一种情况的分析没有左右节点的树情况

可以分为两种情况

  1. 是根(root)节点情况
  2. 不是节点的情况, 是叶子节点情况

①是根节点的情况图
这里写图片描述

//父节点为空时if (parent == NULL) {    root = NULL; //置空   }

②,不是根节点的情况是叶子结点情况

这里写图片描述

if (parent->leftchild == node) {                        parent->leftchild = node->rightChild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->leftchild;                }

二,第二种情况和第三情况

只有左孩子或者右孩子的节点
大致也分为两类

1. 是根节点
2. 不是根节点,是只有左孩子或者右或者情况的节点

①,是根(root)节点的情况
这里写图片描述

//判r断父节点if (parent == NULL) {    root = parent->leftchild;}

②,不是根节点的情况,只有左孩子或者右或者情况的节点
这里写图片描述

实现:

if (parent->leftchild == node) {                    parent->leftchild = node->leftchild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->leftchild;                } 

三,第四情况

分为两个大的情况

  1. 节点right节点的left为空的情况(node->rightChild->left == NULL)
  2. 节点的right节点的left不为空的情况(node->rightCild->left != NULL)

这里写图片描述

①,第一种情况 (node->rightChild->left == NULL)
在这种情况下面也分为两种情况

1. 是根节点
2. 不是根节点,是只有左孩子或者右或者情况的节点

if (parent->rightChild->leftchild == NULL) {                node->rightChild->leftchild = node->rightChild;                if (parent == NULL) {                    root = node->rightChild;                }                else if (parent->leftchild == node) {                    parent->leftchild = node->leftchild;                    //parent->leftchild->rightChild = node->rightChild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->leftchild;                    //parent->rightChild->leftchild = node->rightChild;                 }            }

②第二种情况(node->rightChild->leftChild != NULL)
这里写图片描述

TreeNode *leftNode = MinTreeNode(node->rightChild);                //第一步                   leftNode->leftchild = node->leftchild;                //第二步                TreeNode* leftNodep = leftNode->parent;                leftNodep->leftchild = leftNode->rightChild;                //第三步                leftNode->rightChild = node->rightChild;                //第四步                if (parent == NULL)                      root = leftNode;                 else {                     if (parent->leftchild == node)                         parent->leftchild = leftNode;                     else if (parent->rightChild == node)                         parent->rightChild = leftNode;                     //leftNode->parent = parent;                }            }

C语言的代码实现

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>typedef struct TreeNode {    int data;    struct TreeNode *leftchild;    struct TreeNode *rightChild;    struct TreeNode *parent;}TreeNode;//根节点TreeNode *root = NULL;//添加节点TreeNode* put(int data) {    //判断根节点是否为空    if (root == NULL) {        //创建根节点        root = (TreeNode *)malloc(sizeof(TreeNode));        //赋值        root->data = data;        root->leftchild = NULL;        root->rightChild = NULL;        return root;    }    //遍历比较    TreeNode *parent = NULL;    TreeNode *node = root;    //遍历遍历比较大小   ,查询找到插入的位置    for (; node != NULL; ) {        parent = node;        //比较值        if (data < parent->data)             node = parent->leftchild;        else if (data > parent->data)            node = parent->rightChild;        else             return node;    }    //创建节点    TreeNode* newNode = (TreeNode *)malloc(sizeof(TreeNode));    //赋值操作    newNode->data = data;    newNode->leftchild = NULL;    newNode->rightChild = NULL;    if (data < parent->data) {        parent->leftchild = newNode;    }    else {        parent->rightChild = newNode;    }    //child指针父节点parent    newNode->parent = parent;    return newNode;}/*** 中序遍历*/void midOrderTraverse(TreeNode* node) {    if (node == NULL)        return;    midOrderTraverse(node->leftchild);    printf("%d\t", node->data);    midOrderTraverse(node->rightChild);}/*** 后序遍历*/void maxOrderTraverse(TreeNode* node) {    if (node == NULL)        return;    midOrderTraverse(node->leftchild);    midOrderTraverse(node->leftchild);    printf("%d\t", node->data);}/*前序遍历*/void modleOrderTraverse(TreeNode *node) {    if (node == NULL)        return;    printf("%d\t", node->data);    modleOrderTraverse(node->leftchild);    modleOrderTraverse(node->rightChild);}TreeNode * MinTreeNode(TreeNode *node) {    if (node == NULL) {        printf("方法名:%s\n", __FUNCTION__);        return NULL;    }    else {        while (node->leftchild != NULL) {            node = node->leftchild;        }        return node;    }}/*   删除一个节点*/void delNode(TreeNode *node) {    if (node == NULL) {        printf("node == null\n");    }    else {        TreeNode *parent = node->parent;        //1, 没有孩子        if ((node->rightChild == NULL) && (node->leftchild == NULL)) {            //父节点为空时            if (parent == NULL) {                root = NULL;                }            else {                if (parent->leftchild == node) {                        parent->leftchild = node->rightChild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->leftchild;                }            }            //释放节点的内存            free(node);            //节点数据置空            node->data = NULL;            //父指针            node->parent = NULL;            node = NULL;        }        else if ((node->rightChild == NULL) && (node->leftchild != NULL)) {            //2, 有左孩子            //判r断父节点            if (parent == NULL) {                root = parent->leftchild;            }            else {                if (parent->leftchild == node) {                    parent->leftchild = node->leftchild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->leftchild;                }             }            //释放节点的内存            free(node);            //节点数据置空            node->data = NULL;                //父指针            node->parent = NULL;            node = NULL;        }        else if ((node->rightChild != NULL) && (node->leftchild == NULL)) {            //3,  有右孩子            //判断父节点            if (parent == NULL) {                root = parent->rightChild;                //parent->rightChild->parent = NULL;            }            else {                if (parent->leftchild == node) {                    parent->leftchild = node->rightChild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->rightChild;                }            }            //释放节点的内存            free(node);            //节点数据置空            node->data = NULL;            //父指针            node->parent = NULL;            node = NULL;        }        else if ((node->rightChild != NULL) && (node->leftchild != NULL)) {            //4, 有左右孩子            if (parent->rightChild->leftchild == NULL) {                node->rightChild->leftchild = node->rightChild;                if (parent == NULL) {                    root = node->rightChild;                }                else if (parent->leftchild == node) {                    parent->leftchild = node->leftchild;                    //parent->leftchild->rightChild = node->rightChild;                }                else if (parent->rightChild == node) {                    parent->rightChild = node->leftchild;                    //parent->rightChild->leftchild = node->rightChild;                 }            }            else {                TreeNode *leftNode = MinTreeNode(node->rightChild);                //第一步                   leftNode->leftchild = node->leftchild;                //第二步                TreeNode* leftNodep = leftNode->parent;                leftNodep->leftchild = leftNode->rightChild;                //第三步                leftNode->rightChild = node->rightChild;                //第四步                if (parent == NULL)                      root = leftNode;                 else {                     if (parent->leftchild == node)                         parent->leftchild = leftNode;                     else if (parent->rightChild == node)                         parent->rightChild = leftNode;                     //leftNode->parent = parent;                }            }            //释放节点的内存            free(node);            //节点数据置空            node->data = NULL;            //父指针             node->parent = NULL;            node = NULL;        }    }}TreeNode* searchNode(int data) {    if (root == NULL) {        return NULL;    }    TreeNode* node = root;    while (node != NULL) {        if (node->data == data) {            return node;        }        else if (node->data < data) {            node = node->rightChild;        }        else if (node->data > data) {            node = node->leftchild;        }    }    return NULL;}int main(int argc, char* argv[]){    int arrays[] = {12, 3, 23, 5, 8, 1, 19, 2, 4, 56, 45, 34, 23, 33};    for (int i = 0; i < 14; i++)        put(arrays[i]);    printf("中序遍历\n");    midOrderTraverse(root);    printf("\n");    printf("前序遍历\n");    printf("\n");    modleOrderTraverse(root);    printf("\n");    printf("后序遍历\n");    printf("\n");    maxOrderTraverse(root);    TreeNode * del = searchNode(33);    delNode(del);    printf("\n");    midOrderTraverse(root);    //modleOrderTraverse(root);    printf("\n");    system("pause");    return EXIT_SUCCESS;}

Java代码的实现

package com.songli.BinarayTree;import java.util.NoSuchElementException;import com.sun.jmx.snmp.BerException;/**    > Author: songli    > QQ: 2734030745    > Mail: 15850774503@163.com    > CSDN: http://my.csdn.net/Poisx    > github: https://github.com/chensongpoixs */public class SearchBinaryTree {    //根节点    public TreeNode root;    public class TreeNode {        int data;        TreeNode leftChild;        TreeNode rightChild;        TreeNode parent;        /**         * @return the data         */        public int getData() {            return data;        }        /**         * @param data the data to set         */        public void setData(int data) {            this.data = data;        }        /**         * @return the leftChild         */        public TreeNode getLeftChild() {            return leftChild;        }        /**         * @param leftChild the leftChild to set         */        public void setLeftChild(TreeNode leftChild) {            this.leftChild = leftChild;        }        /**         * @return the rightChild         */        public TreeNode getRightChild() {            return rightChild;        }        /**         * @param rightChild the rightChild to set         */        public void setRightChild(TreeNode rightChild) {            this.rightChild = rightChild;        }        /**         * @return the parent         */        public TreeNode getParent() {            return parent;        }        /**         * @param parent the parent to set         */        public void setParent(TreeNode parent) {            this.parent = parent;        }        /**         * 构造器         * @param data         * @param leftChild         * @param rightChild         * @param parent         */        public TreeNode(int data) {            super();            this.data = data;            this.leftChild = null;            this.rightChild = null;            this.parent = null;        }     }    public TreeNode getRoot() {        return root;    }    /**     * 添加节点     * @param data     * @return     */    public TreeNode put(int data) {        //判断根节点是否为空        if (root == null){            //创建节点            TreeNode node = new TreeNode(data);            //赋值给根节点            root = node;            return node; //返回节点        }        //遍历比较        TreeNode parent = null;        //得到根节点        TreeNode node = root;        //遍历比较节点的大小        for (; node != null; ) {            parent = node;            //比较当前节点的值            if (data < node.data) {                node = node.leftChild;            } else if(data > node.data) {                node = node.rightChild;            } else {                //相等情况返回                return node;            }        }        //添加节点        TreeNode newNode = new TreeNode(data);        if (data < parent.data) {            parent.leftChild = newNode;        } else {            parent.rightChild = newNode;        }        //child指针父节点parent        newNode.parent = parent;        return newNode;    }    /**     * 前序遍历     * @param root     */    public void preOrderTraverse(TreeNode root) {        if (root == null)             return;        System.out.println("pro Order : " + root.data);        preOrderTraverse(root.leftChild);        preOrderTraverse(root.rightChild);    }    /**     * 中序遍历                            时间复杂度 :O(n)     * @param root     */    public void midOrderTraverse(TreeNode root) {        if (root == null)             return;        midOrderTraverse(root.leftChild);        System.out.print(root.data + " ");        midOrderTraverse(root.rightChild);    }    /**     *      * @param data     * @return     */    public TreeNode searchNode(int data) {        if (root == null)             return null;        //比较right和left节点的大小           TreeNode node = root;        //在java中不要使用   递归        while (node != null) {            //比较当前节点            if (node.data == data)                return node;            else if (node.data < data)                 node = node.rightChild;            else if (node.data > data)                 node = node.leftChild;        }        //不存节点在返回null        return null;    }    /**     * 删除一个节点     * @param node     */    private void delNode(TreeNode node) {        if (node == null) {            //异常报错历   没有成            throw new NoSuchElementException();        } else {            TreeNode parent = node.parent;            //1,没有right 和left 子树            if ((node.leftChild == null) && (node.rightChild == null)) {                //判断父节点是否为空                if (parent == null) {                    root = null;                } else if (parent.leftChild == node) {                    parent.leftChild = null;                } else if (parent.rightChild == node) {                    parent.rightChild = null;                }                node.parent = null;            } else if ((node.leftChild != null) && (node.rightChild == null)) {                //2,有left子树                if (parent == null) {                    node.parent = null;                    parent.leftChild.parent = null;  //改变孩子的指针                     root = node.leftChild;                } else {                    if (parent.leftChild == node) {                        parent.leftChild = node.leftChild;                                  } else if (parent.rightChild == node) {                        parent.rightChild = node.rightChild;                    }                    node.parent = null;                }            } else if ((node.leftChild == null) && (node.rightChild != null)) {                //3,有ringht子树                if (parent == null) {                    node.parent = null;                    parent.rightChild.parent = null;  //改变孩子的指针                     root = node.rightChild;                } else {                    if (parent.leftChild == node) {                        parent.leftChild = node.leftChild;                    } else if (parent.rightChild == node) {                        parent.rightChild = node.rightChild;                    }                    node.parent = null;                }            } else if ((node.leftChild != null) && (node.rightChild != null)) {                //4,有letf, ringht树                if (node.rightChild.leftChild == null) {                    if (parent == null) {                        root = node.rightChild;                    } else {                        if (parent.leftChild == node) {                            parent.leftChild = node.rightChild;                        } else if (parent.rightChild == node) {                            parent.rightChild = node.rightChild;                        }                    }                    node.parent = null;                } else {                    TreeNode newleftNode = MinleftNode(node.rightChild);                    //第一步                    newleftNode.leftChild = node.leftChild;                    //第二步                    TreeNode newleftNodeP = newleftNode.parent;                    newleftNodeP.leftChild = newleftNode.rightChild;                    //第三步                    newleftNode.rightChild = node.rightChild;                    //第四步                    if (parent == null) {                        root = newleftNode;                    } else {                        if (parent.leftChild == node) {                            parent.leftChild = newleftNode;                        } else if (parent.rightChild == node) {                            parent.rightChild = newleftNode;                        }                    }                   }                //node.parent = null;                //node = null;                  }           }    }    /**     * @param rightChild     * @return     */    private TreeNode MinleftNode(TreeNode node) {        // TODO Auto-generated method stub        if (node == null) {            return null;        } else {            while (node.leftChild != null) {                node = node.leftChild;            }            return node;        }    }    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        int arrays[] = {12, 3, 23, 5, 8, 1, 19, 2, 4, 56, 45, 34, 23, 33};        SearchBinaryTree tree = new SearchBinaryTree();        for (int i: arrays)             tree.put(i);        //打印        tree.midOrderTraverse(tree.root);        //查找树        TreeNode node = tree.searchNode(23);        //System.out.println(node != null ? node.data: null);        System.out.println();        tree.delNode(node);        //打印        tree.midOrderTraverse(tree.root);    }}