编程题实训-查找

本文介绍了基于递归的折半查找算法、二叉排序树中大于等于特定值的节点输出以及链地址法散列表的插入和删除操作,以及带哨兵的顺序查找算法。
摘要由CSDN通过智能技术生成

第1关:基于递归的折半查找

任务描述
请编写一个递归的折半查找算法,查找给定有序数组中的某一元素。

编程要求
输入
多组数据,每组数据有三行。第一行为数组长度n,第二行为n个递增排列的数字,第三行为需要查找的数字k。当n=0时输入结束。

输出
每组数据输出一行,如果可以找到数字,则输出“YES”,否则输出“NO”。

测试说明
平台会对你编写的代码进行测试:

测试输入:
5
1 4 6 7 8
6
6
1 2 5 7 9 100
8
0

预期输出:
YES
NO

#include<iostream>
using namespace std;
int BinSearch_Cur(int a[],int key,int low,int high)
{//基于递归的折半查找
    /************begin***************/
    if(low > high) return 0; 

int mid = (low + high) / 2; 

if(a[mid] == key) {
    return 1; 
} else if(a[mid] < key) {
    return BinSearch_Cur(a, key, mid + 1, high); 
} else {
    return BinSearch_Cur(a, key, low, mid - 1); 
}
    /************end***************/
}
int main()
{
    int n;//数组长度n
    while(cin>>n)
    {
        if(n==0) break;
        int a[100],k;
        for(int i=0;i<n;i++)
            cin>>a[i];			//输入n个递增排列的数字
        cin>>k;				//输入需要查找的数字k
        if(BinSearch_Cur(a,k,0,n-1))
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
} 

第3关:二叉排序树的限定条件下的数据输出

任务描述
已知二叉排序树采用二叉链表存储结构,根结点的指针为T,链结点的结构为(lchild,data,rchild),其中lchild、rchild分别指向该结点左,右孩子的指针,data域存放结点数据。试编写算法,从小到大输出二叉排序树中所有数值大于等于x的结点的数据。要求先找到第一个满足条件的结点后,再依次输出其他满足条件的结点。

编程要求
输入
多组数据,每组三行。第一行为二叉排序树的结点数n。第二行为空格分隔的n个数字,对应二叉排序树中的n个结点。第三行为一个数字x。n=0时输入结束。

输出
每组数据输出一行。从小到大输出大于等于x的结点数据。每个数据用空格分隔。

测试说明
平台会对你编写的代码进行测试:

测试输入:
5
1 5 3 2 4
3
9
1 30 2 15 6 7 3 9 233
30
0

预期输出:
3 4 5
30 233

#include<iostream>
using namespace std;
typedef struct BSTNode
{//二叉排序树的二叉链表存储表示
	int data;
	struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
int sum;设一个全局变量sum,为了判断该数据是否为输出的最后一个数
void InsertBST(BSTree &T,int e)
{//当二叉排序树T中不存在关键字等于e的数据元素时,则插入该元素
    /**************begin************/
	if (T == NULL)
{
T = new BSTNode;
T->data = e;
T->lchild = T->rchild = NULL;
}
else if (e < T->data)
InsertBST(T->lchild, e);
else if (e > T->data)
InsertBST(T->rchild, e);
    /**************end************/
}
BSTree CreateBSTree(int n)
{//构建二叉排序树
    BSTree T=NULL;
    int e;
    for(int i=0;i<n;i++)
    {
        cin>>e;
        InsertBST(T,e);
    }
    return T;
}
void InOrderTraverse(BSTree T,int x)
{//中序遍历二叉树T的递归算法
    if(T==NULL) return;   //空树
    else
    {
        InOrderTraverse(T->lchild,x);//递归遍历左子树
        sum--;         //每次遍历时sum减1
        if(T->data>=x)
        {                               //输出二叉排序树中所有数值大于等于x的结点的数据
            cout<<T->data;              //先输出数据
            if(sum==0) cout<<endl;    //如果是最后一个元素,换行
            else cout<<" ";           //非末位元素,输出空格
        }
        InOrderTraverse(T->rchild,x);//递归遍历右子树
    }
}
int main()
{
	int n,x;        //二叉排序树的结点数n,数字x
	while(cin>>n)
	{
		if(n==0) break;
		BSTree T=NULL;
		T=CreateBSTree(n);
		cin>>x;          //输入数字x
		sum=n;          //结点数n赋给sum
		InOrderTraverse(T,x);
	}
	return 0;
} 

第6关:基于链地址法的散列表的插入

任务描述
请写出在散列表中插入关键字为k的一个记录的算法,设散列函数为H,H(key)=key%13,解决冲突的方法为链地址法。

编程要求
输入
多组数据,每组三行,第一行为待输入的关键字的个数n,第二行为对应的n个关键字,第三行为需要插入的关键字k。当n=0时输入结束。

输出
每组数据输出用链地址法处理冲突的散列表。

测试说明
平台会对你编写的代码进行测试:

测试输入:
5
1 4 2 3 5
6
4
2 5 8 15
18
0

预期输出:
0
1 1
2 2
3 3
4 4
5 5
6 6
7
8
9
10
11
12
0
1
2 2 15
3
4
5 5 18
6
7
8 8
9
10
11
12

#include<iostream>
using namespace std;
typedef struct LNode
{
	int data;
	struct LNode *next;
}LNode,*LinkList;
LinkList H[13];    //链地址法,13个单链表
void Hash(int e)
{//基于链地址法的散列表的插入
    /**************begin************/
	int index = e % 13; 
LinkList newNode = new LNode; 
newNode->data = e;
newNode->next = NULL;

if (H[index]->next == NULL)
{
	H[index]->next = newNode; 
}
else
{
	LinkList p = H[index]->next;
	while (p->next != NULL)
	{
		p = p->next; 
	}
	p->next = newNode; 
}
    /**************end************/
}
void Input(int n)
{//输入数据
	for(int i=0;i<13;i++)     //建立13个带有头结点的单链表
	{
		H[i]=new LNode;
		H[i]->next=NULL;
	}
	while(n--)          //输入n个关键字,构造散列表
	{
		int e;
		cin>>e;
		Hash(e);
	}
}
void Output()
{//输出数据
	for(int i=0;i<13;i++)
	{
		cout<<i;                 //输出散列地址
		LinkList p=H[i]->next;   //p初始化为链表的首元结点
		while(p)
		{
			cout<<" "<<p->data;
			p=p->next;
		}
		cout<<endl;
	}
}
int main()
{
	int n;
	while(cin>>n)
	{
		if(n==0) break;
		Input(n);     //输入数据
		int k;      //需要插入的关键字k
		cin>>k;
		Hash(k);
		Output();  //输出数据
	}
	return 0;
}

第7关:基于链地址法的散列表的删除

任务描述
请写出在散列表中删除关键字为k的一个记录的算法,设散列函数为H,H(key)=key%13,解决冲突的方法为链地址法。

编程要求
输入
多组数据,每组三行,第一行为待输入的关键字的个数n,第二行为对应的n个关键字,第三行为需要删除的关键字k。当n=0时输入结束。

输出
每组数据输出用链地址法处理冲突的散列表。

测试说明
平台会对你编写的代码进行测试:

测试输入:
5
1 4 2 3 5
3
4
1 10 14 27
14
0

预期输出:
0
1 1
2 2
3
4 4
5 5
6
7
8
9
10
11
12
0
1 1 27
2
3
4
5
6
7
8
9
10 10
11
12

#include<iostream>
using namespace std;
typedef struct LNode
{
	int data;
	struct LNode *next;
}LNode,*LinkList;
LinkList H[13];   //链地址法,13个单链表
void Hash(int e)
{//基于链地址法的散列表的插入
	int index=e%13;       //计算散列地址
	LinkList p=H[index];   //工作指针p指向链表的头结点
	while(p->next)         //移至表尾
		p=p->next;
	LinkList q=new LNode;    //生成新结点*q
	q->data=e;               //将新结点*q的数据域置为e
	q->next=NULL;            //将新结点*q插入在尾结点*p之后
	p->next=q;
}
void Input(int n)
{//输入数据
	for(int i=0;i<13;i++)     //建立13个带有头结点的单链表
	{
		H[i]=new LNode;
		H[i]->next=NULL;
	}
	while(n--)          //输入n个关键字,构造散列表
	{
		int e;
		cin>>e;
		Hash(e);
	}
}
void Delete(int e)
{//基于链地址法的散列表的删除
    /**************begin************/
	int index = e % 13;   
    LinkList p = H[index]; 
    while (p->next && p->next->data != e) 
        p = p->next;
    if (p->next) 
    {
        LinkList q = p->next;  
        p->next = q->next;  
        delete q;   
    }
    /**************end************/
}
void Output()
{//输出数据
	for(int i=0;i<13;i++)
	{
		cout<<i;                 //输出散列地址
		LinkList p=H[i]->next;   //p初始化为链表的首元结点
		while(p)
		{
			cout<<" "<<p->data;
			p=p->next;
		}
		cout<<endl;
	}
}
int main()
{
	int n;
	while(cin>>n)
	{
		if(n==0) break;
		Input(n);     //输入数据
		int k;
		cin>>k;
		Delete(k);  //需要删除的关键字k
		Output();  //输出数据
	}
	return 0;
}

第10关:带哨兵的顺序查找

任务描述
本关任务:请编写一个带哨兵的顺序查找算法,查找给定数组中的某一元素。

编程要求
输入
多组数据,每组数据有三行。第一行为数组长度n,第二行为n个递增排列的数字,第三行为需要查找的数字k。当n=0时输入结束。

输出
每组数据输出一行,如果可以找到数字,则输出“YES”,否则输出“NO”。

测试说明
平台会对你编写的代码进行测试:

测试输入:
5
1 4 6 7 8
6
6
1 2 5 7 9 100
8
0

预期输出:
YES
NO

#include <bits/stdc++.h> 
using namespace std;


int sqSearch(int a[],int n,int k)
{
	/************begin***************/
for (int i = 1; i <= n; i++)
    {
        if (a[i] == k)
        {
            return 1; 
        }
    }
    return 0; 


	/************end***************/
}
int main()
{
	int n;
	while (cin>>n)
	{
		if (n==0) break;
		int a[n+1],k; 
		for (int i=1;i<=n;i++) 
			cin>>a[i];
		cin>>k;
		if (sqSearch(a,n,k))
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值