二叉查詢樹(二叉排序樹)

life4711發表於2014-12-17

二叉排序樹的建立,查詢,刪除節點的操作。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
struct node
{
    int key;///結點值
    node *left;
    node *right;
    node *parent;///指向父親結點的指標
};

///遞迴中序遍歷排序二叉樹
void show(node *p)
{
    if (p==NULL) return;
    if (p->left != NULL) show(p->left);
    printf("%d ",p->key);
    if (p->right != NULL) show(p->right);

}

///插入結點
void inseart(node ** root,int key)
{
    node *p=new node;
    //  node1 p=(node1)malloc(sizeof(node));
    p->key=key;
    p->left=p->right=p->parent=NULL;
    ///空樹時作為根結點
    if((*root)==NULL)
    {
        *root=p;
        return;
    }
    ///插入到*root的左孩子
    // printf("%d\n",root->key);
    if((*root)->left==NULL&&(*root)->key>key)
    {
        p->parent=(*root);
        (*root)->left=p;
        return;
    }
    ///插入到*root的右孩子
    if((*root)->right==NULL&&(*root)->key<key)
    {
        p->parent=(*root);
        (*root)->right=p;
        return;
    }
    if((*root)->key>key)
        inseart(&(*root)->left,key);
    else if((*root)->key<key)
        inseart(&(*root)->right,key);
    else
        return;
}

///建立二叉排序樹
void create(node **root,int *a,int length)
{
    for(int i=0; i<length; i++)
        inseart(root,a[i]);
}
///查詢二叉排序樹
node* search(node *root,int key)
{
    if(root==NULL)
        return NULL;
    if(key>root->key)
        return search(root->right,key);
    else if(key<root->key)
        return search(root->left,key);
    else
        return root;
}
///查詢最小關鍵字,空樹的時候返回NULL
node* searchMin(node *root)
{
    if(root==NULL)
        return NULL;
    if(root->left==NULL)
        return root;
    else
        return searchMin(root->left);
}

///查詢最大關鍵字,空樹的時候返回NULL
node* searchMax(node *root)
{
    if(root=NULL)
        return NULL;
    if(root->right==NULL)
        return root;
    else
        return searchMax(root->right);
}

///查詢一個結點的前驅(排序二叉樹中第一個比它的值小的結點)
node* searchPredecessor(node *p)
{
     /// 空樹
     if(p==NULL)    
        return p;
     ///有左子樹,左子樹中最大的那個
     if(p->left)
        return searchMax(p->left);
     ///無左子樹,查詢某個結點的右子樹,遍歷完了
     else
     {
         if(p->parent==NULL)
            reutrn NULL;
         ///向上尋找前驅
         while(p)
         {
             if(p->parent->right==p)
                  break;
             p=p->parent;
         }
         return p->parent;
     }
}

///查詢每個結點的後繼(排序二叉樹中第一個比它的值大的結點)
node* searchSuccessor(node* p)
{
    ///空樹
    if(p==NULL)
        return p;
    ///有右子樹,右子樹中最小的那個
    if(p->right)
        return searchMin(p->right);
    ///無右子樹,查詢某個結點的左子樹遍歷完了
    else
    {
        if(p->parent==NULL)
            return NULL;
        while(p)
        {
            if(p->parent->left==p)
                break;
            p=p->parent;
        }
        return p->parent;
    }
}

///刪除結點,結點不存在返回0
int delete_node(node ** root,int key)
{
    node* q;
    node *p=search(*root,key);
    int temp;
    if(!p)
        return 0;
    ///1.被刪結點是葉子結點,直接刪除
    if(p->left==NULL&&p->right==NULL)
    {
        if(p->parent==NULL)
        {
            delete(p);
            (*root)=NULL;
        }
        else
        {
            if(p->parent->left==p)
                p->parent->left=NULL;
            else
                p->parent->right=NULL;
            delete(p);
        }
    }
    ///2被刪除的結點只有左子樹
    else if(p->left&&!(p->right))
    {
        p->left->parent=p->right;
        ///如果刪除的是父結點,要改變父結點指標
        if(p->parent==NULL)
            *root=p->left;
        ///刪除的父親結點的左孩子
        else if(p->parent->left==p)
            p->parent->left=p->left;
        ///刪除的父親結點的右孩子
        else
            p->parent->right=p->left;
        delete(p);
    }
    ///3被刪除的結點只有右孩子
    else if(p->right&&!(p->left))
    {
        p->right->parent=p->parent;
        ///如果刪除的是父結點,要改變父結點指標
        if(p->parent==NULL)
            *root=p->right;
        ///刪除的父親結點的左孩子
        else if(p->parent->left==p)
            p->parent->left=p->right;
        ///刪除的父親結點的右孩子
        else
            p->parent->right=p->right;
        delete(p);
    }
    ///4被刪除的結點既有左孩子又有右孩子
    else
    {
        q=searchSuccessor(p);
        temp=q->key;
        delete_node(root,q->key);
        p->key=temp;
    }
    return 1;
}
int main()
{
    int a[11]= {15,6,18,3,7,17,20,2,4,10,9};
    node *root = NULL;
    create(&root,a,11);
    ///遍歷
    show(root);
    ///查詢
    printf("%d\n",search(root,17)->key);
    ///刪除
    for(int i=0; i<11; i++)
    {
        printf("%d\n",a[i]);
        delete_node(&root,a[i]);
        show(root);
        printf("\n");
    }
    return 0;
}


相關文章