日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

二叉排序树(BST)构造与应用

發(fā)布時(shí)間:2025/6/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉排序树(BST)构造与应用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ?二叉排序樹(BST)構(gòu)造與應(yīng)用


? ? ? 本文取自《數(shù)據(jù)結(jié)構(gòu)與算法》(C語(yǔ)言版)(第三版)。出版社是清華大學(xué)出版社。

? ? ??本博文作為學(xué)習(xí)資料整理。

源碼是VC++ 6.0上可運(yùn)行程序,我挪到了VS2010中運(yùn)行。

? ? ??在VS2010中新建C++?Win32 控制臺(tái)應(yīng)用程序項(xiàng)目,創(chuàng)建結(jié)果截圖:

? ? ? ? ??

? ??二叉排序樹(BST):又稱二叉查找樹,其定義為:二叉排序樹或者是空樹,或者是滿足下面性質(zhì)的二叉樹。
? ? ? ?(1) 若它的左子樹非空。則左子樹上全部記錄的keyword均小于根記錄的值。


? ? ? ?(2) 若它的右子樹非空,則右子樹上全部記錄的keyword均大于根記錄的值。


? ? ? ?(3) 左、右子樹本身又各是一棵二叉排序樹。
? ? ? ?按中序遍歷BST所得到的中序序列是一個(gè)遞增有序序列。


? ? ? ?二叉排序樹的類型定義:

typedef struct BSTNode{KeyType key; //數(shù)據(jù)域BSTNode *lchild;BSTNode *rchild;}? ? ?1.二叉排序樹的插入操作
? ? ? ?(1)假設(shè)二叉排序樹T為空,則創(chuàng)建一個(gè)keyword為k的結(jié)點(diǎn)。將其作為根結(jié)點(diǎn)。


? ? ? ?(2)否則將k和根結(jié)點(diǎn)的keyword進(jìn)行比較,假設(shè)相等則返回,假設(shè)k小于根結(jié)點(diǎn)的keyword則插入根結(jié)點(diǎn)的左子樹中,否則插入根結(jié)點(diǎn)的右子樹中。


? ? ? ? 二叉排序樹的插入算法:


int InsertBST(BSTNode *p, KeyType k){if(p==NULL){p=(BSTNode*)malloc(sizeof(BSTNode));p->key=k;p->lchild=p->rchild=NULL;return 1;}else if(k==p->key)return 0;else if(k<p->key)return InsertBST(p->lchild, k);elsereturn InsertBST(p->rchild, k);}? ? ? ?二叉排序樹的生成算法:
BSTNode *CreateBST(KeyType A[], int n){BSTNode *bt=NULL;int i=0;while(i<n){InsertBST(bt, A[i]);i++;}return bt;}? ? ? ?演示樣例:輸入{50,16,56,52,8}生成二叉排序樹

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

? ? ? ?2.二叉排序樹的查找操作
? ? ? ?首先將須要查找的值與根結(jié)點(diǎn)比較,假設(shè)相等則查找成功,算法終止。假設(shè)比根結(jié)點(diǎn)小則左子樹中查找,假設(shè)比根結(jié)點(diǎn)大則到右子樹查找。
? ? ? ?二叉排序樹的查找算法的遞歸形式

BSTree SearchBST(BSTree t, int k){if(t==null || k==t->key)return t;else if(k<t->key)return SearchBST(t->lchild, k);elsereturn SearchBST(t->rchild, k);}? ? ? 二叉排序樹的查找算法的非遞歸形式
BSTree SearchBST2(BSTree t, int k){BSTree p=t;while(p!=null && p->key!=k){if(k<p->key)p=p->lchild;elsep=p->rchild;}return p;}

? ? ? ?查找過程演示圖:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? 3.二叉排序樹的刪除操作

? ? ? ? 刪除二叉排序樹的某一個(gè)結(jié)點(diǎn)的過程例如以下:
? ? ? ? 1)查找待刪除的結(jié)點(diǎn)
? ? ? ? ?查找結(jié)點(diǎn)時(shí),令*p指向其訪問到的結(jié)點(diǎn),*f指向其雙親結(jié)點(diǎn)。若樹中找不到被刪結(jié)點(diǎn)時(shí)返回NULL,否則被刪除結(jié)點(diǎn)是*p,返回*p。
? ? ? ? 2)刪除結(jié)點(diǎn)
? ? ? ? 如果要?jiǎng)h除二叉排序樹中的一個(gè)結(jié)點(diǎn)*p,其雙親結(jié)點(diǎn)為*f,則刪除結(jié)點(diǎn)*p時(shí),需考慮下面3種情況:
? ? ? ? ? ?(1)*p為葉子結(jié)點(diǎn)。
? ? ? ? ? ?在這樣的情況下,能夠?qū)?p結(jié)點(diǎn)直接刪除。
? ? ? ? ? ?p為左子樹:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f->lchild=NULL;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? free(p);
? ? ? ? ? ?p為右子樹:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? f->rclild=NULl;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? free(p);

? ? ? ? ? ?操作示意圖例如以下:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ?(2)*p僅僅有左子樹,或僅僅有右子樹。
? ? ? ? ? ? 對(duì)于這樣的情況,能夠直接將*p的左子樹或右子樹與其雙親結(jié)點(diǎn)*f相連,然后刪除*p。
? ? ? ? ? ? p為f的左孩子。p的左子樹非空:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f->lchild=p->lchild;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(p);
? ? ? ? ? ? p為f的左孩子。p的右子樹非空:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f->lchild=p->rchild;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(p);?
? ? ? ? ? ? p為f的右孩子,p的左子樹非空:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f->rchild=p->lchild;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(p);
? ? ? ? ? ? p為f的右孩子,p的右子樹非空:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?f->rchild=p->rchild;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(p);

? ? ? ? ? ??操作示意圖例如以下:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ?(3)*p有左右子樹。


? ? ? ? ? ? 方法一:設(shè)*s為*p結(jié)點(diǎn)在中序序列中的直接前驅(qū)。將*p的左子樹改為*f的左子樹,將*p的右子樹改為*s的右子樹。


? ? ? ? ? ? ? ? ? ? ? f->lchild=p->lchild;
? ? ? ? ? ? ? ? ? ? ? s->rchild=p->rchild;

? ? ? ? ? ? ? ? ? ? ? free(p);

? ? ? ? ? ??操作示意圖例如以下:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? 方法二:用*p結(jié)點(diǎn)在中序序列中的直接前驅(qū)(或后繼)*s取代*p,然后再?gòu)亩媾判驑渲袑?s刪除。

這時(shí)假設(shè)*s為*p的直接前驅(qū),則*s僅僅有左子樹(或者沒有孩子),則刪除*s能夠依照刪除*p的其余兩種情況處理。假設(shè)*s為*p的直接后繼,則*s僅僅有右子樹(或者沒有孩子)。刪除*s同理能夠依照刪除*p的其余兩種情況處理。?


附錄 ?

? ? ? A.二叉排序樹的構(gòu)造算法:

