歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 二叉排序樹(BST)創建,刪除,查找操作

二叉排序樹(BST)創建,刪除,查找操作

日期:2017/3/1 9:16:57   编辑:Linux編程

binary search tree,中文翻譯為二叉搜索樹、二叉查找樹或者二叉排序樹。簡稱為BST

一:二叉搜索樹的定義

他的定義與樹的定義是類似的,也是一個遞歸的定義:

1、要麼是一棵空樹

2、如果不為空,那麼其左子樹節點的值都小於根節點的值;右子樹節點的值都大於根節點的值

3、其左右子樹也是二叉搜索樹

在算法導論中的定義:

下圖中是BST的兩個例子:

其中(b)圖中的樹是很不平衡的(所謂不平衡是值左右子樹的高度差比較大)

BST在數據結構中占有很重要的地位,一些高級樹結構都是其的變種,例如AVL樹、紅黑樹等,因此理解BST對於後續樹結構的學習有很好的作用。同時利用BST可以進行排序,稱為二叉排序,也是很重要的一種思想。

相關代碼如下:

/** 二叉排序樹(BST)創建,刪除,查找操作 **/
#include<stdio.h>
#include<stdlib.h>
#define LENGTH 15

typedef int ElemType; //數據類型 

typedef struct BiTNode{
    ElemType  data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree; 
 

/**
 * 向下遍歷查找給定結點的相鄰節點,以便插入指定節點
 */
void searchBiTreeNode(BiTree &root,BiTree &node){
    if(root == NULL){
        return;
    }
    if(root->data > node->data){
        searchBiTreeNode(root->lchild,node); //遞歸遍歷搜索
        if(root->lchild == NULL){
           root->lchild = node;
        }
    }else if(root->data < node->data){
        searchBiTreeNode(root->rchild,node);
        if(root->rchild == NULL){
           root->rchild = node;
        }
    }
}


/**
 * 插入指定節點node
 */
void insertNode(BiTree &biTree,BiTree &node){
    if(biTree==NULL){
        biTree = node;
    }else{
        searchBiTreeNode(biTree,node);
    }
}

/**
 * 刪除指定元素x
 */
void deleteNode(BiTree &root,ElemType x){
    if(root == NULL){
        return;
    }
    if(root->data>x){
        deleteNode(root->lchild,x);
    }else if(root->data<x){
        deleteNode(root->rchild,x);
    }else{ //查找到了刪除節點
        if(root->lchild == NULL){ //左子樹為空
           BiTree tempNode = root;
           root = root->rchild;
           free(tempNode);
        }else if(root->rchild == NULL){ //右子樹為空
           BiTree tempNode = root;
           root = root->lchild;
           free(tempNode);
        }else{  //左右子樹都不為空
            //一般的刪除策略是左子樹的最大數據 或 右子樹的最小數據 代替該節點(這裡采用查找左子樹最大數據來代替)
            BiTree tempNode = root->lchild;
            if(tempNode->rchild!=NULL){
                tempNode = tempNode->rchild;
            }
            root->data = tempNode->data;
            deleteNode(root->lchild,tempNode->data);
        }
    }
}


/**
 * 查找指定元素x所在的節點
 */
BiTree BST_Search(BiTree &root,ElemType x){
    if(root == NULL){
        return NULL;
    }else if(root->data>x){
        return BST_Search(root->lchild,x);
    }else if(root->data<x){
        return BST_Search(root->rchild,x);
    }else{
        return root;
    }
}


/**
 * 二叉排序樹創建
 */
void createBiOrderTree(BiTree &biTree,ElemType arr[]){
    for(int i=0;i<LENGTH;i++){
        BiTree s = (BiTree)malloc(sizeof(BiTNode));    
        s->data = arr[i];
        s->lchild = NULL;
        s->rchild = NULL;
        insertNode(biTree,s);
    }
}


/**
 * 中序打印二叉樹
 */ 
void midSearchBiTreePrint(BiTree &biTree){
    if(biTree == NULL){
        return;
    }
    midSearchBiTreePrint(biTree->lchild);
    printf("%d ",biTree->data);
    midSearchBiTreePrint(biTree->rchild);
}


/**
 * 測試程序入口
 */
int main(){
    ElemType arr[LENGTH] = {62,88,58,47,35,73,51,99,37,93,23,27,45,21,12};
    BiTree biTree = NULL;

    /** 創建二叉排序樹,並測試數據 **/
    createBiOrderTree(biTree,arr);
    midSearchBiTreePrint(biTree);
    printf("\n");

    /** 從二叉排序樹中刪除指定元素,並測試數據 **/
    deleteNode(biTree,35);
    midSearchBiTreePrint(biTree);
    printf("\n");

    /** 二叉排序樹查找指定元素操作,並測試數據 **/
    BiTree searchNode = BST_Search(biTree,27);
    if(searchNode == NULL){
        fprintf(stdout,"沒有查找到節點\n");
    }else{
        if(searchNode->lchild==NULL && searchNode->rchild==NULL){ //葉子節點
            printf("所查找的節點x=%d是葉子節點\n",searchNode->data);
        }else{ 
            if(searchNode->lchild != NULL){
                printf("x=%d所在節點的左孩子: %d\n",searchNode->data,searchNode->lchild->data);
            }
            if(searchNode->rchild != NULL){
                printf("x=%d所在節點的右孩子: %d\n",searchNode->data,searchNode->rchild->data);
            }
        }
    }
    return 0;
}

運行結果截圖:

二叉樹的常見問題及其解決程序 http://www.linuxidc.com/Linux/2013-04/83661.htm

【遞歸】二叉樹的先序建立及遍歷 http://www.linuxidc.com/Linux/2012-12/75608.htm

在JAVA中實現的二叉樹結構 http://www.linuxidc.com/Linux/2008-12/17690.htm

【非遞歸】二叉樹的建立及遍歷 http://www.linuxidc.com/Linux/2012-12/75607.htm

二叉樹遞歸實現與二重指針 http://www.linuxidc.com/Linux/2013-07/87373.htm

二叉樹先序中序非遞歸算法 http://www.linuxidc.com/Linux/2014-06/102935.htm

輕松搞定面試中的二叉樹題目 http://www.linuxidc.com/linux/2014-07/104857.htm

Copyright © Linux教程網 All Rights Reserved