链表的结点定义如下
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *p_LNode;
我们先来看看递归算法,看图会比较直观。
我们从最后一个结点开始往前看,发现其实每一个步骤前一个结点的next值为空,后一个结点的next指向了preNode的指向的地址。其实这是将最后一个结点next(为NULL)依次给了前一个结点的next,后一个结点next指向前一个结点。当前一个结点为链表的第一个结点时,第一个结点就成了倒置后链表的最后一个结点,next必然为空,此时倒置就完成了。
于是我们可以推出以下公式。
preNode->next->next == NULL时开始从后往前依次交换结点的next的值
!= NULL 时,继续寻找到最后两个结点
即如下的代码
void ReverseLinkList(p_LNode preNode){ // 只适用两个以上结点的单链表
if(preNode->next->next)
ReverseLinkList(preNode->next); // 目的是寻找到最后一个结点的前一个结点
// 开始修改两个结点的next
preNode->next->next = preNode;
preNode->next = NULL;
}
代码很简短,但是找不出头结点的位置了。所以使用的时候需要事先记录下最后一个结点的位置。如果你感兴趣的话还可以改进一下,不必事先记录最后一个结点位置。