对问题的分析:
对于带头结点的点链表,逆置其中最核心的步骤就是对链表就行头插法。
第一步:先定义两个指针(pCur 和 pNext),同时指向第一个元素的地址;
第二步:使头结点和第一个元素断开链接(Phead->pnext=NULL)
第三步: (1): 先把开始定义的指针pNext移到下一个元素节点
(2):把第一个元素直接链到头结点
(3): 把pNext的值赋给pCur->pnext。
(4):重复(1);
(5):要把第二个元素插到第一个元素前面,那么pCur->pnext = phead->pnext;(先断开第二个元素和第三个元素的链接,使第二个元素保存第一个元素的地址)
(6):把第二个元素的地址给pheda->pnext=pCur,把头结点的与第二个元素链接,断开头结点与第一个元素的链接。
# include<stdio.h>
# include<stdlib.h>
#include<assert.h>
typedef int ELEM_TYPE;
typedef struct Node
{
ELEM_TYPE mdata;
struct Node* pnext;
}Node, *Link;
void Init(Link phead)
{
assert(phead != NULL);
if (phead == NULL)
{
return;
}
phead->pnext = NULL;
}
static Link BuyNode()
{
struct Node* pnewnode = (struct Node*)malloc(sizeof(struct Node));
assert(pnewnode != NULL);
pnewnode->pnext = NULL;
return pnewnode;
}
bool InsertTail(Link phead, ELEM_TYPE val)
{
if (phead == NULL)
{
return false;
}
struct Node* pCur = phead;
while (pCur->pnext != NULL)
{
pCur = pCur->pnext;
}
struct Node* pnewnode = BuyNode();
pnewnode->mdata = val;
pCur->pnext = pnewnode;
return true;
}
void Reverse(Link phead)
{
if (phead == NULL)
{
return;
}
Node* pCur = phead->pnext;//NULL
Node* pNext = pCur;
phead->pnext = NULL;
while (pCur != NULL)
{
pNext = pCur->pnext;
pCur->pnext = phead->pnext;
phead->pnext = pCur;
pCur = pNext;
}
}
void Print(Link phead)
{
if (phead == NULL)
{
return;
}
struct Node* pCur = phead->pnext;
while (pCur != NULL)
{
printf("%d ", pCur->mdata);
pCur = pCur->pnext;
}
printf("\n");
}
int main()
{
Node head;
Init(&head);
for (int i = 0; i < 10; ++i)
{
InsertTail(&head, i + 1);
}
printf("逆置前:");
Print(&head);
printf("逆置后:");
Reverse(&head);
Print(&head);
return 0;
}
运行结果为: