问题 A: DS哈希查找—线性探测再散列
题目描述
定义哈希函数为H(key) = key%11,输入表长(大于、等于11)。输入关键字集合,用线性探测再散列构建哈希表,并查找给定关键字。
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
测试次数t
每组测试数据为:
哈希表长m、关键字个数n
n个关键字
查找次数k
k个待查关键字
输出
对每组测试数据,输出以下信息:
构造的哈希表信息,数组中没有关键字的位置输出NULL
对k个待查关键字,分别输出:0或1(0—不成功,1—成功)、比较次数、查找成功的位置(从1开始)
样例输入
1
12 10
22 19 21 8 9 30 33 4 15 14
4
22
56
30
17
样例输出
22 30 33 14 4 15 NULL NULL 19 8 21 9
1 1 1
0 6
1 6 2
0 1
AC代码
#include<iostream>
using namespace std;
class HashList {
int* list;
int length;
public:
HashList() {
int n;
cin >> length >> n;
list = new int[length];
for (int i = 0; i < length; i++)
list[i] = 0;
for (int i = 0; i < n; i++) {
int key;
cin >> key;
Hash(key);
}
}
void Hash(int key) {
int key1 = key % 11;
for (int i = 0; i < length; i++) {
int temp = (key1 + i) % length;
if (list[temp])
continue;
list[temp] = key;
break;
}
}
void print() {
for (int i = 0; i < length; i++) {
if (i)
cout << " ";
if (list[i])
cout << list[i];
else cout << "NULL";
}
cout << endl;
}
void find(int key) {
int cnt = 0, index = -1;
bool ok = 0;
int key1 = key % 11;
for (int i = 0; i < length; i++)
{
cnt++;
int temp = (key1 + i) % length;
if (!list[temp])
break;
if (list[temp] == key)
{
ok = 1;
index = temp;
break;
}
}
if (ok)
cout << ok << " " << cnt << " " << index + 1 << endl;
else
cout << ok << " " << cnt << endl;
}
~HashList()
{
delete[]list;
}
};
int main() {
int n;
cin >> n;
while (n--)
{
HashList h;
int n1;
h.print();
cin >> n1;
while (n1--)
{
int key;
cin >> key;
h.find(key);
}
}
return 0;
}
问题 B: DS哈希查找—二次探测再散列
题目描述
定义哈希函数为H(key) = key%11。输入表长(大于、等于11),输入关键字集合,用二次探测再散列构建哈希表,并查找给定关键字。
输入
测试次数t
每组测试数据格式如下:
哈希表长m、关键字个数n
n个关键字
查找次数k
k个待查关键字
输出
对每组测试数据,输出以下信息:
构造的哈希表信息,数组中没有关键字的位置输出NULL
对k个待查关键字,分别输出:
0或1(0—不成功,1—成功)、比较次数、查找成功的位置(从1开始)
样例输入
1
12 10
22 19 21 8 9 30 33 4 41 13
4
22
15
30
41
样例输出
22 9 13 NULL 4 41 NULL 30 19 8 21 33
1 1 1
0 3
1 3 8
1 6 6
AC代码
#include<iostream>
#include<cmath>
using namespace std;
class HashList {
int* list;
int length;
int* dis;
void Hash(int key) {
int key1 = key % 11;
for (int i = 0; i < length; i++) {
int temp = (key1 + dis[i] + length) % length;
if (list[temp])
continue;
list[temp] = key;
break;
}
}
public:
HashList() {
int n;
cin >> length >> n;
list = new int[length];
dis = new int[length];
dis[0] = 0;
for (int i = 1; i < length; i++)
{
if (i % 2)
dis[i] = pow((i + 1) / 2, 2);
else
dis[i] = -dis[i - 1];
}
for (int i = 0; i < length; i++)
list[i] = 0;
for (int i = 0; i < n; i++) {
int key;
cin >> key;
Hash(key);
}
}
void print() {
for (int i = 0; i < length; i++) {
if (i)
cout << " ";
if (list[i])
cout << list[i];
else cout << "NULL";
}
cout << endl;
}
void find(int key) {
int cnt = 0, index = -1;
bool ok = 0;
int key1 = key % 11;
for (int i = 0; i < length; i++)
{
cnt++;
int temp = (key1 + dis[i] + length) % length;
if (!list[temp])
break;
if (list[temp] == key)
{
ok = 1;
index = temp;
break;
}
}
if (ok)
cout << ok << " " << cnt << " " << index + 1 << endl;
else
cout << ok << " " << cnt << endl;
}
~HashList()
{
delete[]list;
delete[]dis;
}
};
int main() {
int n;
cin >> n;
while (n--)
{
HashList h;
int n1;
h.print();
cin >> n1;
while (n1--)
{
int key;
cin >> key;
h.find(key);
}
}
return 0;
}
问题 C: DS哈希查找–链地址法
题目描述
给出一个数据序列,建立哈希表,采用求余法作为哈希函数,模数为11,哈希冲突用链地址法和表头插入
如果首次查找失败,就把数据插入到相应的位置中
实现哈希查找功能
输入
第一行输入n,表示有n个数据
第二行输入n个数据,都是自然数且互不相同,数据之间用空格隔开
第三行输入t,表示要查找t个数据
从第四行起,每行输入一个要查找的数据,都是正整数
输出
每行输出对应数据的查找结果
样例输入
6
11 23 39 48 75 62
6
39
52
52
63
63
52
样例输出
6 1
error
8 1
error
8 1
8 2
提示
注意,当两次输入要相同的查找数据,如果第一次查找不成功就会执行插入,那么第二次查找必然成功,且查找次数为1次(因为做表头插入)
例如示例数据中输入两次52,第一次查找失败就把52插入到位置8,第二次查找就成功了,所以第一次输出error,第二次就输出8 1
为什么第三次输入52会输出8 2
AC代码
#include<iostream>
#include<list>
using namespace std;
class HashList {
list<int>* l;
public:
HashList() {
int n;
cin >> n;
l = new list<int>[11];
for (int i = 0; i < n; i++) {
int key;
cin >> key;
hash(key);
}
}
void hash(int key) {
int key1 = key % 11;
l[key1].push_front(key);
}
void find(int key) {
int key1 = key % 11;
int cnt = 0;
bool ok = 0;
for (auto& it : l[key1])
{
cnt++;
if (it != key)
continue;
ok = 1;
break;
}
if (ok)
printf("%d %d\n", key1, cnt);
else {
puts("error");
l[key1].push_front(key);
}
}
~HashList()
{
delete[]l;
}
};
int main() {
HashList h;
int n1;
cin >> n1;
while (n1--)
{
int key;
cin >> key;
h.find(key);
}
return 0;
}
问题 D: DS哈希查找与增补
题目描述
给出一个数据序列,建立哈希表,采用求余法作为哈希函数,模数为11,哈希冲突用链地址法和表尾插入
如果首次查找失败,就把数据插入到相应的位置中
实现哈希查找与增补功能
输入
第一行输入n,表示有n个数据
第二行输入n个数据,都是自然数且互不相同,数据之间用空格隔开
第三行输入t,表示要查找t个数据
从第四行起,每行输入一个要查找的数据,都是正整数
输出
每行输出对应数据的查找结果,每个结果表示为数据所在位置[0,11)和查找次数,中间用空格分开
样例输入
6
11 23 39 48 75 62
6
39
52
52
63
63
52
样例输出
6 1
error
8 1
error
8 2
8 1
AC代码
#include<iostream>
#include<list>
using namespace std;
class HashList {
list<int>* l;
public:
HashList() {
int n;
cin >> n;
l = new list<int>[11];
for (int i = 0; i < n; i++) {
int key;
cin >> key;
hash(key);
}
}
void hash(int key) {
int key1 = key % 11;
//l[key1].push_front(key);
l[key1].push_back(key);
}
void find(int key) {
int key1 = key % 11;
int cnt = 0;
bool ok = 0;
for (auto& it : l[key1])
{
cnt++;
if (it != key)
continue;
ok = 1;
break;
}
if (ok)
printf("%d %d\n", key1, cnt);
else {
puts("error");
//l[key1].push_front(key);
l[key1].push_back(key);
}
}
~HashList()
{
delete[]l;
}
};
int main() {
HashList h;
int n1;
cin >> n1;
while (n1--)
{
int key;
cin >> key;
h.find(key);
}
return 0;
}
问题 E: DS内排—直插排序
题目描述
给定一组数据,使用直插排序完成数据的升序排序。
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
数据个数n,n个数据
输出
直插排序的每一趟排序结果
样例输入
7 34 23 677 2 1 453 3
样例输出
23 34 677 2 1 453 3
23 34 677 2 1 453 3
2 23 34 677 1 453 3
1 2 23 34 677 453 3
1 2 23 34 453 677 3
1 2 3 23 34 453 677
AC代码
#include<iostream>
using namespace std;
//西天还有些儿残霞,教我如何不想她。
void InsertSort(int* p, int num) {
int j;
for (int i = 1; i < num; i++)
{
int temp = p[i];
for (j = i - 1; j >= 0; j--)
if (temp < p[j])
p[j + 1] = p[j];
else break;
p[j + 1] = temp;
for (int i = 0; i < num; i++)
{
if (i)
cout << " ";
cout << p[i];
}
cout << endl;
}
}
int main() {
int* p, num;
cin >> num;
p = new int[num];
for (int i = 0; i < num; i++)
cin >> p[i];
InsertSort(p, num);
delete[]p;
return 0;
}
问题 F: DS单链表–类实现
题目描述
用C++语言和类实现单链表,含头结点
属性包括:data数据域、next指针域
操作包括:插入、删除、查找
注意:单链表不是数组,所以位置从1开始对应首结点,头结点不放数据
类定义参考
输入
n
第1行先输入n表示有n个数据,接着输入n个数据
第2行输入要插入的位置和新数据
第3行输入要插入的位置和新数据
第4行输入要删除的位置
第5行输入要删除的位置
第6行输入要查找的位置
第7行输入要查找的位置
输出
n
数据之间用空格隔开,
第1行输出创建后的单链表的数据
每成功执行一次操作(插入或删除),输出执行后的单链表数据
每成功执行一次查找,输出查找到的数据
如果执行操作失败(包括插入、删除、查找等失败),输出字符串error,不必输出单链表
样例输入
6 11 22 33 44 55 66
3 777
1 888
1
11
0
5
样例输出
11 22 33 44 55 66
11 22 777 33 44 55 66
888 11 22 777 33 44 55 66
11 22 777 33 44 55 66
error
error
44
AC代码
#include<iostream>
using namespace std;
struct Node
{
int data;
Node* next;
Node(int data = 0, Node* next = NULL) :data(data), next(next) {}
};
class LinkLisk {
Node* head;
public:
LinkLisk() {
int n;
cin >> n;
head = new Node(n);
Node* p = head;
while (n--)
{
int data;
cin >> data;
p->next = new Node(data);
p = p->next;
}
}
void insert(int index, int data)
{
if (index < 1 || index > head->data + 1)
{
puts("error");
return;
}
Node* p = head;
for (int i = 1; i < index; i++)
p = p->next;
Node* s = new Node(data, p->next);
p->next = s;
head->data++;
print();
}
void erase(int index) {
if (index<1 || index>head->data)
{
puts("error");
return;
}
Node* p = head;
for (int i = 1; i < index; i++)
p = p->next;
Node* s = p->next;
p->next = s->next;
delete s;
head->data--;
print();
}
void find(int index) {
if (index<1 || index>head->data)
{
puts("error");
return;
}
Node* p = head;
for (int i = 0; i < index; i++)
p = p->next;
cout << p->data << endl;
}
void print() {
Node* p = head->next;
for (int i = 0; i < head->data; i++)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
};
int main() {
LinkLisk l;
l.print();
for (int i = 0; i < 2; i++) {
int index, data;
cin >> index >> data;
l.insert(index, data);
}
for (int i = 0; i < 2; i++) {
int index;
cin >> index;
l.erase(index);
}
for (int i = 0; i < 2; i++) {
int index;
cin >> index;
l.find(index);
}
return 0;
}