1.链表的冒泡排序(结构体+链表)
题目描述
根据输入,采用尾插法创建链表。对创建的链表使用冒泡排序进行降序排序,输出排序后的链表。
说明:程序中不可见数组、容器,否则计0分。
输入
测试次数t
每组测试数据格式为:
数据个数n
n行,每行一个字符串
输出
对每组测试数据,输出字符串按字典降序排序后的链表。各组输出间以空行分隔。
输入样例
2
4
shenzhen
nanjing
beijing
wuhan
6
china
brazil
germany
philippines
switzerland
singapore
输出样例
wuhan
shenzhen
nanjing
beijing
switzerland
singapore
philippines
germany
china
brazil
AC代码
#include<iostream>
#include<cstring>
using namespace std;
struct node
{
string city;
node* next;
};
void create(node* h, int n)
{
h->next = NULL;
node* pp = h, * p2;
string cc;
for (int i = 0; i < n; i++)
{
cin >> cc;
p2 = new node;
p2->next = NULL;
p2->city = cc;
pp->next = p2;
pp = p2;
}
}
void nodesort(node* h, int n)
{
for (int i = 1; i <= n - 1; i++)//共排序n-1趟
{
int cnt = 0;//记录交换次数
bool flag = false;//判断是否已有序
node* p = h;
while (p->next != NULL && cnt != n - i)//当p不是最后一个且还没交换完时则继续
{
if (p->next->city < p->next->next->city)
{
//设本来为 A B C(初始p1为p->next,p2为p1->next)
node* tmp;
tmp = p->next;//p1=A,tmp=A
p->next = p->next->next;//p1=B; -->B C
tmp->next = p->next->next;//A C(tmp)
p->next->next = tmp;
flag = 1;//有交换
}
++cnt;
p = p->next;
}
if (flag==0)break;//已有序
}
}
void show(node* h)
{
while (h->next != NULL)
{
h = h->next;
cout << h->city << endl;
}
cout << endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
node* h = new node;
create(h, n);
nodesort(h, n);
show(h);
}
return 0;
return 0;
}
2.约瑟夫环(结构体+循环链表)
题目描述
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
用循环链表实现约瑟夫环。
输入
输入多组测试数据,每组测试数据格式如下:
人数n(>0)开始位置k(>0)报数m(>0)
输出
对每组测试数据,输出出圈顺序。
输入样例
3 1 2
5 3 3
输出样例
2 1 3
5 3 2 4 1
AC代码:
#include<iostream>
using namespace std;
struct node
{
int num;
node* next;
};
node* createcircle(node* h, int n)
{
node* s = NULL;
h->num = 1;//初始头指针为编号1
h->next = h;//头指针指向自己构成环
for (int i = 2; i <= n; i++)
{
s = new node;
//插入新结点
s->num = i;
//插入编号
s->next = h->next;
//插入的这一个也要指向前一个的下一个
h->next = s;
h = s;
//接到尾部继续插入
}
return s;//返回尾结点
}
void printout(node* t, node* h, int k, int m, int n)
{
node* pre, * p;
node* q1 = h, * q2 = t;
//定位到第k个位置
for (int i = 1; i <= k-1; i++)
{
q2 = q1;
q1 = q1->next;
}
pre = q2;
p = q1;
int count = 1;
//此时p下标为1;
while (p->next != p)//不到环的最后一个时
{
if(count < m)//数到m-1时进入,此时p所对即为第m个(因为count也加一)
{
pre = p;
p = p->next;
count++;
}
else
{
cout << p->num << " ";
pre->next = p->next;
delete p;//删掉p
p = pre->next;
count = 1;
}
}
//输出最后一个人
cout << p->num << endl;
delete p;
}
int main()
{
int n, k, m;
while (cin >> n >> k >> m)//能够多组测试数据
{
node* h = new node;
node* tt = createcircle(h, n);
printout(tt, h, k, m, n);
}
return 0;
}
3.链表原地反转(链表)(订正版)
题目描述
按数字输入顺序创建单链表。不可借助数组、容器,不可开辟新结点空间。编写函数,在原链表上实现单链表的反转。例如单链表10->20->30,反转后变为单链表30->20->10。
注:不符合题目要求,使用上题逆序输出不计分。
输入
测试次数t
每组测试数据一行,格式如下:
数据个数n,后跟n个整数
输出
对每组测试数据,输出反转后的单链表。
输入样例
2
10 1 2 3 4 5 6 7 8 9 10
4 19 20 15 -10
输出样例
10 9 8 7 6 5 4 3 2 1
-10 15 20 19
AC代码:
#include<iostream>
using namespace std;
struct node
{
int num;
node* next;
};
void create(node* h, int n)
{
h->next = NULL;
node* pp = h, * p2;
int x;
for (int i = 0; i < n; i++)
{
cin >> x;
p2 = new node;
p2->next = NULL;
p2->num = x;
pp->next = p2;
pp = p2;
}
}
void show(node* h)
{
node* p = h;
while (p->next != NULL)
{
p = p->next;
cout << p->num << " ";
}
cout << endl;
}
void reverse(node* h)
{
if (h->next == NULL)
{
cout << h->num << " ";
return;
}
else if (h->next)
{
reverse(h->next);
}
cout << h->num << " ";
return;
}
int main()
{
int t;
cin >> t;
while (t--)
{
node* h = new node;
int n;
cin >> n;
create(h, n);
//show(h);
reverse(h->next);
//一定要记得从链表的首元素开始,不能是头指针!而是头指针的下一个!
cout<<endl;
}
return 0;
}