C++算法之 合并两个有序链表
转自 http://blog.csdn.net/djb100316878/article/details/41745417
题目:合并两个已经排序好的链表(非递归和递归两种)
方法1:
- <span style="color:#000000;">// 合并链表.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- struct ListNode
- {
- int m_Data;
- ListNode* m_pNext;
- ListNode(int value,ListNode* next = NULL):m_Data(value),m_pNext(next){}
- };
- ListNode* MergeList2(ListNode* head1,ListNode* head2)
- {
- if (head1 == NULL)
- {
- return head2;
- }
- else if(head2 == NULL)
- {
- return head1;
- }
- ListNode* MergeHead = NULL;
- if (head1->m_Data < head2->m_Data)
- {
- MergeHead = head1;
- head1 = head1->m_pNext;
- }
- else
- {
- MergeHead = head2;
- head2 = head2->m_pNext;
- }
- ListNode* tmpNode = MergeHead;
- while (head1&&head2)
- {
- if (head1->m_Data < head2->m_Data)
- {
- MergeHead->m_pNext = head1;
- head1 = head1->m_pNext;
- }
- else
- {
- MergeHead->m_pNext = head2;
- head2 = head2->m_pNext;
- }
- MergeHead = MergeHead->m_pNext;
- }
- if (head1)
- {
- MergeHead->m_pNext = head1;
- }
- if (head2)
- {
- MergeHead->m_pNext = head2;
- }
- return tmpNode;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- ListNode* pHead1 = new ListNode(1);
- ListNode* pCur = pHead1;
- for (int i = 3; i < 10; i+=2)
- {
- ListNode* tmpNode = new ListNode(i);
- pCur->m_pNext = tmpNode;
- pCur = tmpNode;
- }
- ListNode* pHead2 = new ListNode(2);
- pCur = pHead2;
- for (int j = 4; j < 10; j+=2)
- {
- ListNode* tmpNode = new ListNode(j);
- pCur->m_pNext = tmpNode;
- pCur = tmpNode;
- }
- ListNode* head = MergeList2(pHead1,pHead2);
- while (head)
- {
- cout<<head->m_Data<<" ";
- head=head->m_pNext;
- }
- getchar();
- return 0;
- }</span>
方法2:
/*
我们分析两个链表的过程,首先从合并两个链表的头结点开始,链表1的头节点的值小于链表2的头结点的值,因此链表1的头结点
就是合并链表的头节点,继续合并剩下的链表,在两个链表中剩余的节点仍然是排序的,因此合并两个链表的步骤是一样的,我们还是比较两个头结点的
值,此时链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点是合并剩余链表的头结点,我们把这个节点和前面合并链表时得到的链表的尾巴节点
链接起来
按照上面的分析可知:每次合并的步骤都是一样的,由此我们想到了递归。
*/
- // 合并链表.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- struct ListNode
- {
- int m_Data;
- ListNode* m_pNext;
- ListNode(int value,ListNode* next = NULL):m_Data(value),m_pNext(next){}
- };
-
- ListNode* MergeList(ListNode* pHead1,ListNode* pHead2)
- {
- if (pHead1 == NULL)
- {
- return pHead2;
- }
- else if (pHead2 == NULL)
- {
- return pHead1;
- }
- ListNode* pMergeHead = NULL;
- if (pHead1->m_Data < pHead2->m_Data)
- {
- pMergeHead = pHead1;
- pMergeHead->m_pNext = MergeList(pHead1->m_pNext,pHead2);
- }
- else
- {
- pMergeHead = pHead2;
- pMergeHead->m_pNext = MergeList(pHead1,pHead2->m_pNext);
- }
- return pMergeHead;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- ListNode* pHead1 = new ListNode(1);
- ListNode* pCur = pHead1;
- for (int i = 3; i < 10; i+=2)
- {
- ListNode* tmpNode = new ListNode(i);
- pCur->m_pNext = tmpNode;
- pCur = tmpNode;
- }
- ListNode* pHead2 = new ListNode(2);
- pCur = pHead2;
- for (int j = 4; j < 10; j+=2)
- {
- ListNode* tmpNode = new ListNode(j);
- pCur->m_pNext = tmpNode;
- pCur = tmpNode;
- }
- ListNode* head = MergeList2(pHead1,pHead2);
- while (head)
- {
- cout<<head->m_Data<<" ";
- head=head->m_pNext;
- }
- getchar();
- return 0;
- }
单向链表反转
转自http://www.cnblogs.com/wyqx/p/3346293.html
这次介绍经常在面试中被问到的单向链表的反转问题,问题的解决方法有多种
- 最普通的是从头到尾扫描链表,然后对链表进行反转。
- 使用单个参数的递归方法;使用单个参数是相当于不断的往链表后部深入,并且在每次深入的递归中保存了下一个节点和当前节点的信息,再调用递归后处理当前节点和下一个节点的关系;其中比较有特点的处理过程是返回值的处理,每次递归后返回的指针为同一个;
- 使用两个参数的递归方法,外加一个当前链表头节点的前一个结点的指针,在进一步递归之前处理好头节点和其前一个节点的关系。
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 struct Node{ 5 int value; 6 Node* next; 7 }; 8 9 //使用非递归的链表反转方法 //赋初值,留后手,做反转,向前走,返新头。 10 Node* ReverseList1(Node *Ptr) 11 { 12 Node *pre = NULL; 13 Node *Current = Ptr; 14 Node *pnext = NULL; 15 while ( Current != NULL){ 16 pnext = Current->next; 17 Current->next = pre; 18 pre = Current; 19 Current = pnext; 20 } 21 return pre; 22 } 23 // 一个参数的递归反转方法 24 // 将当前节点的下一个节点保存好,并将当前节点从链表中取出,再递归处理以后的链表 25 // 同时reverseRest没有改变,一直保存了链表的最后一个节点的指针 26 Node* ReverseList2(Node *ptr){ 27 if (ptr->next == NULL) 28 return ptr; 29 Node *nextNode = ptr-> next; 30 ptr->next = NULL; 31 Node *reverseRest = ReverseList2(nextNode); 32 nextNode->next = ptr; 33 return reverseRest; 34 35 36 } 37 38 // 递归实现2:两个参数的递归调用方法 39 // 传递一个当前链表头节点的前一个节点的指针,在函数中将当前头节点的next改为其前一个节点,并递归调用 40 Node* ReverseList3(Node *ptr, Node *pre){ 41 if (ptr->next == NULL){ 42 ptr->next = pre; 43 return ptr; 44 } 45 else{ 46 Node *next = ptr->next; 47 ptr->next = pre; 48 ReverseList3(next, ptr); 49 } 50 } 51 52 53 void printList(Node *Ptr){ 54 Node * Current = Ptr; 55 while (Current != NULL){ 56 cout << Current->value << " "; 57 Current = Current->next; 58 } 59 cout << endl; 60 } 61 62 int main(){ 63 Node *head = NULL; 64 65 for (int i = 9; i > 0; i--){ 66 Node *p = new Node; 67 p->next = head; 68 p->value = i; 69 head = p; 70 } 71 cout << "The Lsit:" << endl; 72 printList(head); 73 74 head = ReverseList1(head); 75 cout << "After reverseList1():" << endl; 76 printList(head); 77 78 79 head = ReverseList2(head); 80 cout << "After reverseList2():" << endl; 81 printList(head); 82 83 Node * tmp = NULL; 84 head = ReverseList3(head, tmp); 85 cout << "After reverseList3():" << endl; 86 printList(head); 87 88 return 1; 89 90 }