单链表逆转
题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
画个图吧,假设存在单链表
A->B->C->D->E
如果不想任何指针,该如何如何定义之类的,那么翻转过程可以搞成如下:
| A->B->C->D->E | B->A->C->D->E | C->B->A->D->E | D->C->B->A->E | E->D->C->B->A
然后我们假设有三颗指针。分别为:
c:当前 n:下一个 l:上一个
这时候我们重新定义上面的执行过程,那么有:
A->B->C->D->E c l n | B->A->C->D->E c l n | C->B->A->D->E c l n | D->C->B->A->E | E->D->C->B->A
仔细观察上图,就知道如何翻转了。
还存在一种递归思路,思路参考到递归逆序打印单链表。。。比上面的循环好理解多了,不过时间复杂度没有减弱~只是一种炫技而已。
A->B->C->D->E A->B->C->D<-E (D->NULL) A->B->C<-D<-E (C->NULL) A->B<-C<-D<-E (B->NULL) A<-B<-C<-D<-E (A->NULL)
代码如下
#include <stdio.h> #include <stdlib.h> #include <utility> #include <vector> using namespace std; struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* CreateListNode(int value) { ListNode* pNode = new ListNode(); pNode->m_nValue = value; pNode->m_pNext = NULL; return pNode; } void PrintListNode(ListNode* pNode) { if(pNode == NULL) { printf("The node is NULL\n"); } else { printf("The key in node is %d.\n", pNode->m_nValue); } } void PrintList(ListNode* pHead) { printf("PrintList starts.\n"); ListNode* pNode = pHead; while(pNode != NULL) { printf("%d\t", pNode->m_nValue); pNode = pNode->m_pNext; } printf("\nPrintList ends.\n"); } void AddToTail(ListNode** pHead, int value) { ListNode* pNew = new ListNode(); pNew->m_nValue = value; pNew->m_pNext = NULL; if(*pHead == NULL) { *pHead = pNew; } else { ListNode* pNode = *pHead; while(pNode->m_pNext != NULL) pNode = pNode->m_pNext; pNode->m_pNext = pNew; } } void TurnOverList(ListNode* root) { vector<int> vec; //如果要求不用更改值的方式,那么就用map。。。 ListNode *p = root; while(p != NULL) { vec.push_back(p->m_nValue); p = p->m_pNext; } p = root; int vecSize = vec.size() - 1; for (int i = vecSize; i >= 0; --i) { p->m_nValue = vec[i]; p = p->m_pNext; } } // 递归翻转链表 // 不断将当前节点往后挪 void RTurnOverList(ListNode* p, ListNode* &new_root) { if (p == NULL) { return; } if (p->m_pNext == NULL) { new_root = p; return; } RTurnOverList(p->m_pNext, new_root); p->m_pNext->m_pNext = p; p->m_pNext=NULL; return; } ListNode* RTurnOverList(ListNode* root) { if (root->m_pNext == NULL) { return root; } ListNode* new_root = NULL; RTurnOverList(root, new_root); if (new_root != NULL) { return new_root; } return root; } int main() { ListNode *root = CreateListNode(10); AddToTail(&root, 9); AddToTail(&root, 8); AddToTail(&root, 7); AddToTail(&root, 6); AddToTail(&root, 5); PrintList(root); TurnOverList(root); PrintList(root); root = RTurnOverList(root); PrintList(root); }