1.上午3个半小时
解决了链表题组的两个题目
题目描述
(线性表)假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
输入格式
输入长度n:5
输入数据:1 2 5 6 8
输入长度m:5
输入数据:3 4 7 9 10
输出格式
10 9 8 7 6 5 4 3 2 1
样例输入
4
7 9 10 11
4
8 12 13 14
样例输出
14 13 12 11 10 9 8 7
思路
利用两个指针同时从第一个结点开始往后移动,比较两个指针所指的结点的数据域的大小,输出大的,如果一样大,就都输出,大多数情况下,有一个链表为空,有一个链表不为空,所以最后把不为空的链表全部输出。注意注意,一定不要忘记continue了
代码实现
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
} Node,*Link;
int main()
{
int n,m;
Link head1,head2,p1,p2,r1,r2;
head1=(Link)malloc(sizeof(Node));//创建头节点
head2=(Link)malloc(sizeof(Node));
head1->next=NULL;
head2->next=NULL;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
p1=(Link)malloc(sizeof(Node));
scanf("%d",&(p1->data));
p1->next=head1->next;
head1->next=p1;
}
scanf("%d",&m);
for(int i=0; i<m; i++)
{
p2=(Link)malloc(sizeof(Node));
scanf("%d",&(p2->data));
p2->next=head2->next;
head2->next=p2;
}
p1=head1->next;
p2=head2->next;
while(p1!=NULL&&p2!=NULL)
{
if(p1->data>p2->data)
{
printf("%d ",p1->data);
p1=p1->next;
continue;//不加continue就会拿NULL和数比较
}
if(p1->data<p2->data)
{
printf("%d ",p2->data);
p2=p2->next;
continue;
}
if(p1->data==p2->data)
{
printf("%d %d ",p1->data,p2->data);
p1=p1->next;
p2=p2->next;
continue;
}
}
while(p1!=NULL)//当链表2全部遍历完了,链表1有剩余的
{
printf("%d ",p1->data);
p1=p1->next;
}
while(p2!=NULL)//当链表1全部遍历完了,链表2有剩余的
{
printf("%d ",p2->data);
p2=p2->next;
}
return 0;
}
输出
4
7 9 10 11
4
8 12 13 14
14 13 12 11 10 9 8 7
Process returned 0 (0x0) execution time : 1.912 s
Press any key to continue.
题目描述
(线性表)已知不带头结点的线性链表list,链表中结点构造为(data、link),其中data为数据域,link为指针域。请写一算法,将该链表按结点数据域的值的大小从小到大重新链接。要求链接过程中不得使用除该链表以外的任何链结点空间。
输入格式
自定义链表节点数
m=5
3 1 5 4 6
输出格式
1 3 4 5 6
样例输入
8
10 1 5 14 32 55 67 6
样例输出
1 5 6 10 14 32 55 67
思路
这题思路很简单,就是排序,但是我排序的时候把头也放进去了,所以输出的时候不要忘记先把指针往前移动一个位置再输出。
代码实现
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* link;
} Node, *Link;
int main()
{
Link r, l, p, q;
int m, i, t;
scanf("%d", &m);
l = r = (Link)malloc(sizeof(Node));
for (i = 0; i < m; i++)//后续结点
{
p = (Link)malloc(sizeof(Node));
scanf("%d", &(p->data));
r = r->link = p;
}
r->link = NULL;
for (p = l->link; p != NULL; p = p->link)//排序
{
for (q = p->link; q != NULL; q = q->link)
{
if (p->data > q->data)
{
t = q->data;
q->data = p->data;
p->data = t;
}
}
}
while (l->link != NULL)
{
l = l->link;//这一行与下一行的位置一定要注意,不可以搞反了
printf("%d ", l->data);
}
return 0;
}
结果
8
10 1 5 14 32 55 67 6
1 5 6 10 14 32 55 67
Process returned 0 (0x0) execution time : 6.584 s
Press any key to continue.
2.下午两个半小时
解决了链表的一个题目
题目描述
已知非空线性链表由list指出,链结点的构造为(data,link).请写一算法,将链表中数据域值最小的那个链结点移到链表的最前面。要求:不得额外申请新的链结点
输入格式
输入长度n:6
输入数据:4 2 6 88 34 6
输出格式
2 4 6 88 34 6
思路
先遍历一遍,找出最小值,然后在遍历一遍,找出最小值所在的位置,因为我用的是头插法,所以是把它与尾节点之前的一个节点交换,这里我用了一个等价的t进行交换,最后输出的时候,因为我是用头插法创建单链表的,所以要逆序输出。
代码实现
#include<stdio.h>//头插法创建的链表,数据的实际顺序与输入顺序相反,因此如果用头插法创建连表,最小值应该和最后的数进行交换
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
} Node,*Link;
int main()
{
int n,i,min,t;
scanf("%d",&n);
int a[n];
Link head,p,q;
head=(Link)malloc(sizeof(Node));
head->next=NULL;
for(i=0; i<n; i++)
{
p=(Link)malloc(sizeof(Node));
scanf("%d",&(p->data));
p->next=head->next;
head->next=p;
}
p=head->next;
min=p->data;
while(p!=NULL)
{
if(p->data<min)
{
min=p->data;
}
q=p;
p=p->next;
}
p=head->next;
while(p!=NULL)
{
if(p->data==min)
{
t=p->data;
p->data=q->data;
q->data=t;
}
p=p->next;
}
p=head->next;
i=0;
while(p!=NULL)
{
a[i]=p->data;
p=p->next;
i++;
}
for(i=n-1;i>=0;i--)
printf("%d ",a[i]);
return 0;
}
3.晚上两个半小时
计划解决链表题组剩余的两个题目,但代码都没有特别完善,因此没有解决任何题目