链表逆置有很多方法,有一种是每一次都把指针移到最后一个元素,并把这个元素取下来,放在一个新链表的首部,到逆置结束,一共扫描链表n-1趟,显然,这一种是较为缓慢的。还有一种是从头节点开始就依次的改变指针的指向,从头到尾共扫描一遍链表,效率明显比上一种高。下面是这种方法的代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct Info
{
int data;
struct Info *next;
}Node,*pNode;
int main()
{
void create(pNode);
void reverse(pNode);
void print(pNode);
pNode link;
link=(pNode)malloc(sizeof(Node));
create(link);
reverse(link);
print(link);
return 0;
}
void create(pNode head)
{
int n=0;
pNode p,q;
p=q=(pNode)malloc(sizeof(Node));
scanf("%d",&p->data);
while(p->data!=0)
{
++n;
if(n==1)
head->next=p;
else
q->next=p;
q=p;
p=(pNode)malloc(sizeof(Node));
scanf("%d",&p->data);
}
q->next=NULL;
}
void reverse(pNode head)
{
pNode p0,p1,p2;
if(head->next==NULL&&head->next->next==NULL)/*当这个链表没有一个元素或者只有一个元素时,不用进行逆序操作*/
return;
p0=NULL;
p2=head->next;/*p2指向第一个元素*/
p1=head->next->next;/*p1指向第二个元素*/
while(p1!=NULL)
{
p2->next=p0;/*先把p1指向的元素和p2指向的元素之间的链断开,让p2指向元素的指针指向其前一个元素*/
p0=p2;/*以下三步完成了指针的一次后移,准备下一次循环*/
p2=p1;
p1=p1->next;
}
p2->next=p0;/*由于最后一次p1为空退出循环了,所以要再执行一次让p2指向元素的指针指向其前一个元素的操作*/
head->next=p2;/*改变头节点的指向*/
}
void print(pNode head)
{
pNode p=head->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
putchar(10);
}