第1关:顺序查找(算法7.1和7.2)
//算法7.1 顺序查找
#include<iostream>
#include<stdio.h>
#include <fstream>
using namespace std;
#define MAXSIZE 10000
#define OK 1;
typedef struct{
int key;//关键字域
}ElemType;
typedef struct{
ElemType *R;
int length;
}SSTable;
int InitList_SSTable(SSTable &L)
{
L.R=new ElemType[MAXSIZE];
if (!L.R)
{
cout<<"初始化错误";
return 0;
}
L.length=0;
return OK;
}
int Insert_SSTable(SSTable &L) //将所有关键字输入顺序表备查
{
/***********************Begin**********************/
int x;
while(cin >> x)
{
L.R[ ++ L.length].key = x;
}
/*********************** End **********************/
}
int Search_Seq(SSTable ST, int key){
//在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为
//该元素在表中的位置,否则为0
/***********************Begin**********************/
ST.R[0].key = key;
int i;
for(i = ST.length;ST.R[i].key != key;i -- );
return i;
/*********************** End **********************/
}// Search_Seq
void Show_End(int result,int testkey)
{
if(result==0)
cout<<"未找到"<<testkey<<endl;
else
cout<<"找到"<<testkey<<"位置为"<<result<<endl;
return;
}
int main()
{
int testkey1;
scanf("%d",&testkey1);
SSTable ST;
InitList_SSTable(ST);
Insert_SSTable(ST);
int result;
result=Search_Seq(ST, testkey1);
Show_End(result,testkey1);
}
第2关:折半查找(算法7.3)
//算法7.3 折半查找
#include<iostream>
#include<stdio.h>
#include<fstream>
using namespace std;
#define MAXSIZE 2000
#define OK 1;
typedef struct{
int key;//关键字域
}ElemType;
typedef struct{
ElemType *R;
int length;
}SSTable;
int InitList_SSTable(SSTable &L)
{
L.R=new ElemType[MAXSIZE];
if (!L.R)
{
cout<<"初始化错误";
return 0;
}
L.length=0;
return OK;
}
int Insert_SSTable(SSTable &L) //将所有关键字输入顺序表备查
{
/***********************Begin**********************/
int x;
while(cin >> x)
{
L.R[++ L.length].key = x;
}
/*********************** End **********************/
}
int Search_Bin(SSTable ST,int key) {
// 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为
// 该元素在表中的位置,否则为0
/***********************Begin**********************/
int low = 1,high = ST.length;
while(low <= high)
{
int mid = low + high >> 1;
if(key == ST.R[mid].key) return mid;
else if(key < ST.R[mid].key) high = mid - 1;
else low = mid + 1;
}
return 0;
/*********************** End **********************/
}// Search_Bin
void Show_End(int result,int testkey)
{
if(result==0)
cout<<"未找到"<<testkey<<endl;
else
cout<<"找到"<<testkey<<"位置为"<<result<<endl;
return;
}
int main()
{
int testkey1;
scanf("%d",&testkey1);
SSTable ST;
InitList_SSTable(ST);
Insert_SSTable(ST);
int result;
result=Search_Bin(ST, testkey1);
Show_End(result,testkey1);
}
第3关:二叉排序树和查找(算法7.4-7.7)
//算法7.4 二叉排序树的递归查找
//算法7.5 二叉排序树的插入
//算法7.6 二叉排序树的创建
//算法 7.7 二叉排序树的删除
#include<iostream>
using namespace std;
#define ENDFLAG '#'
typedef struct ElemType{
char key;
}ElemType;
typedef struct BSTNode{
ElemType data; //结点数据域
BSTNode *lchild,*rchild; //左右孩子指针
}BSTNode,*BSTree;
//算法7.4 二叉排序树的递归查找
BSTree SearchBST(BSTree T,char key) {
//在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素
//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
/***********************Begin**********************/
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);
/*********************** End **********************/
} // SearchBST
//算法7.5 二叉排序树的插入
void InsertBST(BSTree &T,ElemType e ) {
//当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
/***********************Begin**********************/
if(!T)
{
BSTNode *S = new BSTNode;
S -> data = e;
S -> lchild = S -> rchild = NULL;
T = S;
}
else if(e.key < T -> data.key) InsertBST(T -> lchild,e);
else if(e.key > T -> data.key) InsertBST(T -> rchild,e);
/*********************** End **********************/
}// InsertBST
//算法7.6 二叉排序树的创建
void CreateBST(BSTree &T ) {
//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
/***********************Begin**********************/
T = NULL;
ElemType e;
while(cin >> e.key && e.key != '#')
InsertBST(T,e);
/*********************** End **********************/
}//CreatBST
void DeleteBST(BSTree &T,char key) {
//从二叉排序树T中删除关键字等于key的结点
/***********************Begin**********************/
BSTree p = T,f = NULL;
while(p)
{
if(p -> data.key == key) break;
f = p;
if(p -> data.key > key) p = p -> lchild;
else p = p -> rchild;
}
if(!p) return ;
BSTree q = p;
if(p -> lchild && p -> rchild)
{
BSTree s = p -> lchild;
while(s -> rchild)
{
q = s;
s = s -> rchild;
}
p -> data = s -> data;
if(q != p) q -> rchild = s -> lchild;
else q -> lchild = s -> lchild;
delete s;
return ;
}
else if(!p -> rchild) p = p -> lchild;
else if(!p -> lchild) p = p -> rchild;
if(!f) T = p;
else if(q == f -> lchild) f -> lchild = p;
else f -> rchild = p;
delete q;
/*********************** End **********************/
}//DeleteBST
//算法 7.7 二叉排序树的删除
//中序遍历
void InOrderTraverse(BSTree &T)
{
/***********************Begin**********************/
if(T)
{
InOrderTraverse(T -> lchild);
cout << T -> data.key;
InOrderTraverse(T -> rchild);
}
/*********************** End **********************/
}
int main()
{
BSTree T;
CreateBST(T);
cout<<"当前有序二叉树中序遍历结果为";
InOrderTraverse(T);
cout<<endl;
char key;//待查找或待删除内容
cin>>key;
BSTree result=SearchBST(T,key);
if(result)
{cout<<"找到字符"<<key<<endl;}
else
{cout<<"未找到"<<key<<endl;}
cin>>key;
DeleteBST(T,key);
cout<<"当前有序二叉树中序遍历结果为";
InOrderTraverse(T);
}
第4关:B- 树的查找和插入(算法7.8和7.9)
//算法7.8 B-树的查找
//算法7.9 B-树的插入
#include<iostream>
using namespace std;
#define FALSE 0
#define TRUE 1
#define OK 1
#define m 3 //B-树的阶,暂设为3
typedef struct BTNode{
int keynum; //结点中关键字的个数,即结点的大小
BTNode *parent; //指向双亲结点
int key[m+1]; //关键字矢量,0号单元未用
BTNode *ptr[m+1]; //子树指针矢量
}BTNode,*BTree;
//- - - - - B-树的查找结果类型定义- - - - -
struct Result{
BTNode *pt; //指向找到的结点
int i; //1..m,在结点中的关键字序号
int tag; //1:查找成功,0:查找失败
};
int Search(BTree T,int key)
{
BTree p=T;
int endnum;
if(p) //树不为空时
{
endnum=p->keynum; //获得首节点包含的记录个数
}
else
{
return 0; //返回没找到
}
int i=0;
if(endnum==0)
{
return i; //树存在,但仅有一个为空根节点
}
else if(key>=p->key[endnum])//节点不为空,但当前值比最大的key还大
{
i=endnum;
return i;
}
else if(key<=p->key[1]) //节点不为空,但当前值比最小的key还小
{
return i;}
else
{
for(i=1;i<endnum;i++) //有合适的位置,即处于当前结点的最大和最小值之间,或找到了
{
if(p->key[i]<=key && key<p->key[i+1])
return i;
}
}
}
void Insert(BTree &q,int i,int x,BTree &ap)
{//将x插入q结点的i+1位置中
int j;
for(j=m-1;j>i;j--)
{
//将插入位置之后的key全部后移一位
q->key[j+1]=q->key[j];
}
for(j=m;j>i;j--)
{
//相应地也移动其后ptr的位置
q->ptr[j]=q->ptr[j-1];
}
q->key[i+1]=x;//插入x到该位置
q->ptr[i+1]=ap;
q->keynum++;
}
void split(BTree &q,int s,BTree &ap)
{ //将q->key[s+1,..,m], q->ptr[s+1,..,m]移入新结点*ap作为右结点
//原结点作为新的左侧结点
//中间值被保存在ap[0]->key中,等待找到跳转回InsertBTree()寻找到到合适的插入位置插入
int i;
ap=new BTNode;
for(i=s+1;i<=m;i++)
{ //将q->key[s+1,..,m]保存到ap->key[0,..,m-s+1]中
//将q->ptr[s+1,..,m]保存到ap->ptr[0,..,m-s+1]中
ap->key[i-s-1]=q->key[i];
ap->ptr[i-s-1]=q->ptr[i];
}
if(ap->ptr[0])
{
//当ap有子树的时候
for(i=0;i<=1;i++)
{
//将ap的子树的父亲改为ap自己
ap->ptr[i]->parent=ap;
}
}
ap->keynum=(m-s)-1;
ap->parent=q->parent;//将ap的父亲改为q的父亲
q->keynum=q->keynum-(m-s);//修改q的记录个数
}
void NewRoot(BTree &T,BTree q,int x,BTree &ap)//生成含信息(T, x, ap)的新的根结点*T,原T和ap为子树指针
{
BTree newT=new BTNode;//新建一个结点作为新的根
newT->key[1]=x;//写入新根的key[1]
newT->ptr[0]=T;//将原来的树根作为新根的左子树
newT->ptr[1]=ap;//ap作为新根的右子树
newT->keynum=1;
newT->parent=NULL;//新根的父亲为空
ap->parent=newT;//ap的父亲为新根
T->parent=newT;//T的父亲为新根
T=newT;//树改成新根引导的
}
//算法7.9 B-树的插入
int InsertBTree(BTree &T,int K,BTree q,int i){
/***********************Begin**********************/
int x = K;
BTree ap = NULL;
bool finished = false;
while(q && !finished)
{
Insert(q,i,x,ap);
if(q -> keynum < m) finished = true;
else
{
int s = m / 2;
split(q,s,ap);
x = q -> key[s];
q = q -> parent;
if(q) i = Search(q,x);
}
}
if(!finished) NewRoot(T,q,x,ap);
return OK;
/*********************** End **********************/
} //InsertBTree
//算法7.8 B-树的查找
Result SearchBTree(BTree &T, int key){
/***********************Begin**********************/
BTree p = T,q = NULL;
bool found = false;
int i = 0;
while(p && !found)
{
i = Search(p,key);
if(i > 0 && p -> key[i] == key) found = true;
else
{
q = p;
p = p -> ptr[i];
}
}
if(found) return {p,i,1};
else return {q,i,0};
/*********************** End **********************/
}//SearchBTree
void InitialBTree(BTree &T)
{
//初始化一个空的根
T->keynum=0;
T->parent=NULL;
for(int i=0;i<m+1;i++)
{
T->ptr[i]=NULL;
}
}
int main()
{
BTree T=new BTNode;
InitialBTree(T);
//先用SearchBTree()找到要插入的位置,得到一个Result结构体
//再用InsertBTree()插入数据
Result result;
int a[11]={45,24,53,90,3,12,50,61,70,100};
for(int i=0;i<10;i++)
{
result=SearchBTree(T,a[i]);
if(result.tag==0)
{
InsertBTree(T,a[i],result.pt,result.i);
}
}
cout<<"OK";
}
第5关:散列表查找(算法7.10)
#include<iostream>
#include<stdio.h>
using namespace std;
//算法7.10 哈希表的查找
//- - - - -开放地址法哈希表的存储表示- - - - -
#define m 16 //哈希表的表长
#define NULLKEY 0 //单元为空的标记
struct HashTable{
int key; //关键字项
// InfoType otherinfo; //其他数据项
};
// 算法7.10为哈希表查找的算法,采用线性探测法处理冲突。
// 【算法实现】
int H(int key)
{
int result;
result=key%13;
return result;
}
int SearchHash(HashTable HT[],int key){
//在哈希表HT中查找关键字为key的元素,若查找成功,返回哈希表的单元标号,否则返回-1
/***********************Begin**********************/
int H0 = H(key);
if(HT[H0].key == NULLKEY) return -1;
else if(HT[H0].key == key) return H0;
else
{
for(int i = 1;i < m;i ++ )
{
int Hi = (H0 + i) % m;
if(HT[Hi].key == NULLKEY) return -1;
else if(HT[Hi].key == key) return Hi;
}
return -1;
}
/*********************** End **********************/
}//SearchHash
int main()
{
int result,i=0;
int a[m];
char end=' ';
int lookfor; //lookfor为待查找的元素
scanf("%d",&lookfor);
for(;i<m;i++)
{
scanf("%d",&a[i]);
}
HashTable HT[m];
for(i=0;i<16;i++)
{
HT[i].key=a[i];
}
result=SearchHash(HT,lookfor);
if(result!=-1)
{
cout<<"在第"<<result<<"位置找到"<<endl;
}
else
{
cout<<"未找到"<<endl;
}
}