資料結構 折半遞迴查詢,二叉排序樹查詢
阿新 • • 發佈:2019-01-10
實驗題目: 查詢演算法實現與分析
實驗環境: Visual C++ 6.0
實驗專案七:查詢演算法實現與分析
實驗目的:1.掌握順序表的查詢方法,尤其是二分查詢方法。
2.掌握二叉排序樹的建立及查詢過程,理解二叉排序樹查詢過程及插入和刪除演算法。
實驗內容:1.編寫程式實現有序表二分查詢的遞迴演算法;
2.建立二叉排序樹並對其進行查詢、遍歷等有關操作。
3.選作:判斷一棵二叉樹是否為二叉排序樹。
#include<iostream> #include<iostream> #include<stdio.h> #include<stdlib.h> using namespace std; #define MAXSIZE 100 #define OK 1; #define ENDFLAG '#' typedef struct { int key;//關鍵字域 }elemtype; typedef struct { elemtype *R; int length; }SSTable; int InitList_SSTable(SSTable &L) { L.R=(elemtype *)malloc(MAXSIZE *sizeof(elemtype)); if (!L.R) { cout<<"初始化錯誤"; return 0; } L.length=0; return OK; } void Insert_SSTable(SSTable &L) { int j=1; for(int i=1;i<MAXSIZE;i++) { L.R[i].key=j; L.length++; j++; } //return 1; } int Search_Bin(SSTable L,int n,int l,int r) //在長為n的有序表中查詢關鍵字k,若查詢成功,返回k所在位置,查詢失敗返回0。 { if(l<=r) //low和high分別是有序表的下界和上界 { int mid=(l+r)/2; if(L.R[mid].key==n) return mid; else if(L.R[mid].key<n) return Search_Bin(L,n,mid+1,r); else return Search_Bin(L,n,l,mid-1); } } void Show_End(int result,int testkey) { if(result==0) cout<<"未找到"<<testkey<<endl; else cout<<"找到"<<testkey<<"位置為"<<result<<endl; return; } typedef struct ElemType { char key; }ElemType; typedef struct BSTNode{ ElemType data; //結點資料域 BSTNode *lchild,*rchild; //左右孩子指標 }BSTNode,*BSTree; // 二叉排序樹的遞迴查詢 BSTree SearchBST(BSTree T,char 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); //在右子樹中繼續查詢 } // 二叉排序樹的插入 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插入右子樹 } // 二叉排序樹的建立 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,char 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 //二叉排序樹的刪除,中序遍歷 void InOrderTraverse(BSTree &T) { if(T) { InOrderTraverse(T->lchild); cout<<T->data.key; InOrderTraverse(T->rchild); } } int main() { BSTree T; SSTable ST; InitList_SSTable(ST); Insert_SSTable(ST); int testkey1=5; int result1; result1=Search_Bin(ST,testkey1,1,ST.length); Show_End(result1,testkey1); cout<<"請輸入若干字元,用回車區分,以#結束輸入"<<endl; CreateBST(T); cout<<"當前有序二叉樹中序遍歷結果為"<<endl; InOrderTraverse(T); char key;//待查詢或待刪除內容 cout<<"請輸入待查詢字元"<<endl; cin>>key; BSTree result=SearchBST(T,key); if(result) { cout<<"找到字元"<<key<<endl; } else { cout<<"未找到"<<key<<endl;} cout<<"請輸入待刪除的字元"<<endl; cin>>key; DeleteBST(T,key); cout<<"當前有序二叉樹中序遍歷結果為"<<endl; InOrderTraverse(T); }