1. 程式人生 > >二叉排序樹的構造,插入,刪除,完整c程式碼實現

二叉排序樹的構造,插入,刪除,完整c程式碼實現

#include <stdio.h>  
#include <stdlib.h>   
typedef struct BiTNode{  
    int data;  
    struct BiTNode *lchild, *rchild;  
}BiTNode, *BiTree;   
//在給定的BST中插入結點,其資料域為element  
void BSTInsert( BiTree *t, int element )  
{  
    if( NULL == *t ) {  
        (*t) = (BiTree)malloc(sizeof(BiTNode));  
        (*t)->data = element;  
        (*t)->lchild = (*t)->rchild = NULL;  
    }  
  
    if( element == (*t)->data )  
        return ;  
  
    else if( element < (*t)->data )  
        BSTInsert( &(*t)->lchild, element );  
  
    else   
        BSTInsert( &(*t)->rchild, element );  
}  
  
//建立BST  
void CreateBST( BiTree *t, int *a, int n )  
{  
    (*t) = NULL;  
    for( int i=0; i<n; i++ )  
        BSTInsert( t, a[i] );  
}  
  
//BST的遞迴查詢  
void SearchBST( BiTree t, int key )  
{  
    BiTree p;  
    p = t;  
    if( p ) {  
        if( key == p->data )  
            printf("查詢成功!\n");  
        else if( (key < p->data) && (NULL != p->lchild) )  
            SearchBST( p->lchild , key );  
        else if( (key > p->data) && (NULL != p->rchild) )  
            SearchBST( p->rchild , key );  
        else  
            printf("無此元素!\n");  
    }  
}  
  
//BST結點的刪除  
void DelBSTNode( BiTree t, int key )  
{  
    BiTree p, q;  
    p = t;  
    int temp;  
    while( NULL != p && key != p->data ) {  
        q = p;  
        if( key < p->data )  
            p = p->lchild ;  
        else  
            p = p->rchild ;  
    }  
  
    if( NULL == p )  
        printf("無此元素!\n");  
    else {  
        //情況1:結點p的雙親結點為q,且p為葉子結點,則直接將其刪除。  
        if( NULL == p->lchild && NULL == p->rchild ) {  
            if( p == q->lchild )  
                q->lchild = NULL;  
            if( p == q->rchild )  
                q->rchild = NULL;  
            free(p);  
            p = NULL;  
        }  
        //情況2:結點p的雙親結點為q,且p只有左子樹或只有右子樹,則可將p的左子樹或右子樹直接改為其雙親結點q的左子樹或右子樹。  
        else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子樹  
            if( p == q->lchild )  
                q->lchild = p->lchild ;  
            else if( p == q->rchild )  
                q->rchild = p->lchild ;  
            free(p);  
            p = NULL;  
        }  
        else if( NULL == p->lchild && NULL != p->rchild ) {       //p只有右子樹  
            if( p == q->lchild )  
                q->lchild = p->rchild ;  
            if( p == q->rchild )  
                q->rchild = p->rchild ;  
            free(p);  
            p = NULL;  
        }  
        //情況3:結點p的雙親結點為q,且p既有左子樹又有右子樹。本程式碼使用直接前驅(也可以直接後繼)  
      
        else if( NULL != p->lchild && NULL != p->rchild ) {  
                BiTree s, sParent;   
                sParent = p;  
                s = sParent->lchild ;  
                while( NULL != s->rchild )   {   //找到p的直接前驅  
                    sParent = s;  
                    s = s->rchild ;    
                }  
                temp = s->data ;   
                DelBSTNode( t, temp );  
                p->data = temp;  
        }  
    }  
  
}  
  
//中序遍歷列印BST  
void PrintBST( BiTree t )  
{  


    if( t ) {  
        PrintBST( t->lchild);
        printf("%d ", t->data); 
        PrintBST( t->rchild);  
    } 


}  
  
int main()  
{  
    int n;  
    int *a;  
    int key;  
    BiTree t;  
    printf("請輸入二叉查詢樹的結點數:\n");  
    scanf("%d", &n);    
    a = (int *)malloc(sizeof(int)*n);  
    printf("請輸入二叉找樹的結點資料:\n");  
    for( int i=0; i<n; i++ )  
    scanf("%d", &a[i]);  
    CreateBST( &t, a, n );  
    printf("當前二叉查詢樹的遍歷為:\n");  
    PrintBST( t );  
    printf("\n");  
    printf("請輸入要查詢的元素:\n");  
    scanf("%d", &key);  
    printf("查詢結果:\n");  
    SearchBST( t, key );        //遞迴查詢  
    printf("\n");  
    printf("請輸入要刪除的元素:\n");  
    scanf("%d", &key);  
    DelBSTNode( t, key );  
    printf("當前二叉查詢樹的遍歷為:\n");  
    PrintBST( t);  
    printf("\n");  
    return 0;  

}  


程式碼已實現!