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