题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。
struct ListNode
{
int data;
ListNode* next;
};
分析:首先这是一个单向链表的反转。其次反转后的链表的头变为尾,尾变为头。要实现此功能,就假设当前节点cur,前节点prev,下一个节点next.先看当前成员cur,它中的节点指针,要实现反序,只需要cur->next = prev.但这仅仅是完成了部分工作,往下就是怎么实现循环实现呢?
那就要把在执行cur->next = prev之前,把cur->next的成员保存下来,即tmp = cur->next;保存下一个节点的目的,是为了实现循环执行。再执行cur->next =prev.这样当前节点的操作已经完成。之后就是把当前节点变为前一节点,把下一个节点变为当前节点。即prev = cur, cur = tmp.再执行循环。
循环结束后,把实际的尾指针变为NULL,即head->next = NULL.把实际的头指针变为head。即head = prev;
代码:
ListNode *Rever(ListNode *head)
{
ListNode *prev, *cur, *next, *reverhead;
/*check memory NULL*/
if((head == NULL) || (head->next == NULL))
return 0;
/*get the link and it is prev from second*/
prev = head;
/*get cur link*/
cur = head->next;
/*loop change rever*/
while(cur != NULL)
{
/*save next point*/
next = cur->next;
if(next == NULL){
reverhead = cur;
}
/*change cur next point to prev*/
cur->next = prev;
/*change cur to prev*/
prev = cur;
/*change next to cur*/
cur = next;
}
/*change NULL for head that is tail now*/
head->next = NULL;
/*change the head location*/
head = prev;
return reverhead;
}
为了表达方便,用了四个ListNode,如果想更精炼,可以写成:
ListNode *Rever(ListNode *head)
{
ListNode *prev, *cur, *next;
/*check memory NULL*/
if((head == NULL) || (head->next == NULL))
return 0;
/*get the link and it is prev for second*/
prev = head;
/*get cur link*/
cur = head->next;
/*loop change rever*/
while(cur != NULL)
{
/*save next point*/
next = cur->next;
/*change cur next point to prev*/
cur->next = prev;
/*change cur to prev*/
prev = cur;
/*change next to cur*/
cur = next;
}
/*change NULL for head that is tail now*/
head->next = NULL;
/*change the head location*/
head = prev;
return prev;
}
另外还有一个算法就是递归:
node* reverse( node* pNode, node*& head)
{
if ( (pNode == 0) || (pNode->next == 0) ) // 递归跳出条件
{
head = pNode; // 将链表切断,否则会形成回环
return pNode;
}
node* temp = reserve(pNode->next, head);// 递归
temp->next = pNode;// 将下一节点置为当前节点,既前置节点
return pNode;// 返回当前节点
}
这个方法是采用了递归算法,也就是在反转当前节点之前先反转其后继节点,说白了其实就是利用函数的调用堆栈构建了一个临时链表罢了,挺废的一个算法,权当作是写着好玩,没有什么实在的意义。
采用此算法需要注意的是,头结点必须要传入的是引用,因为在递归跳出的时候要切断链表,否则链表将会形成一个回环。
递归算法是网上摘抄,看看即可。
在写程序时,最好不要用递归,想一想所谓的函数也是有入口地址,在运行的过程中,突然又跳到本身函数的入口地址。
你要有胆,你就用。我水平菜,我不敢用。