#include "stdio.h" \x0d\x0a#include"malloc.h" typedef struct node \x0d\x0a{ \x0d\x0a int data\x0d\x0a struct node *next\x0d\x0a}linklink *creat(int n) //创建
链表 \x0d\x0a{ \x0d\x0a link *head,*p,*s\x0d\x0a int i\x0d\x0a p=head=(link *)malloc(sizeof(link))\x0d\x0a for(i=1idata)\x0d\x0a p->next=s\x0d\x0a p=s\x0d\x0a } \x0d\x0a p->next=NULL\x0d\x0a return head\x0d\x0a} void reverse(link *head)//原地置换 \x0d\x0a{ \x0d\x0a link *p,*s,*t\x0d\x0a p=head\x0d\x0a s=p->next\x0d\x0a while(s->next!=NULL)//主要置换过程 \x0d\x0a { \x0d\x0a t=s->next\x0d\x0a s->next=p\x0d\x0a p=s\x0d\x0a s=t\x0d\x0a } \x0d\x0a s->next=p\x0d\x0a head->next->next=NULL//收尾 \x0d\x0a head->next=s//赋头 \x0d\x0a} void display(link *head)//显示链表内容 \x0d\x0a{ \x0d\x0a link *p\x0d\x0a p=head->next\x0d\x0a while(p!=NULL) \x0d\x0a { \x0d\x0a printf("%d ",p->data)\x0d\x0a p=p->next\x0d\x0a } \x0d\x0a printf("\n")\x0d\x0a} void main() \x0d\x0a{ \x0d\x0a link *head\x0d\x0a head=creat(5)//创建一个5个节点的链表 \x0d\x0a printf("原链表:\n")\x0d\x0a display(head)\x0d\x0a reverse(head)\x0d\x0a printf("置换后链表:\n")\x0d\x0a display(head)\x0d\x0a}一、用
递归算法
对于不带头结点的单链表(a1,a2,a3,a4,a5,a6)逆置后的结果为(a6,a5,a4,a3,a2,a1)
考虑递归算法,若只有一个结点,则直接返回,若存在两个结点(a1,a2)则需要做的操作有:
a2->next=a1a1->next=NULLreturn a2
a2即新的头结点,若有三个结点,则应先将子链(a2,a3)先逆置且返回该子链的新的头结点,然后把子链(a2,a3)当作一个复合结点a2',组成新的二元组(a1,a2')然后就可以执行前面相同的操作:a2'->next=a1a1->next=NULLreturn a3'即可,多个以上的结点可同理得到,
Node *Reverse(Node *head)
{
Node *p=head
if(p==NULL)
return NULL //若是空链表,返回空
Node *q=p->next
if(q==NULL)
return p //若只有一个结点,直接返回
else
head=Reverse(q)//记录子序列的新的头结点
q->next=p //当前结点与已经逆置的子序列看成是前后的两个结点p,q,作相应的逆置操作
p->next=NULL
return head //返回新的子序列的头结点
}
二、用普通算法循环逆置(头插法重新建立带头结点的新链表)
参考链接:https://blog.csdn.net/onlyoncelove/article/details/81988514