主要学习了链表的有关知识,把学校刷题网站上链表题组刷了六道,基本掌握了链表的概念,如何建立链表,如何将链表进行排序,链表的插入和合并。
题目描述
(线性表)已知一单链表,从第二个结点至表尾递增有序,(设a1<x<an)如下图(“第二个结点至表尾”指a1..an )。试编写程序,将第一个结点删除并插入表中适当位置,使整个链表递增有序。
输入格式
输入长度n:7
输入数据:4 1 2 3 6 8 9
输出格式
1 2 3 4 6 8 9
样例输入content_copy
5 11 7 8 9 10
样例输出content_copy
7 8 9 10 11
#include<stdio.h>
#include<stdlib.h>
struct node{//建立结点
int date;
struct node *next;
};
int main()
{
int n;
scanf("%d",&n);
struct node *p,*q,*t,*head;
head=NULL;
int f;
scanf("%d",&f);
int a;
for(int i=1;i<n;i++){//建立链表
scanf("%d",&a);
p=(struct node *)malloc(sizeof(struct node));
p->date=a;
p->next=NULL;
if(head==NULL){
head=p;
}
else{
q->next=p;
}
q=p;
}
t=head;
while(t!=NULL){
if(t->next==NULL||t->next->date>f){//将第一个数字插入到链表的合适位置
p=(struct node *)malloc(sizeof(struct node));
p->date=f;
p->next=t->next;
t->next=p;
break;
}
t=t->next;
}
t=head;
while(t!=NULL){//输出链表
printf("%d ",t->date);
t=t->next;
}
}
题目描述
(线性表)已知不带头结点的线性链表list,链表中结点构造为(data、link),其中data为数据域,link为指针域。请写一算法,将该链表按结点数据域的值的大小从小到大重新链接。要求链接过程中不得使用除该链表以外的任何链结点空间。
输入格式
自定义链表节点数
m=5
3 1 5 4 6
输出格式
1 3 4 5 6
样例输入content_copy
8 10 1 5 14 32 55 67 6
样例输出content_copy
1 5 6 10 14 32 55 67
思路
链表排序可分为直接将链表里的数值交换和将结点交换两种,这里用到的是前者,运用冒泡排序将链表进行排序。
#include<stdio.h>
#include<stdlib.h>
typedef struct list
{
int date;
struct list *next;
}node;
int main()
{
int n;
scanf("%d",&n);
node *p,*q,*t,*head;
int a;
head=NULL;
for(int i=0;i<n;i++){//建立无头结点的链表
scanf("%d",&a);
p=(node *)malloc(sizeof(node));
p->date=a;
p->next=NULL;
if(head==NULL){
head=p;
}
else{
q->next=p;
}
q=p;
}
q=head;
int temp;
for(int i=0;i<n-1;i++){//运用冒泡排序将链表进行排序
for(int j=0;j<n-i-1;j++){
if(q->date>q->next->date){
temp=q->date;
q->date=q->next->date;
q->next->date=temp;
}
q=q->next;
}
q=head;
}
p=head;
while(p!=NULL){//输出链表
printf("%d ",p->date);
p=p->next;
}
}
题目描述
已知非空线性链表由list指出,链结点的构造为(data,link).请写一算法,将链表中数据域值最小的那个链结点移到链表的最前面。要求:不得额外申请新的链结点
输入格式
输入长度n:6
输入数据:4 2 6 88 34 6
输出格式
2 4 6 88 34 6
样例输入content_copy
5 11 6 8 7 9
样例输出content_copy
6 11 8 7 9
#include<stdio.h>
#include<stdlib.h>
struct node
{
int date;
struct node *next;
};
int main()
{
int n,a;
scanf("%d",&n);
struct node *head,*p,*q,*t;
head=NULL;
for(int i=0;i<n;i++){//建立链表
scanf("%d",&a);
p=(struct node *)malloc(sizeof(struct node));
p->date=a;
p->next=NULL;
if(head==NULL){
head=p;
}
else{q->next=p;
}
q=p;
}
t=head;
int min=head->date;
while(t!=NULL){//找出链表中的最小值
if(min>t->date){
min=t->date;
}
t=t->next;
}
t=head;
while(t!=NULL){//查询最小值的位置
if(t->next->date=min){
t->next=t->next->next;
break;
}
t=t->next;
}
p=(struct node *)malloc(sizeof(struct node));//将最小值插入链表首部
p->date=min;
p->next=head;
t=p;
while(t!=NULL){//输出
printf("%d ",t->date);
t=t->next;
}
}
题目描述
小T昨天很不爽
昨天路过体彩销售点买了2注生日号码玩,当晚开奖后……
小T号码: 8902088
中奖号码:3902888
一个号码不对就差了十几万……
小T想:为什么规则是那样玩的啊……为什么5个号码要连续才能中二等奖啊……
我自己创建个规则,开N个数字,只要数字位置对了不一定要连续就可以有奖。
现在有一个中奖号码,有一个兑奖号码,小T想知道一共有多少个数字位置正确的,N太大了……要求用链表做
输入格式
输入数据第一行包含一个整数T表示有T组测试数据
对于每组测试数据
第一行包含一个整数N,表示有N个数字
第二行包含N个中奖号码
第三行包含N个兑奖号码
输出格式
对于每组测试数据输出有多少个号码位置正确了
样例输入content_copy
2 7 3902888 8902088 10 1234567890 0987654321
样例输出content_copy
5 0
思路
建立两个数据为字符型的链表,一个结点存一个数,将两个链表进行比较,输出相同位置为相同数字的个数。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
char date;
struct node *next;
}link;
link *creat(int n)//建立链表
{
link *head,*p,*q;
head=(link *)malloc(sizeof(link));
q=head;
while(n--){
p=(link *)malloc(sizeof(link));
scanf("%c",&p->date);
q->next=p;
q=p;
}
q->next=NULL;
return head;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n,s=0;
scanf("%d",&n);
link *p1,*p2,*q1,*q2,*t2,*t1,*head1,*head2;
getchar();//不能忘了吸收一个换行
head1=creat(n);
getchar();
head2=creat(n);
getchar();
t1=head1->next;
t2=head2->next;
while(t1!=NULL&&t2!=NULL){//计算相同位置相同数字的个数
if((t1->date)==(t2->date)){
s++;
}
t1=t1->next;
t2=t2->next;
}
printf("%d\n",s);
}
}
题目描述
知L1、L2分别为两循环单链表的头结点指针,m,n分别为L1、L2表中数据结点个数。要求设计一算法,用最快速度将两表合并成一个带头结点的循环单链表。
输入格式
m=5
3 6 1 3 5
n=4
7 10 8 4
输出格式
3 6 1 3 5 7 10 8 4
样例输入content_copy
m=7 3 5 1 3 4 6 0 n=5 5 4 8 9 5
样例输出content_copy
3 5 1 3 4 6 0 5 4 8 9 5
思路
建立两个链表,将第一个链表的最后一个结点的next部分连接到第二个链表的有数值的第一个结点,即可实现链表合并。
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int date;
struct node *next;
}link;
link *creat(int n)//建立链表
{
link *head,*p,*q;
head=(link *)malloc(sizeof(link));
q=head;
while(n--){
p=(link *)malloc(sizeof(link));
scanf("%d",&p->date);
q->next=p;
q=p;
}
q->next=NULL;
return head;
}
int main()
{
int m,n;
link *p1,*p2,*q1,*q2,*head1,*head2,*t;
scanf("m=%d",&m);
head1=creat(m);
getchar();//吸收换行
getchar();
scanf("n=%d",&n);
head2=creat(n);
t=head1;
while(t!=NULL){//将第一个链表和第二个链表连接
if(t->next==NULL){
(t->next)=(head2->next);
break;
}
t=t->next;
}
/*(q1->next)=(head2->next);*/
t=head1->next;
while(t!=NULL){//输出合并后的链表
printf("%d ",t->date);
t=t->next;
}
}
题目描述
(线性表)假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
输入格式
输入长度n:5
输入数据:1 2 5 6 8
输入长度m:5
输入数据:3 4 7 9 10
输出格式
10 9 8 7 6 5 4 3 2 1
样例输入content_copy
4 7 9 10 11 4 8 12 13 14
样例输出content_copy
14 13 12 11 10 9 8 7
思路
前两题链表排序和链表合并
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int date;
struct node *next;
}link;
link *creat(int n)//建立链表
{
link *head,*p,*q;
head=(link *)malloc(sizeof(link));
q=head;
while(n--){
p=(link *)malloc(sizeof(link));
scanf("%d",&p->date);
q->next=p;
q=p;
}
q->next=NULL;
return head;
}
int main()
{
int m,n;
link *p1,*p2,*q1,*q2,*head1,*head2,*t;
scanf("%d",&m);
head1=creat(m);
scanf("%d",&n);
head2=creat(n);
t=head1;
while(t!=NULL){//将两个链表合并
if(t->next==NULL){
(t->next)=(head2->next);
break;
}
t=t->next;
}
t=head1->next;
int temp;
for(int i=0;i<n+m-1;i++){//将合并后的链表进行排序
for(int j=0;j<n+m-i-1;j++){
if((t->date)<(t->next->date)){
temp=(t->date);
(t->date)=(t->next->date);
(t->next->date)=temp;
}
t=t->next;
}
t=head1->next;
}
t=head1->next;
while(t!=NULL){//输出
printf("%d ",t->date);
t=t->next;
}
}
学习时长:10h
明日目标:
将链表的题刷完
然后学习搜索算法