题目要求:
带头结点的单链表,头指针为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 LinkListInsert(LinkList h, int pos, DataType x)
{ // 在单链表的第pos个位置插入新开辟的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)
{ // 找到单链表的第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); // 某些编译器要求此处改为scanf_s
LinkListInsert(h, pos++, x);
} while ((ch = getchar()) != '\n');
scanf("%d", &N); // 某些编译器要求此处改为scanf_s
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 pTmp = a->next;
while (pTmp)
{
(*len)++;
pTmp = pTmp->next;
}
if (len < 2 || posN >= *len)
return 0;
PNode pCur = a->next;
PNode pPrior = a;
for (int i = 2; i <= posN; i++)
{
pCur = pCur->next;
pPrior = pPrior->next;
}
PNode pNext = pCur->next;
PNode pNextNext = pNext->next;
pPrior->next = pNext;
pNext->next = pCur;
pCur->next = pNextNext;
return 1;
}