首先我们需要知道的是逆置单链表不是逆序打印单链表,逆置单链表改变了原链表!!!
逆置单链表的两种方法:头删+头插;3个指针
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef int DataType;
typedef struct SListNode
{
DataType data;
struct SListNode *pNext;
} SListNode;
//打印函数
void SListNodePrint(SListNode **ppfirst)
{
SListNode *pNode;
for (pNode = *ppfirst; pNode != NULL; pNode = pNode->pNext)
{
printf("%d -> ", pNode->data);
}
printf("NULL\n");
}
- 头删+头插
思路:逆置单链表就是要把第一个结点逆置成最后一个非空结点,把最后一个非空结点逆置成第一个结点。所以当我们拿到一个单链表的时候从头一个一个拿出结点(头删)再利用头插的方法将后取出来的结点放在先取出来的结点的前面,直到原来的链表再无结点为止。
//逆置单链表(头删+头插)
SListNode * ReverseList(SListNode *pFirst)
{
SListNode *pCur = NULL;
SListNode *pNode = NULL;
if (NULL == pFirst)
return NULL;
while (NULL != pFirst)
{
//头删
pCur = pFirst;
pFirst = pCur->pNext;
//头插
pCur->pNext = pNode;
pNode = pCur;
}
return pNode;
}
- 3个指针
思路:既然要实现单链表的逆置,那么我们可以定义三个指针,第一个指针初始化为空指针,第二个指针初始化为第一个结点,第三个指针初始化为第一个结点的下一个结点。在第二个指针不为空的时候,先改变第二个指针的指向,让其指向第一个指针,在第三个指针不为空的情况下,再整体往后挪一个位置,最后所得的第一个指针即为逆置后单链表的第一个结点。
//逆置单链表(3个指针)
SListNode * ReverseList(SListNode *pFirst)
{
SListNode *p1 = NULL;
SListNode *p2 = pFirst;
SListNode *p3 = pFirst->pNext;
if (NULL == pFirst)
return NULL;
while (p2 != NULL)
{
p2->pNext = p1;
p1 = p2;
p2 = p3;
if (p3 != NULL)
{
p3 = p3->pNext;
}
}
return p1;
}