1. 程式人生 > >資料結構 折半遞迴查詢,二叉排序樹查詢

資料結構 折半遞迴查詢,二叉排序樹查詢

實驗題目:         查詢演算法實現與分析             

實驗環境:     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);
}