递归和非递归实现链表反转
链表反转是面试笔试常考题目,直接贴代码。
反转函数如下:
//思路为将节点从前到后依次放到表头,最后最后的节点到了最前面,最前面的节点到了最后面 ListNode * ReverseList(ListNode * head) { //如果链表为空或者链表中只有一个元素 if(head==NULL || head->m_pNext==NULL) return head; ListNode * p=head->m_pNext; ListNode * q=head; while(p!=NULL) { q->m_pNext=p->m_pNext;//记录下p的下一个节点 p->m_pNext=head; head=p; p=q->m_pNext;//准备将p的下一个节点放到表头 } return head; } //递归方式 ListNode * ReverseList2(ListNode * head) { //如果链表为空或者链表中只有一个元素 if(head==NULL || head->m_pNext==NULL) return head; else { ListNode * newhead=ReverseList2(head->m_pNext);//先反转后面的链表 head->m_pNext->m_pNext=head;//再将当前节点设置为其然来后面节点的后续节点 head->m_pNext=NULL; return newhead; } }
整体测试代码如下:
// 反转链表.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> using namespace std; //定义一个链表节点 typedef struct ListNode { int m_nKey; struct ListNode * m_pNext; }ListNode; //插入一个新节点到链表中(放在链表头部) void CreateList(ListNode * & head,int data) { //创建新节点 ListNode * p=(ListNode*)malloc(sizeof(ListNode)); p->m_nKey=data; p->m_pNext=NULL; if(head==NULL) { head=p; return; } p->m_pNext=head; head=p; } void printList(ListNode* head) { ListNode * p=head; while(p!=NULL) { cout<<p->m_nKey<<" "; p=p->m_pNext; } cout<<endl; } //思路为将节点从前到后依次放到表头,最后最后的节点到了最前面,最前面的节点到了最后面 ListNode * ReverseList(ListNode * head) { //如果链表为空或者链表中只有一个元素 if(head==NULL || head->m_pNext==NULL) return head; ListNode * p=head->m_pNext; ListNode * q=head; while(p!=NULL) { q->m_pNext=p->m_pNext;//记录下p的下一个节点 p->m_pNext=head; head=p; p=q->m_pNext;//准备将p的下一个节点放到表头 } return head; } //递归方式 ListNode * ReverseList2(ListNode * head) { //如果链表为空或者链表中只有一个元素 if(head==NULL || head->m_pNext==NULL) return head; else { ListNode * newhead=ReverseList2(head->m_pNext);//先反转后面的链表 head->m_pNext->m_pNext=head;//再将当前节点设置为其然来后面节点的后续节点 head->m_pNext=NULL; return newhead; } } int _tmain(int argc, _TCHAR* argv[]) { ListNode * Head=NULL; for(int i=0;i<10;i++) CreateList(Head,i); printList(Head); Head=ReverseList(Head); printList(Head); system("PAUSE"); return 0; }
运行结果如下: