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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

理论基础 —— 查找 —— 二叉排序树

發布時間:2025/3/17 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 理论基础 —— 查找 —— 二叉排序树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【概述】

二叉排序樹(Binary Search Tree),又稱二叉查找樹,其本質是按一定的順序進行構造的二叉樹。

其遞歸定義如下:

  • 若其左子樹不空,則左子樹上所有結點的值均小于根結點的值
  • 若其右子樹不空,則右子樹上所有結點的值均大于根節點的值
  • 其左右子樹也是二叉排序樹

從上述定義可以看出,二叉排序樹是記錄之間滿足一定次序的二叉樹,中序遍歷二叉排序樹可以得到一個按關鍵碼有序的序列。

折半查找判定樹就是一棵二叉排序樹:點擊這里

【實現類】

template<class T> struct Node{T data;Node *lchild,*rchild; }; template<class T> class BiSortTree{ public:BiSortTree(T a[],int n);//構造函數~BiSortTree(){release(root);}//析構函數void insertBST(Node<T> *&root,Node<T> *s);//插入結點void deleteBST(Node<T> *p,Node<T> *f);//刪除結點Node<T> *searchBST(Node<T> *bt,int k);//查找結點 private:Node<T> *root;//指向根節點的頭指針void release(Node<T> *bt);//析構函數調用 };

【插入操作】

根據二叉排序樹的定義,向二叉排序樹中插入一個結點 s 的過程可用如下偽代碼描述:

  • 若 root 是空樹,則將結點 s 作為根節點插入
  • 否則,若 s->data 小于 root->data,則將結點 s 插入到 root 的左子樹中
  • 否則,將結點 s 插入到 root 的右子樹中
  • 從上述插入過程可以看出,插入的結點是作為葉結點插入到二叉排序樹中的,其過程是遞歸進行的。

    template<class T> void BiSortTree<T>::insertBST(Node<T> *&root,Node<T> *s) {if(root==NULL)root=s;else if(s->data<root->data)insertBST(root->lchild,s);elseinsertBST(root->rchild,s); }

    【構造函數】

    構造二叉排序樹的過程是從空的二叉排序樹開始,依次插入一個個結點,其構造過程可用如下偽代碼描述:

    依次取每一個記錄 a[i],進行如下操作:

    1)申請一個數據域為 a[i] 的結點 s,令結點 s 的左右指針域為空

    2)調用插入操作的方法,將結點 s 插入二叉排序樹中

    template<class T> BiSortTree<T>::BiSortTree(T a[],int n){for(int i=0;i<n;i++){Node<T> *s;s->data=a[i];s->lchild=NULL;s->rchild=NULL;insertBST(root,s);} }

    【刪除操作】

    在二叉排序樹中,由于刪除結點時,刪除的可能是葉結點也可能是分支結點,因此在刪除時,需要重新修改指針,使得刪除一個結點后,仍能保證二叉排序樹的特性。

    在二叉排序樹中的刪除操作中,設待刪除結點為 p,其父結點為 f,且 p 是 f 的左孩子,那么可分為以下三種情況進行討論:

    1.p 為葉結點

    當被刪除的結點為葉結點時,由于刪除后不影響二叉排序樹特性,因此只需將被刪除結點的父節點 f 的相應指針域改為空即可。

    如下圖,有:f->lchild=NULL

    2.p 只有左子樹 pl 或只有右子樹 pr

    當被刪除的結點僅有一棵子樹時,需要將 pl 或 pr 替換為 f 的左子樹。

    如下圖,有:f->lchild=p->lchild 或 f->rchild=p-rchild

    3.p 既有左子樹又有右子樹

    當被刪除的結點有兩棵子樹時,需要找其前驅(即:大于 p 的最小值小于 p 的最大值)來將其代替,然后刪除該前驅。

    綜上,刪除操作可用如下偽代碼描述:

    1.若結點 p 是葉結點,則直接刪除結點 p

    2.若結點 p 只有左子樹,則只需重接 p 的左子樹;若結點 p 只有右子樹,則只需重接 p 的右子樹

    3.若結點 p 的左右子樹均不空,則:
    ? 1)查找結點 p 的右子樹上的最左下結點 s 及 s 雙親結點 f
    ? 2)將結點 s 數據域替換到被刪結點 p 的數據域
    ? 3)若結點 p 的右孩子無左子樹,則將 s 的右子樹接到 f 的右子樹上;否則,將 s 的右子樹接到結點 f 的左子樹上
    ? 4)刪除結點 s?

    template<class T> void BiSortTree<T>::deleteBST(Node<T> *p,Node<T> *f){if(p->lchild==NULL && p->rchild==NULL){//p是葉結點if(f->child==p)f->lchild=NULL;elsef->lchild=NULL;delete p;}else if(p->rchild==NULL){//p只有左子樹if(f->child==p)f->lchild=p->lchild;elsef->rchild=p->lchild;delete p;}else if(p->lchild==NULL){//p只有右子樹if(f->child==p)f->lchild=p->rchild;elsef->rchild=p->rchild;delete p;}else{//左右子樹均不空f=p;Node<T> *s=p->rchild;while(s->lchild!=NULL){//查找最左下結點f=s;s=s->lchild;}p->data=s->data;if(f==p)//特殊情況p->rchild=s->rchild;else//一般情況f->lchild=s->rchild;delete s;} }

    【查找操作】

    由于二叉排序樹的定義,在二叉樹中查找給定值 k 的過程是:

    • 若 root 是空樹,查找失敗
    • 若 k=root->data,查找成功
    • 若 k<root->data,在 root 的左子樹進行查找
    • 若 k>root->data,在 root 的右子樹進行查找

    上述過程一直持續到 k 被找到或者待查找的子樹為空,若待查找的子樹為空,則查找失敗。值得注意的是,當查找失敗時,恰好找到了以 k 為鍵值的新結點在二叉排序樹中的插入位置。

    template<class T> Node<T> *BiSortTree<T>::searchBST(Node<T> *bt,int k){if(bt==NULL)return NULL;else if(bt->data==k)return bt;else if(k<bt->data)return searchBST(bt->lchild,k);elsereturn searchBST(bt->rchild,k); }

    【析構函數】

    二叉排序樹的析構函數與二叉鏈表的析構函數相同

    template<class T> void BiSortTree<T>::release(Node<T> *bt){if(bt!=NULL){release(bt->lchild);release(bt->rchild);delete bt;} }

    ?

    總結

    以上是生活随笔為你收集整理的理论基础 —— 查找 —— 二叉排序树的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。