给定一个链表的头指针,要求只遍历一次,将单链表中的元素的顺序翻转过来

时间:2022-10-08 11:01:03

Beauty of Programming..

#include <stdlib.h>
#include <assert.h>
#include <iostream.h>
struct ListNode
{
int data;
ListNode* next;
};
void InitList(ListNode** head)
{
*head = (ListNode*)malloc(sizeof(ListNode));
(*head)->next = NULL;
}
void InsertList(ListNode* head,int d)
{
assert(head!=NULL);
ListNode* pNewNode = (ListNode*)malloc(sizeof(ListNode));
pNewNode->data = d;
pNewNode->next = head->next;
head->next = pNewNode;
}
void PrintList(ListNode* head)
{
if(head == NULL)
{
return ;
}
ListNode* Next = head->next;
while(Next!=NULL)
{
cout<<Next->data<<endl;
Next = Next->next;
}
}
/*
反转链表核心算法
用了几个临时变量,然后遍历整个链表,将当前节点的下一节点置为前节点。
我们需要在调整pCurr的next指针之前先将pNext节点保存下来。
反转后的头节点就是原来的尾节点
*/
ListNode* ReverseList(ListNode* head)
{
ListNode* pReverseHead = NULL;
ListNode* pCurr = head->next;
ListNode* pNext = NULL;
ListNode* pPre = NULL;
while(pCurr!=NULL)
{
pNext = pCurr->next;//保存下一个节点
//如果下一个节点为空,那么当前节点pNode就是反转后的头指针了
if(pNext==NULL)
{
pReverseHead = pCurr;
}
pCurr->next = pPre;//将当前节点的下一节点置为前节点
//移动两个指针
pPre = pCurr;//将当前指针作为前一个节点
pCurr = pNext;//将下一个指针作为当前节点
}
//添加头指针
ListNode* pNewHead = (ListNode*)malloc(sizeof(ListNode));
pNewHead->next=pReverseHead;
return pNewHead;
}
int main()
{

ListNode* pListHead = NULL;
InitList(&pListHead);
for(int i=9;i>=0;i--)
{
InsertList(pListHead,i);
}

cout<<"链表反转之前:"<<endl;
PrintList(pListHead);

ListNode* pRHead = ReverseList(pListHead);
cout<<"链表反转之后:"<<endl;
PrintList(pRHead);
return 0;
}