首先来介绍一下什么叫做就地逆序。单链表的就地逆序指不需要另外建立头结点,仅用大小为O(1)的辅助空间来完成单链表的逆序。从这个要求看来似乎是很复杂的,但实际上并没有想象中的复杂。
我们先试着完成下图除头结点外仅有两个结点的单链表的逆序。要完成它的逆序只需要让头指针的指针域指向a2所在结点,a2所在结点的指针域指向a1所在结点,但由于头指针是无法移动的,所以容易想到建立两个辅助指针p和q,来帮助完成逆序这一操作。
我们让指针p遍历整个单链表(p=p->next),让指针q指向p,并且指向的结点作为逆序后的链表的结点。
首先我们让链表为空(head->next=NULL),在这时我们只需要将a1和a2分别用头插法的方式链接起来,链表的逆序也就完成了。
因为实际生活中的链表肯定不止两个结点,所以完成这一过程需要利用循环体按照上述操作来完成,不管a2后面有多少个a3、a4……它们也是依次按照头插法的方法被链接起来,而进行循环的条件便是p!=NULL。
部分代码如下:
linklist p, q; //linklist为已定义好的单链表结构体,head为主函数中已分配内存空间的头指针。
p = head->next;
head->next = NULL;
while (p != NULL)
{
q = (linklist)malloc(sizeof(node));
q = p;
p = p->next;
q->next = head->next;
head->next = q;
}