二叉排序樹查找所在層次 與判斷是否爲二叉排序樹

二叉排序樹

 二叉排序樹的遞歸查找
 二叉排序樹的插入
 二叉排序樹的建立
 二叉排序樹的刪除ios

提示:判斷是否爲二叉排序樹時,根據二叉排序樹的性質,在進行中序遍歷的時候,當前結點的值老是大於前驅結點的值,
須要在遍歷時保存前驅結點的值,這樣有利於進行判斷,基於這樣的思路來進行解題。算法

#include <iostream>
using namespace std;
#define ENDFLAG -1
//char a[10]={'5','6','7','2','1','9','8','10','3','4','#'};//全局變量
typedef struct ElemType
{
    int key;
} ElemType;

typedef struct BSTNode
{
    ElemType data;            //結點數據域
    BSTNode *lchild, *rchild; //左右孩子指針
} BSTNode, *BSTree;

//算法7.4 二叉排序樹的遞歸查找
BSTree SearchBST(BSTree T, int key)
{
    //在根指針T所指二叉排序樹中遞歸地查找某關鍵字等於key的數據元素
    //若查找成功,則返回指向該數據元素結點的指針,不然返回空指針
    if ((!T) || key == T->data.key)
        return T; //查找結束
    else if (key < T->data.key)
        return SearchBST(T->lchild, key); //在左子樹中繼續查找
    else
        return SearchBST(T->rchild, key); //在右子樹中繼續查找
} // SearchBST

//非遞歸實現查找成功時返回指向該數據元素結點的指針和所在的層次
BSTree Searchlev(BSTree T, int k, int &lev)
{
    //統計查找次數

    // BSTree p = T; //p爲二叉樹中工做指針
    
        lev++;
        while(T)
        { 
            // cout<<lev;
            if(T->data.key==k) return T;
            if(k > T->data.key){
                T = T->lchild; //在左子樹查找
                lev++;
            } else{
                T = T->rchild; //在右子樹查找
                lev++;
            }
            // cout<<lev;
        }
        // cout<<"end";
    // return T;
    return NULL;

} // Searchlev
//算法7.5 二叉排序樹的插入



// int  Level(BSTree T,int k){
//  int height=0;
//      k++;
//  if(!T)
//      return 0;
//  while (T){

//      if(T->data.key==k){
//          height++;
//          break;
//      }
//      else if(T->data.key>k){
//          height++;
//          T=T->lchild;
//      }
//      else{
//          height++;
//          T=T->rchild;
//      }
//  }
//  return height;
// }

void InsertBST(BSTree &T, ElemType e)
{
    //當二叉排序樹T中不存在關鍵字等於e.key的數據元素時,則插入該元素
    if (!T)
    {                                 //找到插入位置,遞歸結束
        BSTree S = new BSTNode;       //生成新結點*S
        S->data = e;                  //新結點*S的數據域置爲e
        S->lchild = S->rchild = NULL; //新結點*S做爲葉子結點
        T = S;                        //把新結點*S連接到已找到的插入位置
    }
    else if (e.key < T->data.key)
        InsertBST(T->lchild, e); //將*S插入左子樹
    else if (e.key > T->data.key)
        InsertBST(T->rchild, e); //將*S插入右子樹
} // InsertBST

//算法7.6 二叉排序樹的建立
void CreateBST(BSTree &T)
{
    //依次讀入一個關鍵字爲key的結點,將此結點插入二叉排序樹T中
    T = NULL;
    ElemType e;
    cin >> e.key; //???
    while (e.key != ENDFLAG)
    {                    //ENDFLAG爲自定義常量,做爲輸入結束標誌
        InsertBST(T, e); //將此結點插入二叉排序樹T中
        cin >> e.key;   //???
    }                    //while
} //CreatBST

