資料結構與演算法——二叉排序樹詳解以及代碼實現__二叉排序樹

來源:互聯網
上載者:User
二叉排序樹介紹

我們知道二叉樹,每個結點最多有2棵子樹,被稱為左子樹 和 右子樹。
二叉排序樹,顯然也是一顆二叉樹,它有更突出的特性在資料域上呈現排序的特性
二叉排序樹中,每個樹的左子樹的資料域均小於它的根結點值,每個樹的右子樹的資料域均大於它的根結點值,每棵樹的左、右子樹 均為二叉排序樹。從它特性很容易得到,對二叉排序樹 進行中序遍曆一定是升序序列代碼實現思路

二叉排序樹,相關演算法主要有: 建立二叉排序樹 結點的查詢 結點的插入 結點的刪除

查詢。很好實現吧,遞迴結點查詢key的值是否相等 ,不相等就遞迴查詢唄,遞迴出口 node==NULL,查詢到結點通過傳出參數返回,沒有查詢到返回離key值最近的結點

插入。根據二叉排序的特性進行插入唄,可以調用查詢介面,如果二叉排序樹沒有該結點,則允許插入,將插入結點掛到返回的結點上唄

刪除。刪除就要分情況了,第3種情況有點繞,初學者要好好結合代碼理解。 待刪除結點,只有左子樹,可以直接用其左子樹替換刪除結點,因為它的左子樹上的所以結點都比它值小,仍然符合二叉排序的特性 待刪除結點,只有右子樹,同理可以直接使用其右子樹替換刪除結點,因為它的右子樹上 待刪除結點,左右子樹都存在,如何是好呢。因為我們刪除結點之後,仍然要滿足二叉排序樹的特性,每個樹結點的左子樹比都比它小,右子樹都比它大。現在就要想到前面提到的特性了,二叉排排序樹的中序遍曆一定是升序序列,刪除結點的資料域可以使用 中序遍曆的前驅結點 或者後驅結點資料域替換。有木有,注意這裡只替換資料域,因為原來的邏輯關係還要保留所以不能釋放刪除結點的記憶體,而釋放的是替換的前驅結點或者後驅結點

建立二叉排序樹。利用插入演算法直接實現唄,剛開始為空白二叉樹,利用插入演算法,可以產生二叉排序樹。 實現代碼

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>//二叉樹節點typedef struct BiNode {    int data;    struct BiNode* lchild, *rchild;}BiNode,*BiTree;typedef enum bool{ false,true }bool;//二叉樹 中序遍曆void TraverseMid(BiTree root){    if (root == NULL)    {        return;    }    TraverseMid(root->lchild);    printf("%d ", root->data);    TraverseMid(root->rchild);}/*二叉排序樹的查詢    tree    尋找的二叉樹根結點    parent  tree的雙親結點    node    傳出參數,尋找到的結點指標,沒找到為最接近key的結點的指標    key     尋找關鍵字*/bool SearchBST(BiTree root,BiTree parent,BiNode** node,int key ){    if (root == NULL)               //已經找到頭了,還沒有找到,返回最接近key的結點的指標    {        *node = parent;        return false;    }    else    {        if (key < root->data)       //key 比root 小,搜尋root的左子樹        {            return SearchBST(root->lchild, root, node, key);        }        else if(key > root->data)   //key 比root 大,搜尋root的右子樹        {            return SearchBST(root->rchild, root, node, key);        }        else                        //key == root->data,找到key 返回        {            *node = root;            return true;        }    }}//插入bool InsertBST(BiTree root, int data){    BiNode* node = NULL;    if (SearchBST(root, NULL, &node, data)) //在樹上有相同的結點,不允許插入    {        return false;    }    else    {        BiNode * newNode = (BiNode*)malloc(sizeof(BiNode));        newNode->lchild = newNode->rchild = NULL;        newNode->data = data;        if (data < node->data)        {            node->lchild = newNode;        }        else        {            node->rchild = newNode;        }        return true;    }}//具體刪除結點動作bool DeleteNode(BiTree* node){    BiTree tmp, pre, pre_parent;    if ((*node)->lchild == NULL)                    //刪除結點的左子樹為NULL,將右子樹頂替,釋放刪除結點記憶體    {        tmp = *node;        *node = (*node)->rchild;                                        free(tmp);    }    else if ((*node)->rchild == NULL)               //刪除結點的右子樹為NULL,將左子樹頂替,釋放刪除結點記憶體    {        tmp = *node;        *node = (*node)->lchild;        free(tmp);    }    else                                            //刪除結點的左右子樹均不為空白,刪除結點資料換成其前驅或者後繼的資料 結點並不釋放,這裡換成前驅    {        pre_parent = *node;        pre = pre_parent->lchild;                   //pre 刪除結點的中序遍曆前驅結點        while (pre->rchild != NULL)                 //while迴圈 尋找左子樹中最大結點        {            pre_parent = pre;            pre = pre->rchild;        }        if (pre == (*node)->lchild)        {            (*node)->data = pre->data;            (*node)->lchild = pre->lchild;        }        else        {            (*node)->data = pre->data;            pre_parent->rchild = pre->lchild;        }        free(pre);    }    return true;}//刪除bool DeleteBST(BiTree *root, int key){    if (root == NULL)        return false;    if (key == (*root)->data)    {        return DeleteNode(root);    }    else if (key < (*root)->data)    {        return DeleteBST(&(*root)->lchild, key);    }    else    {        return DeleteBST(&(*root)->rchild, key);    }}//利用二叉樹插入操作,建立二叉排序樹void CreateBST(BiTree *tree){    int num;    printf("請輸入根節點資料:");    scanf("%d", &num);    *tree = malloc(sizeof(BiNode));    (*tree)->data = num;    (*tree)->lchild = (*tree)->rchild = NULL;    while (1)    {        printf("請輸入結點資料(-1結束):");        scanf("%d", &num);        if (num == -1)        {            break;        }        InsertBST(*tree, num);    }}int main(int argc, char *argv[]){    BiTree binarySortTree;//二叉排序樹    CreateBST(&binarySortTree);    int menu, key,ret;    BiNode* node;    while (1)    {        printf("----菜單----------------\n");        printf("----1.中序遍曆二叉排序樹\n");        printf("----2.尋找結點\n");        printf("----3.插入結點\n");        printf("----4.刪除結點\n");        printf("----5.退出\n");        scanf("%d", &menu);        switch (menu)        {        case 1:            TraverseMid(binarySortTree);            printf("\n");            break;        case 2:            printf("請輸入key:");            scanf("%d", &key);            ret = SearchBST(binarySortTree, NULL, &node, key);            ret == true ? printf("%d存在\n",key) : printf("%d不存在\n", key);            break;        case 3:            printf("請輸入插入data:");            scanf("%d", &key);            ret = InsertBST(binarySortTree,key);            ret == true ? printf("%d插入成功\n", key) : printf("%d插入失敗\n", key);            break;        case 4:            printf("請輸入刪除data:");            scanf("%d", &key);            ret = DeleteBST(&binarySortTree,key);            ret == true ? printf("%d刪除成功\n", key) : printf("%d刪除失敗\n", key);            break;        case 5:            exit(0);        }    }    return 0;}
運行檢測


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.