【数据结构】搜索二叉树

来源:互联网 发布:淘宝 门禁ic卡 编辑:程序博客网 时间:2024/06/05 05:04

手写实现搜索二叉树:


  • 树的节点定义:
class TreeNode{public:    TreeNode(int v) :value(v){};    TreeNode* left_son = NULL;    TreeNode* right_son = NULL;    TreeNode* p = NULL;         //一定保存双亲的指针    int value = 0;};

  • 节点插入:
bool TreeInsert(TreeNode*& pRoot,int value){    TreeNode* pNew = new TreeNode(value);//待插入的节点    TreeNode* pParent = NULL;//父节点    TreeNode* pCur = pRoot;//子节点    while (pCur != NULL)    {        pParent = pCur;        if (pCur->value < value)        {            pCur = pCur->right_son;        }        else if (pCur->value>value)        {            pCur = pCur->left_son;        }        else        {            return false;        }    }    if (pParent == NULL)//空树    {        pRoot = pNew;    }    else if ( pParent->value<value )//插右边    {        pParent->right_son = pNew;        pNew->p = pParent;    }    else//插左边    {        pParent->left_son = pNew;        pNew->p = pParent;    }    return true;}

  • 最大值,最小值函数
TreeNode* TreeMax(TreeNode* pRoot){    while (pRoot!=NULL&&pRoot->right_son!=NULL)    {        pRoot = pRoot->right_son;    }    return pRoot;}TreeNode* TreeMin(TreeNode* pRoot){    while (pRoot!=NULL&&pRoot->left_son!=NULL)    {        pRoot = pRoot->left_son;    }    return pRoot;}

  • 前驱、后继函数
TreeNode* Successor(TreeNode* pRoot){    /*    寻找节点的后继节点    方法一:中序遍历,后继即 该节点输出的后一个节点    方法二:若当前节点有右孩子,则后继为右孩子子树的最小节点            若当前节点无右孩子,则后继为其最底层的祖先,条件是该结点位于此祖先的左子树    */    if (pRoot==NULL)    {        return pRoot;    }    if (pRoot->right_son != NULL)// 当前节点有右孩子    {        return TreeMin(pRoot->right_son);    }    TreeNode* pChild = pRoot;    TreeNode* pParent = pChild->p;    while (pParent != NULL&&pParent->right_son == pChild)//当前节点无右孩子,寻找满足要求的最底层祖先    {        pChild = pParent;        pParent = pParent->p;    }    return pParent;}TreeNode* Processor(TreeNode* pRoot){    /*    寻找节点的前驱节点    若当前节点有左孩子,则前驱为左孩子子树的最大节点    若当前节点无左孩子,则后继为其最底层的祖先,条件是该结点位于此祖先的右子树    */    if (pRoot == NULL)    {        return pRoot;    }    if (pRoot->left_son != NULL)//有左孩子    {        return TreeMax(pRoot->left_son);    }    TreeNode* pChild = pRoot;    TreeNode* pParent = pChild->p;    while (pParent != NULL&&pParent->left_son == pChild)//无左孩子,寻找满足要求的最底层祖先    {        pChild = pParent;        pParent = pParent->p;    }    return pParent;}

  • 替换函数,使用一棵树接管另一棵树的双亲
bool TransPlant(TreeNode *& pRoot, TreeNode* pOld, TreeNode* pNew){    /*    使用一棵树接管另一棵树的双亲    */    if (pRoot == NULL||pOld == NULL)//旧子树为空    {        return false;    }    //调整父节点的指针    if (pOld->p == NULL)//父节点为空:替换了根节点    {        pRoot = pNew;    }    else    {        if (pOld == pOld->p->left_son)        {            pOld->p->left_son = pNew;        }        else        {            pOld->p->right_son = pNew;        }    }    //调整指向父节点的指针    if (pNew != NULL)//新子树不为空    {        pNew->p = pOld->p;    }    return true;}
  • 删除节点
void TreeDelete(TreeNode*& pRoot, TreeNode* pDelete){    /*    删除指定节点    */    if (pRoot == NULL || pDelete == NULL)        return;    if (pDelete->left_son == NULL)//没有孩子或者只有一个孩子,直接将孩子提上来    {        TransPlant(pRoot,pDelete, pDelete->right_son);    }    else if (pDelete->right_son == NULL)    {        TransPlant(pRoot,pDelete, pDelete->left_son);    }    else//同时有两个孩子时    {        TreeNode* successor = TreeMin(pDelete->right_son);//寻找后继,后继一定没有左孩子节点        if (successor->p != pDelete)//后继不是被删除节点的右孩子节点        {            TransPlant(pRoot,successor, successor->right_son);//删除后继节点            successor->right_son = pDelete->right_son;//将后继提到被删除节点右孩子位置上:接管被删除节点的右孩子            successor->right_son->p = successor;        }        TransPlant(pRoot,pDelete, successor);//后继接管被删节点的双亲        successor->left_son = pDelete->left_son;//后继接管被删节点的左孩子        successor->left_son->p = successor;    }}

  • 中序打印函数
  • 测试主函数
void TreePrint(TreeNode* pRoot){    if (pRoot == NULL)    {        return;    }    TreePrint(pRoot->left_son);    cout << pRoot->value << " ";    TreePrint(pRoot->right_son);}int main(){    TreeNode* pRoot(NULL);    TreeInsert(pRoot, 4);    TreeInsert(pRoot, 1);    TreeInsert(pRoot, 9);    TreeInsert(pRoot, 2);    TreeInsert(pRoot, 8);    TreeInsert(pRoot, 3);    TreeInsert(pRoot, 6);    TreePrint(pRoot);    cout << endl;    TreeDelete(pRoot,pRoot);    TreePrint(pRoot);    return 0;}
原创粉丝点击