? ? ? 注:判定一棵二叉樹是二叉排序樹能夠採(cǎi)用中序遍歷算法將樹上的頂點(diǎn)輸出。假設(shè)得到的中序序列是有序的。則說明這棵二叉樹是二叉排序樹,否則不是二叉排序樹。 #include<stdio.h>#include<stdlib.h>#define MAX 100typedef struct tnode{int data;struct tnode *lchild, *rchild;}TNODE;void create();void insert(int m); //插入二叉排序樹的結(jié)點(diǎn)void inOrder(TNODE *ptr); //中序遍歷TNODE *root=NULL;void inOrder(TNODE *ptr){if(ptr!=NULL){inOrder(ptr->lchild);printf("%d ", ptr->data);inOrder(ptr->rchild);}}void create(){int n, i;int k[MAX];printf("Please input the node number:\n");scanf("%d", &n);for(i=0; i<n; i++)scanf("%d",&k[i]);for(i=0; i<n; i++)insert(k[i]);}void insert(int m){TNODE *p1, *p2;if(root==NULL){root=(TNODE *)malloc(sizeof(TNODE));root->data=m;root->lchild=root->rchild=NULL;}else{p1=root;while(m!=p1->data){if((m<p1->data) && (p1->lchild!=NULL))p1=p1->lchild;else if((m>p1->data) && (p1->rchild!=NULL))p1=p1->rchild;else if((m<p1->data) && (p1->lchild==NULL)){p2=(TNODE *)malloc(sizeof(TNODE));p2->data=m;p2->lchild=p2->rchild=NULL;p1->lchild=p2;return;}else if((m>p1->data) && (p1->rchild==NULL)){p2=(TNODE *)malloc(sizeof(TNODE));p2->data=m;p2->lchild=p2->rchild=NULL;p1->rchild=p2;return;}}}}int main(){create();printf("\n");inOrder(root);printf("\n");return 0;}? ? ?Ctrl+F5執(zhí)行SortTree.cpp輸出結(jié)果例如以下:

? ? ??

? ? ? B.求出二叉排序樹T中小于x的最大元素和大于x的最小元素

? ? ? 在二叉排序樹中。一個(gè)小于樹中某個(gè)結(jié)點(diǎn)的最大元素,是在中序序列中這個(gè)結(jié)點(diǎn)的直接前驅(qū);大于這個(gè)
結(jié)點(diǎn)的最小元素,是在中序序列中這個(gè)結(jié)點(diǎn)的直接后繼。
? ? ? 其程序例如以下:

#include<stdio.h>#include<stdlib.h>#define MAX 100typedef struct tnode{int data;struct tnode *lchild, *rchild;}TNODE;int last=0;void create();void insert(int m); //插入二叉排序樹的結(jié)點(diǎn)void findMaxMin(int aim, TNODE *ptr);TNODE *root=NULL;void findMaxMin(int aim, TNODE *ptr){if(ptr!=NULL){findMaxMin(aim, ptr->lchild);if(last<aim && ptr->data>=aim) //找到小于aim的最大元素printf("a=%d\n",last);if(last<=aim && ptr->data>aim) //找到大于aim的最小元素printf("b=%d\n",ptr->data);last=ptr->data;findMaxMin(aim, ptr->rchild);}}void create(){int n, i;int k[MAX];printf("Please input the node number:\n");scanf("%d", &n);for(i=0; i<n; i++)scanf("%d",&k[i]);for(i=0; i<n; i++)insert(k[i]);}void insert(int m){TNODE *p1, *p2;if(root==NULL){root=(TNODE *)malloc(sizeof(TNODE));root->data=m;root->lchild=root->rchild=NULL;}else{p1=root;while(m!=p1->data){if((m<p1->data) && (p1->lchild!=NULL))p1=p1->lchild;else if((m>p1->data) && (p1->rchild!=NULL))p1=p1->rchild;else if((m<p1->data) && (p1->lchild==NULL)){p2=(TNODE *)malloc(sizeof(TNODE));p2->data=m;p2->lchild=p2->rchild=NULL;p1->lchild=p2;return;}else if((m>p1->data) && (p1->rchild==NULL)){p2=(TNODE *)malloc(sizeof(TNODE));p2->data=m;p2->lchild=p2->rchild=NULL;p1->rchild=p2;return;}}}}int main(){int toBeFind;create();printf("\n");printf("Input the record to be finded! \n");scanf("%d", &toBeFind);findMaxMin(toBeFind, root);printf("\n");return 0;}? ? ?Ctrl+F5執(zhí)行SortTree1.cpp輸出結(jié)果例如以下:

? ? ?

總結(jié)

以上是生活随笔為你收集整理的二叉排序树(BST)构造与应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。