void DeleteBST(BSTree &T, int key)
{
    //從二叉排序樹T中刪除關鍵字等於key的結點
    BSTree p = T;
    BSTree f = NULL; //初始化
    BSTree q;
    BSTree s;
    /*------------下面的while循環從根開始查找關鍵字等於key的結點*p-------------*/
    while (p)
    {
        if (p->data.key == key)
            break; //找到關鍵字等於key的結點*p,結束循環
        f = p;   //*f爲*p的雙親結點
        if (p->data.key > key)
            p = p->lchild; //在*p的左子樹中繼續查找
        else
            p = p->rchild; //在*p的右子樹中繼續查找
    }                      //while
    if (!p)
        return; //找不到被刪結點則返回
    /*―考慮三種狀況實現p所指子樹內部的處理:*p左右子樹均不空、無右子樹、無左子樹―*/
    if ((p->lchild) && (p->rchild))
    { //被刪結點*p左右子樹均不空
        q = p;
        s = p->lchild;
        while (s->rchild) //在*p的左子樹中繼續查找其前驅結點,即最右下結點
        {
            q = s;
            s = s->rchild;
        }                  //向右到盡頭
        p->data = s->data; //s指向被刪結點的「前驅」
        if (q != p)
        {
            q->rchild = s->lchild; //重接*q的右子樹
        }
        else
            q->lchild = s->lchild; //重接*q的左子樹
        delete s;
    } //if
    else
    {
        if (!p->rchild)
        { //被刪結點*p無右子樹,只需重接其左子樹
            q = p;
            p = p->lchild;
        } //else if
        else if (!p->lchild)
        { //被刪結點*p無左子樹,只需重接其右子樹
            q = p;
            p = p->rchild;
        } //else if
          /*――――――――――將p所指的子樹掛接到其雙親結點*f相應的位置――――――――*/
        if (!f)
            T = p; //被刪結點爲根結點
        else if (q == f->lchild)
            f->lchild = p; //掛接到*f的左子樹位置
        else
            f->rchild = p; //掛接到*f的右子樹位置
        delete q;
    }
} //DeleteBST

//算法 7.7 二叉排序樹的刪除

//中序遍歷
void InOrderTraverse(BSTree &T)
{
    if (T)
    {
        InOrderTraverse(T->lchild);
        cout << T->data.key << " ";
        InOrderTraverse(T->rchild);
    }
}
int predt=0;
int judgeBST(BSTree T)
{
    int b1, b2;
    if(T == NULL){
        return 1;
    }
    else{
        b1 = judgeBST(T->lchild);
        if(b1 == 0 || predt > T->data.key) return 0;
        predt = T->data.key;
        b2 = judgeBST(T->rchild);
        return b2;
    }
}

int main()
{
    BSTree T;
    int lev = 0;
    cout << "請輸入若干整數,用空格分開,以-1結束輸入" << endl;
    CreateBST(T);
    cout << "當前有序二叉樹中序遍歷結果爲" << endl;
    InOrderTraverse(T);
    cout << endl;
    int key; //待查找或待刪除內容
    cout << "請輸入待查找關鍵字(整數)" << endl;
    cin >> key;
    BSTree result = SearchBST(T, key);
    // int a=result->data.key;
    // cout<<"fghj"<< a;
    // }
    //求層數方法一
    result = Searchlev(T, key, lev);
    //方求層數法二
//    lev=Level(T,key);//沒判斷是否有這個節點,下面的result不用取非,建議用第一種

    if (!result)//這要取非
    {
        cout << "找到關鍵字" << key << "在" << lev << "層" << endl;
    }
    else
    {
        cout << "未找到" << key << endl;
    }
    //Searchpath( T, key);cout<<endl;
    cout << "請輸入待刪除的關鍵字" << endl;
    cin >> key;
    DeleteBST(T, key);
    cout << "當前有序二叉樹中序遍歷結果爲" << endl;
    InOrderTraverse(T);
    if(judgeBST(T))
       cout<<" 是一棵排序樹"<<endl;
    else
      cout<<" 不是一棵排序樹"<<endl;
    return 1;
}
相關文章
相關標籤/搜索