题目要求
带头结点的单链表,头指针为h,编写算法SwapN_inList( ),实现单链表中第n个结点和第n+1个结点相互交换,如果n为尾结点,需要向用户输出提示信息,代表交换失败,返回0,若交换成功返回1,并打印交换后的单链表。
单链表结点定义
定义如下:
typedef int DataType;
typedef struct Node
{
DataType data; // data域用于存储数据元素
struct Node *next; // next域用于存放指向其后继的指针
}LNode, *PNode, *LinkList; // LinkList为头指针
函数接口定义
函数接口如下:
int SwapN_inList( LinkList a , int posN , int *len);
其中 a ,posN , *len都是用户传入的参数。 a是单链表的头指针,posN代表需要进行交换的链点位置,*len是在遍历A链表时顺便记录A链表的长度。
测试程序样例
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node
{ DataType data;
struct Node *next;
}LNode, *PNode, *LinkList;
int InitLinkList(LinkList *head)
{
*head = (LinkList)malloc(sizeof(LNode));
if (!head)
{
printf("初始化链表错误!\n");
return 0;
}
(*head)->next = NULL;
return 1;
}
int LinkListLength(LinkList head)
{
int length = 0;
PNode p = head->next;
while (p)
{
length++;
p = p->next;
}
return length;
}
int LinkListEmpty(LinkList head)
{
if (head->next)
{
return 0;
}
else
{
return 1;
}
}
int LinkListInsert(LinkList h, int pos, DataType x)
{
PNode p = h, q;
int i = 0;
while (p && i < pos- 1)
{
p = p->next;
i++;
}
if (!p || i > pos - 1)
{
printf("插入位置不合法!\n");
return 0;
}
q = (PNode)malloc(sizeof(LNode));
if (!q)
{
printf("不能生成新结点\n");
return 0;
}
q->data = x;
q->next = p->next;
p->next = q;
return 1;
}
void DestroyLinkList(LinkList h)
{
PNode p = h->next;
while (h)
{
p = h;
h = h->next;
free(p);
}
}
void TraverseLinkList(LinkList h)
{
PNode p = h->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
PNode findN(LinkList a,int n)
{
int cnt = 1;
PNode p = a;
while( p && cnt++ <= n )
p = p->next;
return p;
}
int main()
{
LinkList h;
char ch;
PNode s1=NULL,s2=NULL,s3=NULL,s4=NULL;
DataType x,N;
int length = 0, pos = 1;
InitLinkList(&h);
do
{
scanf("%d",&x);
LinkListInsert( h , pos++ , x );
}while((ch=getchar())!='\n');
scanf("%d",&N);
s1 = findN(h,N);
if (s1)
{
s2 = s1->next;
}
if ( SwapN_inList( h , N , &length) == 1 )
{
s3 = findN(h,N);
if (s3)
{
s4 = findN(h,N+1);
}
if ( s1 == s4 && s2 == s3 )
{
printf("交换第%d个和第%d个链点位置后的单链表A是\n", N , N+1 );
TraverseLinkList( h );
}
}
else
{
printf("单链表A的第%d个结点为尾结点,没有下一个结点与之交换\n", length);
}
DestroyLinkList( h );
return 0;
}
输入样例
在这里给出一组输入。例如:
1 2 3 4 5 6 7 8 9
6
输出样例
在这里给出相应的输出。例如:
交换第6个和第7个链点位置后的单链表A是
1 2 3 4 5 7 6 8 9
答案
int SwapN_inList(LinkList a, int posN, int *len)
{
PNode pre = a;
PNode p = a->next;
PNode q;
PNode r;
int cnt = 1; //指针位置计数
while (p->next && cnt++ < posN)//跳出条件:指针到达链表尾/计数达到指定值
{
p = p->next; //指针p,pre双双后移
pre = pre->next;
}
if (p->next) //计数达到指定值,开始交换
{
q = p->next;
r = q->next; //交换点n后两位链点
//交换前顺序:pre-p-q-r
pre->next = q; //按照pre->q->p->r顺序排列
q->next = p;
p->next = r;
return 1;
}
else //指针抵达链表尾情况,将计数值作为链表长度值返回
{
*len = cnt;
return 0;
}
}
数据结构学习中,个人笔记,仅供参考
如有错误,烦请指正
参考视频: 【LinkList5-交换单链表第n和n加1个链点】