今天白天学会了链表的排序(选择和冒泡)、合并、插入、删除
链表的合并
题目描述
知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
3 5 1 3 4 6 0 5 4 8 9 5
样例输出content_copy
#include<stdio.h>
#include<string.h>
struct note//定义结构体类型
{
int date;
struct note *next;
};
int n,m;//全局变量
struct note *creat (int n)//创建链表
{
struct note *p,*q,*head,*t;
int a,i;
head=NULL;
for(i=0; i<n; i++)
{
scanf("%d",&a);
p=(struct note *)malloc(sizeof(struct note));
p->date=a;
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
return head;
};
int main()
{
struct note *t,*p,*l;
scanf("m=%d",&m);
t=creat(m);
getchar();
getchar();//回收字符串(很有必要,因为在例题中输入的两组数据中间有一个空行)
l=t;
scanf("n=%d",&n);
p=creat(n);
while(t!=NULL)
{
if(t->next==NULL)
{
t->next=p;//将t链表末尾指向空的指针指向p的首地址
break;
}
t=t->next;
}
while(l!=NULL)
{
printf("%d ",l->date);
l=l->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<string.h>
struct note
{
int date;
struct note *next;
};
int main()
{
struct note *p,*q,*head,*t,*b;
int a,i,n;
scanf("%d",&n);
head=NULL;
for(i=0; i<n; i++)
{
scanf("%d",&a);
p=(struct note *)malloc(sizeof(struct note));
p->date=a;
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
b=head;
t=head;
int k;
while(b->next!=NULL)
{
t=b->next;//t指针始终表示b所指向的下一个地址
while(t!=NULL)
{
if(b->date>t->date)//比较前后两个地址的数据大小
{
k=b->date;
b->date=t->date;
t->date=k;
}//交换两个地址的数值
t=t->next;
}
b=b->next;
}
t=head;
while(t!=NULL)
{
printf("%d ",t->date);
t=t->next;
}
}
冒泡排序
#include<stdio.h>
#include<string.h>
struct note
{
int date;
struct note *next;
};
int main()
{
struct note *p,*q,*head,*t,*tail;
int a,i,n;
scanf("%d",&n);
head=NULL;
for(i=0; i<n; i++)
{
scanf("%d",&a);
p=(struct note *)malloc(sizeof(struct note));
p->date=a;
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
t=head;
tail=NULL;
int k;
while(t->next!=tail)
{
while(t->next!=tail)
{
if(t->date>t->next->date)
{
k=t->date;
t->date=t->next->date;
t->next->date=k;
}//将最大的数移到最后
t=t->next;
}
tail=t;//将链表的尾指针前移
t=head;//将t指针重新定义为头指针,从头再次遍历
}
t=head;
while(t!=NULL)
{
printf("%d ",t->date);
t=t->next;
}
}
插入
题目描述
(线性表)已知一单链表,从第二个结点至表尾递增有序,(设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<string.h>
struct note
{
int date;
struct note *next;
};
int main()
{
struct note *p,*q,*head,*t;
int a,i,n;
scanf("%d",&n);
head=NULL;
for(i=0;i<n;i++)
{
scanf("%d",&a);
p=(struct note *)malloc(sizeof(struct note));
p->date=a;
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
int k,leap=0;
k=head->date;
t=head;
while(t->next!=NULL)
{
if(k<t->next->date)
{
p=(struct note *)malloc(sizeof(struct note));
p->date=k;
p->next=t->next;
t->next=p;
leap=1;
break;
}
t=t->next;
}
if(leap==0)
{
t=head;
for(;;)
{
t=t->next;
if(t->next==NULL)
{
p=(struct note *)malloc(sizeof(struct note));
p->date=k;
p->next=NULL;
t->next=p;
break;
}
}
}
t=head->next;
while(t!=NULL)
{
printf("%d ",t->date);
t=t->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<string.h>
struct note
{
int date;
struct note *next;
};
int main()
{
struct note *p,*q,*head,*t,*b;
int a,i,n;
scanf("%d",&n);
head=NULL;
for(i=0;i<n;i++)
{
scanf("%d",&a);
p=(struct note *)malloc(sizeof(struct note));
p->date=a;
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
t=head;
int min=t->date;
while(t->next!=NULL)
{
if(min>t->next->date)
min=t->next->date;
t=t->next;
}
t=head;
while(t!=NULL)
{
if(t->next->date==min)
{
b=t->next;//将b指针指向t的后一个地址
t->next=t->next->next;//将t指针指向t指针的下下个地址,达到删除t指针的后一个地址的目的
b->next=head;//同时将删去的b指针指向t链表的头指针
break;
}
}
t=b;
//printf("%d %d %d\n",b->date,b->next->date,head->date);
while(t!=NULL)
{
printf("%d ",t->date);
t=t->next;
}
}
今天学习了链表,完成了链表的6道题,还听学长讲了dfs,bfs,和快排
明日计划
学习链表的双向循环,继续完成链表的其他题目
学习搜索,写洛谷上的题目