题目编号:Exp09-Basic04
题目名称:单链表交换两结点
题目描述:请填写缺失代码完成程序,实现如下功能:
首先根据键盘随机输入,以0结束的若干非零整数建立单链表;
然后根据输入的两个索引位置交换链表上的两个结点(链表首元素索引为1,且要交换的两个索引位置不相邻);
最后链表各结点值输出,相邻数字间以一个西文空格间隔,最后一个数字后无任何字符。
若是空链表,则输出NULL。
例如,
输入:1 2 3 4 5 6 0 1 5
输出:5 2 3 4 1 6
输入:0 1 2 3 4 5 6 0 1 5
输出:NULL
#include <stdio.h>
#include <malloc.h>
struct cell {
int x;
struct cell* next;
};
struct cell* build(void) {
struct cell* head, * tmp, * p;
head = tmp = p = NULL;
int n;
scanf("%d",&n);
while(n!=0)
{
p=NULL;
p=(struct cell*)malloc(sizeof(struct cell*));
p->x=n;
p->next=NULL;
if(head==NULL)
{
head=p;
tmp=head;
}
else
{
tmp->next=p;
tmp=p;
}
scanf("%d",&n);
}
return head;
}
struct cell* swap(struct cell* head,int m,int n) {//交换索引为m和n的两个结点,head是单链表首结点指针
if(head==NULL) return NULL;
struct cell* pm=head, * pn=head;
struct cell* pm0 = NULL, * pn0 = NULL;
struct cell* tmp;
int i;
for (i = 1;i < m && pm != NULL;i++) {
pm0 = pm;
pm = pm->next;
}
for (i = 1;i < n && pn != NULL;i++) {
pn0 = pn;
pn = pn->next;
}
if (pm != NULL && pn != NULL && m != n) {//索引为m,n的结点位于链表中间
tmp=pm->next;
pm->next=pn->next;
pn->next=tmp;
if (pm0 != NULL && pn0 != NULL) {
pm0->next=pn;
pn0->next=pm;
}
if (pm0 == NULL && pn0 != NULL) {
pn0->next=pm;
head=pn;
}
if (pm0 != NULL && pn0 == NULL) {
pm0->next=pn;
head=pm;
}
}
return head;
}
void print(struct cell* head) {
struct cell*p;
p=head;
while(p!=NULL)
{
printf(" %d",p->x);
p=p->next;
}
}
void release(struct cell* head) {
struct cell*p;
while(head!=NULL)
{
p=head;
head=p->next;
free(p);
}
}
int main(void) {
struct cell* head;
int m, n;
head = build();
scanf("%d%d", &m, &n);
head = swap(head,m,n);
if(head!=NULL)
print(head);
else
printf("NULL");
release(head);
}
一直循环
调试时发现,79行带回后,head->next和head->next->next相同
这是为什么呢,谢谢