目录
-
-
- 题目传送门
- 214、基于链式存储结构的图书信息表的创建和输出
- 215、基于链式存储结构的图书信息表的排序
- 216、基于链式存储结构的图书信息表的修改
- 217、基于链式存储结构的图书信息表的逆序存储
- 218、基于链式存储结构的图书信息表的最贵图书的查找
- 219、基于链式存储结构的图书信息表的最爱图书的查找
- 220、基于链式存储结构的图书信息表的最佳位置图书的查找
- 221、基于链式存储结构的图书信息表的新图书的入库
- 222、基于链式存储结构的图书信息表的旧图书的出库
- 223、基于链存储结构的图书信息表的图书去重
- 224、基于链表的两个一元多项式的基本运算
- 225、基于链表的两个递增有序序列的合并
- 226、基于链表的两个非递减有序序列的合并
- 227、基于链表的两个集合的交集
- 228、基于链表的两个集合的差集
- 229、链表的分解
- 230、查找链表中的最大值
- 231、链表的逆转
- 232、删除链表中满足区间值的结点
- 233、双向循环链表中结点的交换
- 235、查找链表中倒数第k个结点
- 236、删除链表中绝对值相等的结点
- 237、求解两个升序序列的中位数
- 238、查找两个单词链表共同后缀的起始结点
- 239、猴子选大王问题
-
题目传送门
214、基于链式存储结构的图书信息表的创建和输出
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。
输入
输入n+1行,其中前n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。最后第n+1行是输入结束标志:0 0 0(空格分隔的三个0)。其中书号和书名为字符串类型,价格为浮点数类型。
输出
总计n+1行,第1行是所创建的图书表中的图书个数,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。
输入样例 1
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
输出样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
AC 代码
前插法:
#include <iostream>
#include <algorithm>
using namespace std;
struct Book // 创建书类数据类型
{
string ibsn;
string name;
double price;
};
typedef struct LNode // 创建结点类型
{
Book data;
struct LNode *next;
}LNode, *LinkList;
bool InitList(LinkList &L) // 注意这里的参数等价于LNode * &L,返回值为bool值表示状态
{
L = new LNode;
L -> next = NULL;
return true; // 表示初始化成功
}
int main()
{
// 1、创建一个链表(先创建一个头结点),用LinkList用来强调这是一个链表
LinkList L;
// 2、初始化链表
InitList(L);
// 3、前插法创建单链表(注意创建完后是倒序)
int cnt = 0;
while (1)
{
LNode *tmp1;
tmp1 = new LNode;
cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
if (tmp1 -> data.price == 0) break;
tmp1 -> next = L -> next;
L -> next = tmp1;
cnt ++;
}
cout << cnt << endl;
// 4、循环倒序输出
while (cnt --)
{
LNode *tmp2;
tmp2 = new LNode;
tmp2 = L -> next;
for (int i = 0; i < cnt; i ++) // 注意是循环cnt次,目的是使得指针最后指向尾结点
tmp2 = tmp2 -> next;
cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
printf("%.2lf\n", tmp2 -> data.price);
}
return 0;
}
尾插法:
AC 代码
#include <iostream>
#include <algorithm>
using namespace std;
struct Book // 创建书类数据类型
{
string ibsn;
string name;
double price;
};
typedef struct LNode // 创建结点类型
{
Book data;
struct LNode *next;
}LNode, *LinkList;
bool InitList(LinkList &L) // 注意这里的参数等价于LNode * &L,返回值为bool值表示状态
{
L = new LNode;
L -> next = NULL;
return true; // 表示初始化成功
}
int main()
{
// 1、创建一个链表(先创建一个头结点),用LinkList用来强调这是一个链表
LinkList L;
// 2、初始化链表
InitList(L);
// 3、尾插法创建单链表(注意创建完后是正序)
int cnt = 0;
LNode *r; // 创建尾指针
r = new LNode;
r = L;
while (1)
{
LNode *tmp1; // 创建临时结点
tmp1 = new LNode;
cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
if (tmp1 -> data.price == 0) break;
tmp1 -> next = NULL;
r -> next = tmp1;
r = tmp1;
cnt ++;
}
cout << cnt << endl;
LNode *tmp2; // 创建输出使用的临时指针
tmp2 = new LNode;
tmp2 = L -> next;
// 4、正序输出
while(tmp2 != r -> next) // 注意,是遍历到r -> next,即尾结点后面那个结点,因为tmp2 = tmp2 -> next 在cout语句后面
{
cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
printf("%.2lf\n", tmp2 -> data.price);
tmp2 = tmp2 -> next;
}
return 0;
}
215、基于链式存储结构的图书信息表的排序
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。
输入
输入n+1行,其中前n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。最后第n+1行是输入结束标志:0 0 0(空格分隔的三个0)。其中书号和书名为字符串类型,价格为浮点数类型。
输出
总计n+1行,第1行是所创建的图书表中的图书个数,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。
输入样例 1
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
输出样例 1
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787302164340 Operating-System 50.00
9787822234110 The-C-Programming-Language 38.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257646 Data-Structure 35.00
9787302219972 Software-Engineer 32.00
AC 代码
#include <iostream>
using namespace std;
struct Book // 创建书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode // 创建结点
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数,通过头结点指向空
bool InitList(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法创建链表函数
void createList_tail(LinkList &L, int &cnt)
{
LNode *r; // 创建尾指针,使得尾指针一开始指向头结点
r = new LNode;
r = L;
while (1)
{
LNode *tmp1; // 创建一个临时结点
tmp1 = new LNode;
cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
if (tmp1 -> data.price == 0) break;
tmp1 -> next = NULL;
r -> next = tmp1;
r = tmp1;
cnt ++;
}
}
// 输出函数
void show(LinkList L)
{
LNode *tmp2;
tmp2 = new LNode;
tmp2 = L -> next;
while (tmp2)
{
cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
printf("%.2lf\n", tmp2 -> data.price);
tmp2 = tmp2 -> next;
}
}
// 降序的冒泡排序
void listSort(LinkList &L, int cnt)
{
LNode *tmp3;
for (int i = 0; i < cnt; i ++)
{
int j = 0;
tmp3 = L -> next; // 由于第一个结点是最大的,因此,每次冒泡排序的开始都应该是从头开始
while (tmp3 && j < cnt -i - 1)
{
if (tmp3 -> data.price < tmp3 -> next -> data.price)
{
Book t = tmp3 -> data;
tmp3 -> data = tmp3 -> next -> data;
tmp3 -> next -> data = t;
}
j ++;
tmp3 = tmp3 -> next;
}
}
}
int main()
{
// 1、创建链表(通过创建一个头结点)并初始化
LinkList L;
InitList(L);
// 2、利用尾插法进行创建一个链表(注意是正序输出)
int cnt = 0;
createList_tail(L, cnt);
// 3、进行排序,利用双指针的冒泡排序
listSort(L, cnt);
// // 4、进行正序输出
show(L);
return 0;
}
216、基于链式存储结构的图书信息表的修改
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。
输入
输入n+1行,前n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。最后第n+1行是输入结束标志:0 0 0(空格分隔的三个0)。其中书号和书名为字符串类型,价格为浮点数类型。
输出
总计n+1行,第1行是修改前所有图书的平均价格,后n行是价格修改后n本图书的信息,每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。
输入样例 1
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
0 0 0
输出样例 1
43.88
9787302257646 Data-Structure 42.00
9787302164340 Operating-System 55.00
9787302219972 Software-Engineer 38.40
9787302203513 Database-Principles 43.20
9787810827430 Discrete-Mathematics 43.20
9787302257800 Data-Structure 68.20
9787811234923 Compiler-Principles 68.20
9787822234110 The-C-Programming-Language 45.60
AC 代码
#include <iostream>
using namespace std;
struct Book // 建立书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool InitList(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法创建函数
void createList_tail(LinkList &L, int &len, double &sum) // len是指长度
{
LNode *tail;
tail = new LNode;
tail = L; // 创建尾指针,一开始指向头结点
while (1)
{
LNode *tmp; // 创建一个临时结点
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
if (tmp -> data.price == 0) break; // 情况特判
sum += tmp -> data.price; // 算出总价格
tmp -> next = NULL;
tail -> next = tmp;
tail = tmp;
len ++;
}
}
// 改变价格函数
void changePrice(LinkList &L, double ave)
{
LNode *p;
p = new LNode;
p = L;
while (p)
{
if (p -> data.price < ave) p -> data.price *= 1.2;
else p -> data.price *= 1.1;
p = p -> next;
}
}
// 输出函数
void show(LinkList L)
{
LNode *tmp2;
tmp2 = new LNode;
tmp2 = L -> next;
while (tmp2)
{
cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
printf("%.2lf\n", tmp2 -> data.price);
tmp2 = tmp2 -> next;
}
}
int main()
{
// 1、通过创建一个头结点创建链表
LinkList L;
// 2、通过将头结点指向NULL进行初始化
InitList(L);
// 3、利用尾插法建立链表
int len = 0;
double sum = 0;
createList_tail(L, len, sum);
// 4、按照题意改变价格
double ave = sum / len;
printf("%.2lf\n", ave);
changePrice(L, ave);
// 5、输出
show(L);
return 0;
}
217、基于链式存储结构的图书信息表的逆序存储
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后将读入的图书逆序存储,逐行输出逆序存储后每本图书的信息。
输入
输入n+1行,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。
输出
总计n行,第i行是原有图书表中第n-i+1行的图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔。其中价格输出保留两位小数。
输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输出样例 1
9787822234110 The-C-Programming-Language 38.00
9787811234923 Compiler-Principles 62.00
9787302257800 Data-Structure 62.00
9787810827430 Discrete-Mathematics 36.00
9787302203513 Database-Principles 36.00
9787302219972 Software-Engineer 32.00
9787302164340 Operating-System 50.00
9787302257646 Data-Structure 35.00
AC 代码
#include <iostream>
using namespace std;
struct Book // 建立书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool InitList(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法创建函数
void createList_tail(LinkList &L, int n) // len是指长度
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp; // 创建一个临时结点
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tmp -> next = NULL;
tail -> next = tmp;
tail = tmp;
}
}
// 输出函数
void show(LinkList L, int n)
{
while (n --)
{
LNode *tmp2;
tmp2 = new LNode;
tmp2 = L -> next;
for (int i = 0; i < n; i ++)
tmp2 = tmp2 -> next;
cout << tmp2 -> data.ibsn << " " << tmp2 -> data.name << " ";
printf("%.2lf\n", tmp2 -> data.price);
}
}
int main()
{
// 1、通过创建一个头结点创建链表
LinkList L;
// 2、通过将头结点指向NULL进行初始化
InitList(L);
// 3、利用尾插法建立链表
int n;
cin >> n;
createList_tail(L, n);
// 4、按照题意改变价格
// double ave = sum / len;
// printf("%.2lf\n", ave);
// changePrice(L, ave);
// 5、逆序输出
show(L, n);
return 0;
}
218、基于链式存储结构的图书信息表的最贵图书的查找
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后查找价格最高的图书,输出相应图书的信息。
输入
总计输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。
输出
总计输出m+1行,其中,第一行是最贵图书数目(价格最高的图书可能有多本),后m行是最贵图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,其中价格输出保留两位小数。
输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输出样例 1
2
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
AC 代码
#include <iostream>
using namespace std;
struct Book // 建立书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool InitList(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法创建函数
void createList_tail(LinkList &L, int n)
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp; // 创建一个临时结点
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tmp -> next = NULL;
tail -> next = tmp;
tail = tmp;
}
}
void listSort(LinkList &L, int n) // 冒泡排序
{
LNode * tmp;
for (int i = 0; i < n; i ++)
{
tmp = L -> next;
int j = 0;
while (tmp && j < n - i - 1)
{
if (tmp -> data.price < tmp -> next -> data.price)
{
Book t = tmp -> data;
tmp -> data = tmp -> next -> data;
tmp -> next -> data = t;
}
j ++;
tmp = tmp -> next;
}
}
}
// 输出函数
void show(LinkList L, int n)
{
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
int count = 0; // 存储最贵图书数量
n -= 1; // 由于tmp是从首元结点开始遍历,因此需要先减去 1
while (n --)
{
if (tmp -> data.price == tmp -> next -> data.price) // 注意这里不要用浮点数的相等判断,因为输入的值时固定的
count ++;
tmp = tmp -> next;
}
cout << count << endl;
while (count --)
{
cout << L -> next -> data.ibsn << " " << L -> next -> data.name << " ";
printf("%.2lf\n", L -> next -> data.price);
L = L -> next;
}
}
int main()
{
// 1、通过创建一个头结点创建链表
LinkList L;
// 2、通过将头结点指向NULL进行初始化
InitList(L);
// 3、利用尾插法建立链表
int n;
cin >> n;
createList_tail(L, n);
// 4、进行降序排序
listSort(L, n);
// 5、输出最贵图书信息
show(L, n);
return 0;
}
219、基于链式存储结构的图书信息表的最爱图书的查找
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的最爱图书的名字,查找最爱的图书,输出相应图书的信息。
输入
总计n+m+2行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。然后输入m+1行,其中,第一行是一个整数m,代表查找m次,后m行是每次待查找的最爱图书名字。
输出
若查找成功: 总计输出m*(k+1)行,对于每一次查找,第一行是最爱图书数目(同一书名的图书可能有多本),后k行是最爱图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,其中价格输出保留两位小数。 若查找失败: 只输出以下提示:抱歉,没有你的最爱!
输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
2
Java-Programming-Language
Data-Structure
输出样例 1
Sorry,there is no your favourite!
2
9787302257646 Data-Structure 35.00
9787302257800 Data-Structure 62.00
AC 代码
#include <iostream>
using namespace std;
struct Book // 建立书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool InitList(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法创建函数
void createList_tail(LinkList &L, int n)
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp; // 创建一个临时结点
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tmp -> next = NULL;
tail -> next = tmp;
tail = tmp;
}
}
// 输出最爱图书函数
void findFavorite(LinkList L, string name, int n)
{
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
int count = 0; // 存储最爱图书数量
n -= 1; // 由于tmp是从首元结点开始遍历,因此需要先减去 1
while (n --)
{
if (tmp -> data.name == name)
count ++;
tmp = tmp -> next;
}
if (!count) // 表示没有找到最爱图书
{
cout << "Sorry,there is no your favourite!" << endl;
return ; // 函数返回值类型类void
}
else
{
cout << count << endl;
LNode *tmp1;
tmp1 = new LNode;
tmp1 = L -> next;
while (tmp1) // 遍历
{
if (name == tmp1 -> data.name)
{
cout << tmp1 -> data.ibsn << " " << tmp1 -> data.name << " ";
printf("%.2lf\n", tmp1 -> data.price);
}
tmp1 = tmp1 -> next;
}
}
}
int main()
{
// 1、通过创建一个头结点创建链表
LinkList L;
// 2、通过将头结点指向NULL进行初始化
InitList(L);
// 3、利用尾插法建立链表
int n;
cin >> n;
createList_tail(L, n);
// 4、输入最爱图书
int t;
cin >> t;
while (t --)
{
string name;
cin >> name;
findFavorite(L, name, n);
}
return 0;
}
220、基于链式存储结构的图书信息表的最佳位置图书的查找
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的最佳位置的序号,查找该位置上的图书,输出相应图书的信息。
输入
总计n+m+2行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。然后输入m+1行,其中,第一行是一个整数m,代表查找m次,后m行每行内容为一个整数,代表待查找的图书的位置序号。
输出
输出m行 若查找成功: 输出内容为第i次查询的指定位置上的一本图书的信息(书号、书名、价格),书号、书名、价格用空格分隔,其中价格输出保留两位小数。 若查找失败: 只输出以下提示:抱歉,最佳位置上的图书不存在!
输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
2
2
0
输出样例 1
9787302164340 Operating-System 50.00
Sorry,the book on the best position doesn't exist!
AC 代码
#include <iostream>
using namespace std;
struct Book // 建立书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool InitList(LinkList &L)
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法创建函数
void createList_tail(LinkList &L, int n)
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp; // 创建一个临时结点
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tmp -> next = NULL;
tail -> next = tmp;
tail = tmp;
}
}
// 查找函数
void find(LinkList L, int site, int n)
{
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
if (site < 1 || site > n) // 不合法位置
{
cout << "Sorry,the book on the best position doesn't exist!" << endl;
return ;
}
site -= 1;
while (site --)
tmp = tmp -> next;
cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
printf("%.2lf\n", tmp -> data.price);
}
int main()
{
// 1、通过创建一个头结点创建链表
LinkList L;
// 2、通过将头结点指向NULL进行初始化
InitList(L);
// 3、利用尾插法建立链表
int n;
cin >> n;
createList_tail(L, n);
// 4、输入查找位置
int t;
cin >> t;
while (t --)
{
int site;
cin >> site;
find(L, site, n);
}
return 0;
}
221、基于链式存储结构的图书信息表的新图书的入库
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的待入库的新图书的位置和图书的信息,将新图书插入到图书表中指定的位置上,最后输出新图书入库后的所有图书的信息。
输入
总计n+3行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。之后输入第n+2行,内容仅为一个整数,代表待入库的新图书的位置序号。最后输入第n+3行,内容为新图书的信息,书号、书名、价格用空格分隔。
输出
若插入成功: 输出新图书入库后所有图书的信息(书号、书名、价格),总计n+1行,每行是一本图书的信息,书号、书名、价格用空格分隔。其中价格输出保留两位小数。 若插入失败: 只输出以下一行提示:抱歉,入库位置非法!
输入样例 1
7
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
2
9787822234110 The-C-Programming-Language 38.00
输出样例 1
9787302257646 Data-Structure 35.00
9787822234110 The-C-Programming-Language 38.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
AC 代码
#include <iostream>
using namespace std;
struct Book // 定义书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode // 定义结点数据类型
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool Init(LinkList &L) // 创建头结点并使头结点指向空
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法
void createList_tail(LinkList &L, int n) // 利用尾插法得到链表,记得尾指针
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tail -> next = tmp;
tmp -> next = NULL;
tail = tmp;
}
}
// 输出整个链表
void show(LinkList L)
{
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
while (tmp) // 遍历
{
cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
printf("%.2lf\n", tmp -> data.price);
tmp = tmp -> next;
}
}
void add(LinkList &L, int site, int n)
{
if (site < 1 || site > n) // 情况特判
{
cout << "Sorry,the position to be inserted is invalid!" << endl;
return ;
}
LNode *tmp;
tmp = new LNode;
tmp = L;
site -= 1;
while (site --) // 先遍历找到待插入的位置
tmp = tmp -> next;
LNode *tmp1; // 先改右指向,再改左指向
tmp1 = new LNode;
cin >> tmp1 -> data.ibsn >> tmp1 -> data.name >> tmp1 -> data.price;
tmp1 -> next = tmp -> next;
tmp -> next = tmp1;
show(L); // 输出整个链表(内嵌函数)
}
int main()
{
// 1、通过头结点创建一个链表
LinkList L;
// 2、初始化
Init(L);
// 3、插入
int n;
cin >> n;
createList_tail(L, n);
// 4、进行入库
int site;
cin >> site;
add(L, site, n);
return 0;
}
222、基于链式存储结构的图书信息表的旧图书的出库
描述
定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后根据指定的待出库的旧图书的位置,将该图书从图书表中删除,最后输出该图书出库后的所有图书的信息。
输入
总计n+2行。首先输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格。其中书号和书名为字符串类型,价格为浮点数类型。之后输入第n+2行,内容仅为一个整数,代表待删除的旧图书的位置序号。
输出
若删除成功: 输出旧图书出库后所有图书的信息(书号、书名、价格),总计n-1行,每行是一本图书的信息,书号、书名、价格用空格分隔。其中价格输出保留两位小数。 若删除失败: 只输出以下一行提示:抱歉,出库位置非法!
输入样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
2
输出样例 1
9787302257646 Data-Structure 35.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输入样例 2
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
9
输出样例 2
Sorry,the position to be deleted is invalid!
AC 代码
#include <iostream>
using namespace std;
struct Book // 定义书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode // 定义结点数据类型
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool Init(LinkList &L) // 创建头结点并使头结点指向空
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法
void createList_tail(LinkList &L, int n) // 利用尾插法得到链表,记得尾指针
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tail -> next = tmp;
tmp -> next = NULL;
tail = tmp;
}
}
// 输出整个链表
void show(LinkList L)
{
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
while (tmp) // 遍历
{
cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
printf("%.2lf\n", tmp -> data.price);
tmp = tmp -> next;
}
}
void remove(LinkList &L, int site, int n)
{
if (site < 1 || site > n) // 情况特判
{
cout << "Sorry,the position to be deleted is invalid!" << endl;
return ;
}
LNode *tmp;
tmp = new LNode;
tmp = L;
site -= 1;
while (site --) // 先遍历找到待删除的位置
tmp = tmp -> next;
tmp -> next = tmp -> next -> next; // 只需要将next向后直接指两位,等价于删除一个结点
show(L); // 输出整个链表(内嵌函数)
}
int main()
{
// 1、通过头结点创建一个链表
LinkList L;
// 2、初始化
Init(L);
// 3、插入
int n;
cin >> n;
createList_tail(L, n);
// 4、进行出库
int site;
cin >> site;
remove(L, site, n);
return 0;
}
223、基于链存储结构的图书信息表的图书去重
描述
出版社出版的任何一本图书的书号(ISBN)都是唯一的,即图书表中不允许包含书号重复的图书。定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建(书号可能重复),然后进行图书的去重,即删除书号重复的图书(只保留第一本),最后输出去重后所有图书的信息。
输入
总计输入n+1行,其中,第一行是图书数目n,后n行是n本图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,价格之后没有空格(书号可能重复)。其中书号和书名为字符串类型,价格为浮点数类型。
输出
总计输出m+1行(m≤n),其中,第一行是去重后的图书数目,后m行是去重后图书的信息(书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔,其中价格输出保留两位小数。
输入样例 1
9
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
输出样例 1
8
9787302257646 Data-Structure 35.00
9787302164340 Operating-System 50.00
9787302219972 Software-Engineer 32.00
9787302203513 Database-Principles 36.00
9787810827430 Discrete-Mathematics 36.00
9787302257800 Data-Structure 62.00
9787811234923 Compiler-Principles 62.00
9787822234110 The-C-Programming-Language 38.00
AC 代码
#include <iostream>
using namespace std;
struct Book // 定义书类数据结构
{
string ibsn;
string name;
double price;
};
typedef struct LNode // 定义结点数据类型
{
Book data;
struct LNode *next;
}LNode, *LinkList;
// 初始化函数
bool Init(LinkList &L) // 创建头结点并使头结点指向空
{
L = new LNode;
L -> next = NULL;
return true;
}
// 尾插法
void createList_tail(LinkList &L, int n) // 利用尾插法得到链表,记得尾指针
{
LNode *tail;
tail = new LNode;
tail = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data.ibsn >> tmp -> data.name >> tmp -> data.price;
tail -> next = tmp;
tmp -> next = NULL;
tail = tmp;
}
}
// 去重
void unique(LinkList &L, int n)
{
LNode * tmp1 = L -> next; // 第一个指针从首元结点开始
int cnt = 0; // 存储重复的数量
while (tmp1) // 只要指针 1 不为空(未遍历到最后)
{
LNode *tmp2 = tmp1; // 让第二指针从首元结点开始,并且我们功能使用的是其next结点
while (tmp2 -> next) // 比较 n - 1次
{
if (tmp1 -> data.ibsn == tmp2 -> next -> data.ibsn)
{
LNode *tmp3 = tmp2 -> next; // 创建一个临时LNode变量存储这个结点的地址,然后释放
delete tmp3;
tmp2 -> next = tmp2 -> next -> next;
cnt ++; // 重复数量进行 ++
}
else tmp2 = tmp2 -> next;
}
tmp1 = tmp1 -> next;
}
cout << n - cnt << endl; // 输出去重后的数量
}
// 输出整个链表
void show(LinkList L)
{
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
while (tmp) // 遍历
{
cout << tmp -> data.ibsn << " " << tmp -> data.name << " ";
printf("%.2lf\n", tmp -> data.price);
tmp = tmp -> next;
}
}
int main()
{
// 1、通过头结点创建一个链表
LinkList L;
// 2、初始化
Init(L);
// 3、插入
int n;
cin >> n;
createList_tail(L, n);
// 4、去重
unique(L, n);
// 5、输出
show(L);
return 0;
}
224、基于链表的两个一元多项式的基本运算
AC 代码
#include <iostream>
using namespace std;
typedef struct PNode
{
double a; // a指整数
int x;
struct PNode *next;
}*Polynomial, PNode;
void createPolynomial(Polynomial &L, int n)
{
L = new PNode;
L -> next = NULL;
for (int i = 0; i < n; i ++)
{
PNode *s = new PNode;
cin >> s -> a >> s -> x;
PNode *pre = L;
PNode *cur = L -> next;
while (cur && s -> x < cur -> x)
{
pre = cur;
cur = cur -> next;
}
s -> next = cur;
pre -> next = s;
}
}
void outPutPolynomial(Polynomial L)
{
if (!L || !L -> next)
{
cout << 0 << endl;
return ;
}
PNode *p = L -> next;
while (p)
{
if (p == L -> next)
{
if (p -> x)
cout << p -> a << "x^" << p -> x;
}
else
{
if (p -> a > 0) cout << "+" ;
if (p -> x)
cout << p -> a << "x^" << p -> x;
else
cout << p -> a;
}
p = p -> next;
}
cout << endl;
}
int main()
{
int T;
cin >> T;
while (T --)
{
int a, b;
cin >> a >> b;
Polynomial L1, L2;
createPolynomial(L1, a);
createPolynomial(L2, b);
outPutPolynomial(L1);
outPutPolynomial(L2);
// char c;
// cin >> c;
// if (c == '+') outPutPolynomial(add(L1, L2));
}
return 0;
}
### 226、基于链表的两个非递减有序序列的合并
##### 描述
给定两个非递减的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个非递增的有序序列C,序列C允许有重复的数据。要求空间复杂度为O(1)。
##### 输入
多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。
##### 输出
对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。
##### 输入样例 1
```Cpp
5 5
1 3 5 7 9
2 4 6 8 10
5 6
1 2 2 3 5
2 4 6 8 10 12
0 0
输出样例 1
10 9 8 7 6 5 4 3 2 1
12 10 8 6 5 4 3 2 2 2 1
- 草了,原来根本不需要去重,XS
AC 代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
// 尾插法创建函数
LinkList createList(int n)
{
LinkList L; // 初始化
L = new LNode; // 申请空间必不可少
L -> next = NULL;
LNode *r = L ; // 尾指针
for (int i = 0; i < n; i ++)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void merge(LinkList &L1, LinkList &L2) // 合并的整体思路是将两个链表合并之后,仍然使用L1的空间
{
// 分为两种情况,如果 L1更小,则将L1的元素拿走;如果L2更小,则将L2的元素拿走;
// 拿走操作是指先将遍历结点接到工作指针之后,然后遍历结点和工作结点均后移
LNode *r1 = L1 -> next;
LNode *r2 = L2 -> next;
LNode *r3 = L1;
while (r1 && r2)
{
if (r1 -> data <= r2 -> data)
{
r3 -> next = r1;
r3 = r1;
r1 = r1 -> next;
}
else
{
r3 -> next = r2;
r3 = r2;
r2 = r2 -> next;
}
}
r3 -> next = r1 ? r1 : r2;
delete L2;
}
void reserShow(LinkList L) // 整个链表的输出函数
{
// 注意这里为暴力逆序输出
LNode *r;
r = new LNode;
r = L;
int cnt = 0;
while (r -> next)
{
cnt ++;
r = r -> next;
}
while (cnt --)
{
if (cnt == 0) // 这里进行特判是为了处理最后的空格
{
cout << L -> next -> data;
break;
}
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
for (int i = 0; i < cnt; i ++)
tmp = tmp -> next;
cout << tmp -> data << " ";
}
cout << endl;
// while (r -> next -> next) // 这里之所以用第三个结点作为遍历结点
// { // 是因为某OJ丧心病狂卡最后一个空格
// cout << r -> next -> data << " ";
// r = r -> next;
// }
// cout << r -> next -> data << endl;
}
int main()
{
int n1, n2;
while (true)
{
cin >> n1 >> n2;
if (n1 == 0 && n2 == 0) break; // 特判输入
LinkList L1, L2; // 1、创建两个链表
L1 = createList(n1);
L2 = createList(n2);
merge(L1, L2); // 2、进行合并
reserShow(L1); // 3、逆序输出
}
return 0;
}
225、基于链表的两个递增有序序列的合并
描述
给定两个递增的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个递增的有序序列C,序列C不允许有重复的数据。要求空间复杂度为O(1)。
输入
多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。
输出
对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。
输入样例 1
5 5
1 3 5 7 9
2 4 6 8 10
3 4
1 5 9
1 2 5 9
0 0
输出样例 1
1 2 3 4 5 6 7 8 9 10
1 2 5 9
- 题目要求空间复杂度是O(1),因此不能单独创建一个链表用来作为合并后的链表
- 草了,居然卡结尾空格
- 关于申请空间操作,如果是声明之后需要用到next指针,那么就必须要申请空间;如果可以直接赋值某个结点,那么申请空间操作就可以省略
AC 代码:
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
// 尾插法创建函数
LinkList createList(int n)
{
LinkList L; // 初始化
L = new LNode; // 申请空间必不可少
L -> next = NULL;
LNode *r = L ; // 尾指针
for (int i = 0; i < n; i ++)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void merge(LinkList &L1, LinkList &L2) // 合并的整体思路是将两个链表合并之后,仍然使用L1的空间
{
// 分为三种情况,如果 L1更小,则将L1的元素拿走;如果L2更小,则将L2的元素拿走;
// 若相等,则拿走 L1 ,且使 L2 的指针也需要后移
// 拿走操作是指先将遍历结点接到工作指针之后,然后遍历结点和工作结点均后移
LNode *r1 = L1 -> next;
LNode *r2 = L2 -> next;
LNode *r3 = L1;
while (r1 && r2)
{
if (r1 -> data < r2 -> data)
{
r3 -> next = r1;
r3 = r1;
r1 = r1 -> next;
}
else if (r1 -> data == r2 -> data)
{
r3 -> next = r1;
r3 = r1;
r1 = r1 -> next;
r2 = r2 -> next;
}
else
{
r3 -> next = r2;
r3 = r2;
r2 = r2 -> next;
}
}
if (r1) // 如果还有剩下,则只需要直接连接就好,不需要遍历
r3 -> next = r1;
if (r2)
r3 -> next = r2;
// 也可以用三目运算符进行骚操作
// r3 -> next = r1 ? r1 : r2;
delete L2;
}
void show(LinkList L) // 整个链表的输出函数
{
LNode *r;
r = new LNode;
r = L;
while (r -> next -> next) // 这里之所以用第三个结点作为遍历结点
{
// 是因为某OJ丧心病狂卡最后一个空格
cout << r -> next -> data << " ";
r = r -> next;
}
cout << r -> next -> data << endl;
}
int main()
{
int n1, n2;
while (true)
{
cin >> n1 >> n2;
if (n1 == 0 & n2 == 0) break; // 特判输入
LinkList L1, L2; // 1、创建两个链表
L1 = createList(n1);
L2 = createList(n2);
merge(L1, L2); // 2、进行合并
show(L1); // 3、输出
}
return 0;
}
226、基于链表的两个非递减有序序列的合并
描述
给定两个非递减的整数序列A和B,利用链表表示序列A和B,将A和B合并为一个非递增的有序序列C,序列C允许有重复的数据。要求空间复杂度为O(1)。
输入
多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。
输出
对于每组数据输出一行,为合并后的序列,每个数据之间用空格分隔。
输入样例 1
5 5
1 3 5 7 9
2 4 6 8 10
5 6
1 2 2 3 5
2 4 6 8 10 12
0 0
输出样例 1
10 9 8 7 6 5 4 3 2 1
12 10 8 6 5 4 3 2 2 2 1
- 草了,原来根本不需要去重,XS
AC 代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
// 尾插法创建函数
LinkList createList(int n)
{
LinkList L; // 初始化
L = new LNode; // 申请空间必不可少
L -> next = NULL;
LNode *r = L ; // 尾指针
for (int i = 0; i < n; i ++)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void merge(LinkList &L1, LinkList &L2) // 合并的整体思路是将两个链表合并之后,仍然使用L1的空间
{
// 分为两种情况,如果 L1更小,则将L1的元素拿走;如果L2更小,则将L2的元素拿走;
// 拿走操作是指先将遍历结点接到工作指针之后,然后遍历结点和工作结点均后移
LNode *r1 = L1 -> next;
LNode *r2 = L2 -> next;
LNode *r3 = L1;
while (r1 && r2)
{
if (r1 -> data <= r2 -> data)
{
r3 -> next = r1;
r3 = r1;
r1 = r1 -> next;
}
else
{
r3 -> next = r2;
r3 = r2;
r2 = r2 -> next;
}
}
r3 -> next = r1 ? r1 : r2;
delete L2;
}
void reserShow(LinkList L) // 整个链表的输出函数
{
// 注意这里为暴力逆序输出
LNode *r;
r = new LNode;
r = L;
int cnt = 0;
while (r -> next)
{
cnt ++;
r = r -> next;
}
while (cnt --)
{
if (cnt == 0) // 这里进行特判是为了处理最后的空格
{
cout << L -> next -> data;
break;
}
LNode *tmp;
tmp = new LNode;
tmp = L -> next;
for (int i = 0; i < cnt; i ++)
tmp = tmp -> next;
cout << tmp -> data << " ";
}
cout << endl;
// while (r -> next -> next) // 这里之所以用第三个结点作为遍历结点
// { // 是因为某OJ丧心病狂卡最后一个空格
// cout << r -> next -> data << " ";
// r = r -> next;
// }
// cout << r -> next -> data << endl;
}
int main()
{
int n1, n2;
while (true)
{
cin >> n1 >> n2;
if (n1 == 0 && n2 == 0) break; // 特判输入
LinkList L1, L2; // 1、创建两个链表
L1 = createList(n1);
L2 = createList(n2);
merge(L1, L2); // 2、进行合并
reserShow(L1); // 3、逆序输出
}
return 0;
}
227、基于链表的两个集合的交集
描述
给定两个递增的整数集合A和B,分别用链表表示集合A和B,求出A和B的交集,并存放在A中。要求空间复杂度为O(1)。
输入
多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。
输出
对于每组数据输出一行,为A和B的交集,每个数据之间用空格分隔。
输入样例 1
5 5
1 3 5 7 9
1 2 3 4 5
3 4
1 2 5
2 4 5 6
0 0
输出样例 1
1 3 5
2 5
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n) // 链表的创建和初始化函数
{
LinkList L;
L = new LNode;
L -> next = NULL;
LNode* r = L; // 利用尾插法进行创建
for (int i = 0; i < n; i ++)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
// 基本思路为用两个指针遍历两个链表,分三种情况讨论
LinkList merge(LinkList &L1, LinkList &L2)
{
LinkList L = createList(0);
LinkList p = L;
LinkList p1 = L1 -> next;
LinkList p2 = L2 -> next;
while (p1 && p2)
{
if (p1 -> data == p2 -> data)
{
p -> next = p1;
p = p1;
p1 = p1 -> next;
p2 = p2 -> next;
}
else if(p1 -> data > p2 -> data)
p2 = p2 -> next;
else
p1 = p1 -> next;
}
p -> next = NULL;
return L;
}
void show(LinkList L) // 输出函数(注意特判结尾空格)
{
LinkList p;
p = L -> next;
while (p -> next)
{
cout << p -> data << " ";
p = p -> next;
}
cout << p -> data;
cout << endl;
}
int main()
{
int n, m;
while (cin >> n >> m, n && m)
{
LinkList L1 = createList(n); // 进行链表的创建和初始化
LinkList L2 = createList(m);
LinkList L3 = merge(L1, L2);
// show(L1);
// show(L2);
show(L3);
}
return 0;
}
//给定两个递增的整数集合A和B,分别用链表表示集合A和B,求出A和B的交集,并存放在A中。要求空间复杂度为O(1)。
#include <bits/stdc++.h>
using namespace std;
typedef struct link {
int data;
struct link* next;
}link,*linklist;
void Createlist(linklist& L, int n)
{
L = new link[sizeof(link)];
L->next = NULL;
linklist p,r;
r = L;
while (n)
{
p=new link[sizeof(link)];
cin >> p->data;
p->next = r->next;
r->next = p;
r = p;
n--;
}
}
void Output(linklist L)
{
linklist p;
p = L->next;
int flag = 1;
while (p)
{
if (flag)
{
cout << p->data;
flag = 0;
}
else
cout << " " << p->data;
p=p->next;
}
cout << endl;
}
void Intersect(linklist& A, linklist& B)
{
linklist pa, pb, pc;
pa = A->next;
pc = A;
while (pa)
{
int flag = 1;
pb = B->next;
while (pb)
{
if (pb->data == pa->data)
{
flag = 0;
break;
}
else
pb = pb->next;
}
if (!flag)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else
pa = pa->next;
}
pc->next=NULL;
delete B;
}
int main()
{
linklist A, B;
int n, m;
while (1)
{
cin>>n>>m;
if(n==0&&m==0)
break;
Createlist(A, n);
Createlist(B, m);
Intersect(A, B);
Output(A);
}
return 0;
}
228、基于链表的两个集合的差集
描述
给定两个递增的整数集合,分别用链表A和B表示,求出A和B的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。要求空间复杂度为O(1)。
输入
多组数据,每组数据有三行,第一行为序列A和B的长度n和m,第二行为序列A的n个元素,第三行为序列B的m个元素(元素之间用空格分隔)。n=0且m=0时输入结束。
输出
对于每组数据输出两行,第一行是A和B的差集,第二行为差集中的元素个数,每个数据之间用空格分隔。
输入样例 1
5 5
1 3 5 7 9
1 2 3 4 5
3 4
1 2 6
2 4 5 7
0 0
输出样例 1
7 9
2
1 6
2
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
// LinkList difference(LinkList L1, LinkList L2)
// {
// LinkList L = createList(0);
// LinkList p = L;
// LinkList p1 = L1 -> next;
// LinkList p2 = L2 -> next;
// while (p1 && p2)
// {
// if (p1 -> data == p2 -> data)
// {
// p1 = p1 -> next;
// p2 = p2 -> next;
// }
// else if (p1 -> data < p2 -> data)
// {
// p -> next = p1;
// p = p1 -> next;
// p1 -> next;
// }
// else
// p2 = p2 -> next;
// }
// p -> next = NULL;
// return L;
// }
LinkList diff(LinkList L1, LinkList L2)
{
LinkList L = createList(0);
LinkList p = L;
LinkList p1 = L1 -> next;
LinkList p2 = L2 -> next;
while (p1 && p2)
{
if (p1 -> data == p2 -> data)
{
p1 = p1 -> next;
p2 = p2 -> next;
}
else if (p1 -> data > p2 -> data)
p2 = p2 -> next;
else if (p1 -> data < p2 -> data)
{
p -> next = p1;
p1 = p1 -> next;
p = p -> next;
}
if (!p2) p -> next = p1;
}
return L;
}
void show(LinkList L)
{
LinkList p = L -> next;
int cnt = 0;
while (p -> next)
{
cout << p -> data << " ";
p = p -> next;
cnt ++;
}
cout << p -> data;
cout << endl;
cout << cnt + 1 << endl;
}
int main()
{
int n, m;
while (cin >> n >> m, n && m)
{
LinkList L1 = createList(n);
LinkList L2 = createList(m);
LinkList L3 = diff(L1, L2);
show(L3);
}
return 0;
}
229、链表的分解
描述
利用单链表A表示一个非零整数序列,把A分解为两个具有相同结构的链表B和C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点。要求空间复杂度为O(1),链表B和C均利用链表A的结点空间。
输入
多组数据,每组数据有两行,第一行为链表A的长度n,第二行为链表A的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出两行,分别对应链表B和C的元素,每个数据之间用空格分隔。
输入样例 1
7
3 -6 1 -2 4 -3 8
8
2 5 3 -1 -2 2 6 -1
0
输出样例 1
-6 -2 -3
3 1 4 8
-1 -2 -1
2 5 3 2 6
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while(n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void show(LinkList L)
{
LinkList p = L -> next;
while (p -> next)
{
cout << p -> data << " ";
p = p -> next;
}
cout << p -> data;
cout << endl;
}
void resolve(LinkList L)
{
LinkList L1 = createList(0); // 初始化创建两个链表
LinkList L2 = createList(0);
LinkList r1 = L1; // 两个链表的尾指针
LinkList r2 = L2;
LinkList p = L -> next;
while (p)
{
if (p -> data < 0)
{
r1 -> next = p;
r1 = p;
}
else if (p -> data > 0)
{
r2 -> next = p;
r2 = p;
}
else ; // 如果和 0 相等的话,就不执行任何操作
p = p -> next;
}
r1 -> next = NULL; // 注意这两步,我们需要将尾指针置空,不然的话,最后的尾指针是指向 p
r2 -> next = NULL;
show (L1);
show (L2);
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L = createList(n);
resolve(L); // 分解函数中包含输出
}
return 0;
}
230、查找链表中的最大值
描述
利用单链表表示一个整数序列,通过一趟遍历在单链表中确定值最大的结点。
输入
多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出一行,输出每个链表的最大值。
输入样例 1
5
2 1 3 5 4
6
2 3 10 4 5 1
4
-1 -2 -3 -4
0
输出样例 1
5
10
-1
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void show(LinkList L)
{
LinkList p = L -> next;
while (p -> next)
{
cout << p -> data << " ";
p = p -> next;
}
cout << p -> data;
cout << endl;
}
/* 基本思路是:
将结点 1 的data值作为最大值,遍历链表时,如果有结点的值
大于 max ,则进行替换
*/
int getMax(LinkList L)
{
LinkList p = L -> next;
int max = p -> data;
while (p)
{
if (p -> data > max)
max = p -> data;
p = p -> next;
}
return max;
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L = createList(n);
cout << getMax(L) << endl; // 得到最大值并输出
}
return 0;
}
231、链表的逆转
描述
利用单链表表示一个整数序列,通过一趟遍历,将单链表中所有结点的链接方向逆转。要求空间复杂度为O(1)。
输入
多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出一行,逆序输出链表中的元素,元素之间用空格分隔。
输入样例 1
5
1 2 3 4 5
6
3 1 2 5 4 6
0
输出样例 1
5 4 3 2 1
6 4 5 2 1 3
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void show(LinkList L)
{
LinkList p = L -> next;
while (p -> next)
{
cout << p -> data << " ";
p = p -> next;
}
cout << p -> data;
cout << endl;
}
/* 基本思路:
用一个指针暴力到输入链表的尾端,然后将该结点存入新链表中
暴力循环的次数减 1,再次进行循环
*/
LinkList reserve(LinkList L, int n) // 注意这里将链表长度也传进去
{
LinkList L1 = createList(0); // 创建一个链表接收翻转后的链表
LinkList r1 = L1;
while (n --)
{
LinkList r = L -> next;
for (int i = 0; i < n; i ++)
r = r -> next;
r1 -> next = r;
r1 = r;
}
r1 -> next = NULL;
return L1;
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L = createList(n);
show (reserve(L, n));
}
return 0;
}
232、删除链表中满足区间值的结点
描述
利用单链表表示一个递增的整数序列,删除链表中值大于等于mink且小于等于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)。
输入
多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为给定的mink和maxk(用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出一行,依次输出删除元素后的链表元素,元素之间用空格分隔。
输入样例 1
5
1 2 3 4 5
2 4
6
2 4 6 8 10 12
3 5
0
输出样例 1
1 5
2 6 8 10 12
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void show(LinkList L)
{
LinkList p = L -> next;
while (p -> next)
{
cout << p -> data << " ";
p = p -> next;
}
cout << p -> data;
cout << endl;
}
/*
原理简单不解释,记住删除结点的抽象操作
*/
LinkList del(LinkList L, int mink, int maxk)
{
LinkList p = L;
while (p -> next)
{
if (p -> next -> data >= mink && p -> next -> data <= maxk)
{
LNode *tmp = p -> next;
p -> next = p -> next -> next;
delete tmp;
}
else p = p -> next; // 这个else一定要加上,不然就会重复进行后移操作
}
p -> next = NULL;
return L;
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L = createList(n);
int mink, maxk;
cin >> mink >> maxk;
show(del(L, mink, maxk));
}
return 0;
}
233、双向循环链表中结点的交换
描述
利用双向循环链表表示一个整数序列,指定一个结点位置用p指向该结点,交换p所指向的结点及其前驱结点的顺序。
输入
多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为p所指向的结点位置。当n=0时输入结束。
输出
对于每组数据分别输出一行,依次输出交换结点顺序后的链表元素,元素之间用空格分隔。
输入样例 1
5
44 11 22 33 55
3
6
22 33 11 66 44 55
6
0
输出样例 1
44 22 11 33 55
22 33 11 66 55 44
AC代码
/*这道题难点如下:
1、循环链表的建立
2、循环链表的输出
*/
#include <iostream>
using namespace std;
typedef struct BCLNode
{
int data;
struct BCLNode *next;
struct BCLNode *prior;
}BCLNode, *BCLinkList;
BCLinkList createList(int n)
{
BCLinkList L = new BCLNode; // 这是创建链表的简洁方式
cin >> L -> data; // 这里一定要注意,双向循环链表的每一个结点都有值
BCLinkList r = L; // 作为双向循环链表的尾指针
for (int i = 1; i < n; i ++) // 由于之前赋了一次值,因此只循环 n - 1 次
{
BCLNode *tmp = new BCLNode; // 临时结点
cin >> tmp -> data;
r -> next = tmp;
tmp -> prior = r;
r = tmp;
}
r -> next = L; // 最后将尾结点和头结点连接
L -> prior = r;
return L;
}
void show(BCLinkList L)
{
cout << L -> data << " "; // 注意这里需要先输出一次头结点
BCLNode *p = L -> next;
while (p -> next != L) // 终止条件是遍历指针指向头结点
{
cout << p -> data << " ";
p = p -> next;
}
cout << p -> data;
cout << endl;
}
/* 思路:
交换方面我们进行取巧,与其修改众多指针指向,
我们不如直接只交换遍历指针所指结点与其前驱结点
的数据即可,只是一个简单的swap函数
*/
void exchange(BCLinkList &L, int key)
{
BCLinkList p = L -> next;
for (int i = 0; i < key - 2; i ++) // 这里注意循环次数是 key - 2
p = p -> next;
int tmp = p -> prior -> data;
p -> prior -> data = p -> data;
p -> data = tmp;
}
int main()
{
int n;
while (cin >> n, n)
{
BCLinkList L = createList(n);
int key;
cin >> key;
exchange(L, key);
show(L);
}
return 0;
}
235、查找链表中倒数第k个结点
描述
利用单链表表示一个整数序列,请实现一个时间复杂度为O(n)、空间复杂度为O(1)的算法,通过一趟遍历在单链表中确定倒数第k个结点。
输入
多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为k。当n=0时输入结束。
输出
对于每组数据分别输出一行,输出每个链表的倒数第k个结点对应的数值。
输入样例 1
7
5 2 3 4 50 100 70
3
5
20 30 10 4 5
5
0
输出样例 1
50
20
AC代码
// 简单题,不解释
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L = createList(n);
int k;
cin >> k;
for (int i = 0; i < n - k + 1; i ++)
{
L = L -> next;
}
cout << L -> data << endl;
}
return 0;
}
236、删除链表中绝对值相等的结点
描述
利用单链表表示一个整数序列,实现一个时间复杂度为O(n)的算法,对于链表中绝对值相
等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。
例如,若给定的单链表HEAD如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDgOY7st-1635648565407)(https://www.bjfuacm.com/public/upload/b6286aba48.png)]
删除后的单链表HEAD为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QoszRfRK-1635648565410)(https://www.bjfuacm.com/public/upload/a6f8e04e53.png)]
输入
多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出一行,依次输出删除结点后的链表元素,元素之间用空格分隔。
输入样例 1
5
21 -15 -15 -7 15
7
90 32 -90 -66 77 66 90
0
输出样例 1
21 -15 -7
90 32 -66 77
AC代码
描述
利用单链表表示一个整数序列,请实现一个时间复杂度为O(n)、空间复杂度为O(1)的算法,通过一趟遍历在单链表中确定倒数第k个结点。
输入
多组数据,每组数据有三行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔),第三行为k。当n=0时输入结束。
输出
对于每组数据分别输出一行,输出每个链表的倒数第k个结点对应的数值。
输入样例 1
7
5 2 3 4 50 100 70
3
5
20 30 10 4 5
5
0
输出样例 1
50
20
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
void show(LinkList &L)
{
LinkList p=L->next;
while(p)
{
cout<<p->data;
if(p->next) cout<<" ";
p=p->next;
}
cout<<endl;
return;
}
/* 这段代码就是比较好的诠释了我对于结点指针的疑问
*/
// void delAbs(LinkList &L)
// {
// LinkList p = L -> next;
// while (p)
// {
// LinkList tmp = p -> next;
// while (tmp)
// {
// if (p -> data == tmp -> data || p -> data == (- tmp -> data))
// {
// LNode *tmp1 = tmp -> next;
// tmp -> next = tmp -> next -> next;
// delete tmp1;
// }
// tmp = tmp -> next;
// }
// p = p -> next;
// }
// }
void delAbs(LinkList &L)
{
LinkList p1, p2;
p1 = L -> next;
p2 = p1 -> next;
bool flag[100010] = {
0}; // 注意,这个数组定义在函数中,不要定义在全局范围内,因为只能使用一次
flag[abs(p1 -> data)] = 1; // 将这个值进行标记
while(p2)
{
if (flag[abs(p2 -> data)] == 0) // 如果这个值没有被标记,则标记
flag[abs(p2 -> data)] = 1;
else if (p2 -> next && flag[abs(p2 -> data)] == 1) // 如果pre不是尾结点且这个值被标记了,则删除这个结点
p1 -> next = p2 -> next;
else if (p2 -> next == NULL && flag[abs(p2 -> data)] == 1) // 如果为尾结点,且这个值被标记了,则指针置空
p1 -> next = NULL;
p2 = p2 -> next; // 使遍历指针后移
if (p1 -> next != p2) // 说明删除了一次,有可能后面还需要删,因此第一个遍历指针不能后移
p1 = p1 -> next;
}
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L = createList(n);
delAbs(L);
show(L);
}
return 0;
}
237、求解两个升序序列的中位数
描述
一个长度为L(L≥1)的升序序列S,处在第L/2(若为小数则去掉小数后加1)个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S1的中位数是15。两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现有两个等长升序序列A和B,试实现一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。
输入
多组数据,每组数据有三行,第一行为序列的长度n,第二行为序列A的n个元素,第三行为序列B的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出两个序列的中位数,占一行。
输入样例 1
511 13 15 17 19 2 4 6 8 2061 2 3 4 5 67 8 9 10 11 120
输出样例 1
116
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
LinkList r = L;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> data;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
return L;
}
/*整体思路:
遍历L1和L2,从小到大将结点存到新链表L3中,
然后由于两个链表合并之后,中位数即为第 n 位,
直接输出第 n 个结点
*/
void getMidian(LinkList L1, LinkList L2, int n)
{
LinkList p1 = L1 -> next;
LinkList p2 = L2 -> next;
LinkList L3 = createList(0);
LinkList p3 = L3;
while (p1 && p2)
{
if (p1 -> data < p2 -> data)
{
p3 -> next = p1;
p3 = p1;
p1 = p1 -> next;
}
else
{
p3 -> next = p2;
p3 = p2;
p2 = p2 -> next;
}
}
p3 -> next = NULL;
for (int i = 0; i < n; i ++)
L3 = L3 -> next;
cout << L3 -> data << endl;
}
int main()
{
int n;
while (cin >> n, n)
{
LinkList L1 = createList(n);
LinkList L2 = createList(n);
getMidian(L1, L2, n);
}
return 0;
}
238、查找两个单词链表共同后缀的起始结点
描述
利用单链表表示一个整数序列,通过一趟遍历在单链表中确定值最大的结点。
输入
多组数据,每组数据有两行,第一行为链表的长度n,第二行为链表的n个元素(元素之间用空格分隔)。当n=0时输入结束。
输出
对于每组数据分别输出一行,输出每个链表的最大值。
输入样例 1
52 1 3 5 462 3 10 4 5 14-1 -2 -3 -40
输出样例 1
510-1
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef struct LNode
{
char ch;
struct LNode *next;
}LNode, *LinkList;
/*整体思路:
我们使用前插法,这样的话,就不需要遍历了
*/
LinkList createList(int n)
{
LinkList L;
L = new LNode;
L -> next = NULL;
while (n --)
{
LNode *tmp;
tmp = new LNode;
cin >> tmp -> ch;
tmp -> next = L -> next;
L -> next = tmp;
}
return L;
}
// test
// void show(LinkList L)
// {
// LinkList p = L -> next;
// while (p -> next)
// {
// cout << p -> ch << " ";
// p = p -> next;
// }
// cout << p -> ch;
// cout << endl;
// }
void findSame(LinkList L1, LinkList L2)
{
LinkList p1 = L1 -> next;
LinkList p2 = L2 -> next;
while (p1 -> next && p2 -> next)
{
if (p1 -> next -> ch != p2 -> next -> ch)
{
cout << p1 -> ch << endl;
return ;
}
p1 = p1 -> next;
p2 = p2 -> next;
}
}
int main()
{
int n, m;
while (cin >> n >> m, n && m)
{
LinkList L1 = createList(n);
LinkList L2 = createList(m);
findSame(L1, L2);
}
return 0;
}
239、猴子选大王问题
描述
一堆猴子都有编号,编号是1,2,3 …m,这群猴子(m个)按照1~m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。利用单向循环链表模拟此过程,依次输出出圈的猴子编号。
输入
多组数据,每组数据占一行,包括两个数据m和n。m代表猴子个数,n代表步数,m=0且n=0时输入结束。
输出
依次输出出圈的猴子编号,编号之间用空格隔开。
输入样例 1
10 48 30 0
输出样例 1
4 8 2 7 3 10 9 1 6 53 6 1 5 2 8 4 7
AC代码
#include <iostream>
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode, *LinkList;
/*注意,这里的创建函数和之前不太一样,循环单链表要求不能有头结点
因此,使用尾插法创建函数时,我们应该先输入首元结点,然后再创建剩
下的 n - 1个结点,最后使得尾指针指向首元结点
*/
LinkList createList(LinkList &L, int n)
{
L = new LNode;
L -> data = 1;
L -> next = NULL;
LinkList r = L;
for (int i = 2; i <= n; i ++) // 注意这里是从 2 开始
{
LNode *tmp;
tmp = new LNode;
tmp -> data = i;
tmp -> next = NULL;
r -> next = tmp;
r = tmp;
}
r -> next = L; // 尾指针的next指向头结点
L = r; // 链表名指向尾指针
return L;
}
void moneyKing(LinkList L, int m)
{
while (L -> next != L)
{
for (int i = 1; i < m; i ++)
L = L -> next;
LinkList tmp = L -> next;
cout << tmp -> data << " ";
L -> next = tmp -> next; // 输出最后一个猴子,顺便特判空格
delete(tmp);
}
cout << L -> data;
cout << endl;
}
int main()
{
int n, m;
while (cin >> n >> m, n)
{
LinkList L;
createList(L, n);
moneyKing(L, m);
}
return 0;
}