Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4
, you should return the list as 2->1->4->3
.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
题目就是将链表中的结点两两反转。
其实实现很简单,设置三个指针,q和m是要交换的结点指针,p是q的父节点,用来让父节点指针指向新的子节点m。
实现中要考虑输入head为空、只有一个结点这两种情况。然后只有两个结点的情况也要单独处理,因为这影响到了头结点指针的指向。我在实现时没有设置头结点,如果设置了头结点,就能将只有两个结点的情况,合并到后面的程序当中。
实现比较简单, 代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
void CreateList(LinkList *head,int n);
void SwapNodes(LinkList *head);
int IsTwo(LinkList head);
void PrintList(LinkList head);
void DestoryList(LinkList *head);
int main()
{
LinkList head = NULL;
int n;
while(scanf("%d",&n) != EOF){
CreateList(&head,n);
PrintList(head);
SwapNodes(&head);
PrintList(head);
DestoryList(&head);
}
return 0;
}
void CreateList(LinkList *head,int n)
{
int data;
for(int i = 0;i < n;++i){
LinkList p = (LinkList)malloc(sizeof(LNode));
if(!p){
printf("malloc error!\n");
exit(1);
}
scanf("%d",&data);
p->data = data;
p->next = (*head);
*head = p;
}
}
void SwapNodes(LinkList *head)
{
LinkList p,q,m;
if(*head == NULL){
printf("NULL!\n");
return ;
}
if((*head)->next == NULL)
return ;
p = (*head)->next; //处理头指针情况,如果设置头结点,就不用这么麻烦了
q = p->next;
(*head)->next = q;
p->next = *head;
*head = p;
p = (*head)->next;
while(IsTwo(p)){
q = p->next;
m = q->next;
q->next = m->next;
m->next = q;
p->next = m;
p = q;
}
}
int IsTwo(LinkList head)
{
if(head->next == NULL || head->next->next == NULL)
return 0;
return 1;
}
void PrintList(LinkList head)
{
LinkList p = head;
while(p){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
void DestoryList(LinkList *head)
{
if(*head == NULL)
return ;
LinkList p = *head;
*head = NULL;
while(p){
LinkList q = p->next;
free(p);
p = q;
}
}