算法练习-常用查找算法复现

第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;
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值