数据结构与算法——链表

C++算法之 合并两个有序链表

转自 http://blog.csdn.net/djb100316878/article/details/41745417

题目:合并两个已经排序好的链表(非递归和递归两种)

方法1:

  1. <span style="color:#000000;">// 合并链表.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8.   
  9. struct ListNode  
  10. {  
  11.     int         m_Data;  
  12.     ListNode*   m_pNext;  
  13.     ListNode(int value,ListNode* next = NULL):m_Data(value),m_pNext(next){}  
  14. };  
  15.   
  16.   
  17. ListNode* MergeList2(ListNode* head1,ListNode* head2)  
  18. {  
  19.     if (head1 == NULL)  
  20.     {  
  21.         return head2;  
  22.     }  
  23.     else if(head2 == NULL)  
  24.     {  
  25.         return head1;  
  26.     }  
  27.   
  28.     ListNode* MergeHead = NULL;  
  29.     if (head1->m_Data < head2->m_Data)  
  30.     {  
  31.         MergeHead = head1;  
  32.         head1 = head1->m_pNext;  
  33.     }  
  34.     else  
  35.     {  
  36.         MergeHead = head2;  
  37.         head2 = head2->m_pNext;  
  38.     }  
  39.     ListNode* tmpNode = MergeHead;  
  40.     while (head1&&head2)  
  41.     {  
  42.         if (head1->m_Data < head2->m_Data)  
  43.         {  
  44.             MergeHead->m_pNext = head1;  
  45.             head1 = head1->m_pNext;  
  46.         }  
  47.         else  
  48.         {  
  49.             MergeHead->m_pNext = head2;  
  50.             head2 = head2->m_pNext;  
  51.         }  
  52.         MergeHead = MergeHead->m_pNext;  
  53.     }  
  54.     if (head1)  
  55.     {  
  56.         MergeHead->m_pNext = head1;  
  57.     }  
  58.     if (head2)  
  59.     {  
  60.         MergeHead->m_pNext = head2;  
  61.     }  
  62.   
  63.     return tmpNode;  
  64.   
  65. }  
  66. int _tmain(int argc, _TCHAR* argv[])  
  67. {  
  68.     ListNode* pHead1 = new ListNode(1);  
  69.     ListNode* pCur = pHead1;  
  70.     for (int i = 3; i < 10; i+=2)  
  71.     {  
  72.         ListNode* tmpNode = new ListNode(i);  
  73.         pCur->m_pNext = tmpNode;  
  74.         pCur = tmpNode;  
  75.     }  
  76.   
  77.     ListNode* pHead2 = new ListNode(2);  
  78.     pCur = pHead2;  
  79.     for (int j = 4; j < 10; j+=2)  
  80.     {  
  81.         ListNode* tmpNode = new ListNode(j);  
  82.         pCur->m_pNext = tmpNode;  
  83.         pCur = tmpNode;  
  84.     }  
  85.   
  86.     ListNode* head = MergeList2(pHead1,pHead2);  
  87.     while (head)  
  88.     {  
  89.         cout<<head->m_Data<<" ";  
  90.         head=head->m_pNext;  
  91.     }  
  92.   
  93.   
  94.     getchar();  
  95.     return 0;  
  96. }</span>  


方法2:

/*

我们分析两个链表的过程,首先从合并两个链表的头结点开始,链表1的头节点的值小于链表2的头结点的值,因此链表1的头结点
就是合并链表的头节点,继续合并剩下的链表,在两个链表中剩余的节点仍然是排序的,因此合并两个链表的步骤是一样的,我们还是比较两个头结点的
值,此时链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点是合并剩余链表的头结点,我们把这个节点和前面合并链表时得到的链表的尾巴节点
链接起来

按照上面的分析可知:每次合并的步骤都是一样的,由此我们想到了递归。

*/

  1. // 合并链表.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8.   
  9. struct ListNode  
  10. {  
  11.     int         m_Data;  
  12.     ListNode*   m_pNext;  
  13.     ListNode(int value,ListNode* next = NULL):m_Data(value),m_pNext(next){}  
  14. };  
  15.  
  16.   
  17. ListNode* MergeList(ListNode* pHead1,ListNode* pHead2)  
  18. {  
  19.     if (pHead1 == NULL)  
  20.     {  
  21.         return pHead2;  
  22.     }  
  23.     else if (pHead2 == NULL)  
  24.     {  
  25.         return pHead1;  
  26.     }  
  27.   
  28.     ListNode* pMergeHead = NULL;  
  29.     if (pHead1->m_Data < pHead2->m_Data)  
  30.     {  
  31.         pMergeHead = pHead1;  
  32.         pMergeHead->m_pNext = MergeList(pHead1->m_pNext,pHead2);  
  33.   
  34.     }  
  35.     else  
  36.     {  
  37.         pMergeHead = pHead2;  
  38.         pMergeHead->m_pNext = MergeList(pHead1,pHead2->m_pNext);  
  39.     }  
  40.   
  41.     return pMergeHead;  
  42.   
  43. }  
  44.   
  45.   
  46. int _tmain(int argc, _TCHAR* argv[])  
  47. {  
  48.     ListNode* pHead1 = new ListNode(1);  
  49.     ListNode* pCur = pHead1;  
  50.     for (int i = 3; i < 10; i+=2)  
  51.     {  
  52.         ListNode* tmpNode = new ListNode(i);  
  53.         pCur->m_pNext = tmpNode;  
  54.         pCur = tmpNode;  
  55.     }  
  56.   
  57.     ListNode* pHead2 = new ListNode(2);  
  58.     pCur = pHead2;  
  59.     for (int j = 4; j < 10; j+=2)  
  60.     {  
  61.         ListNode* tmpNode = new ListNode(j);  
  62.         pCur->m_pNext = tmpNode;  
  63.         pCur = tmpNode;  
  64.     }  
  65.   
  66.     ListNode* head = MergeList2(pHead1,pHead2);  
  67.     while (head)  
  68.     {  
  69.         cout<<head->m_Data<<" ";  
  70.         head=head->m_pNext;  
  71.     }  
  72.   
  73.   
  74.     getchar();  
  75.     return 0;  


单向链表反转

转自http://www.cnblogs.com/wyqx/p/3346293.html

这次介绍经常在面试中被问到的单向链表的反转问题,问题的解决方法有多种

  1. 最普通的是从头到尾扫描链表,然后对链表进行反转。
  2. 使用单个参数的递归方法;使用单个参数是相当于不断的往链表后部深入,并且在每次深入的递归中保存了下一个节点和当前节点的信息,再调用递归后处理当前节点和下一个节点的关系;其中比较有特点的处理过程是返回值的处理,每次递归后返回的指针为同一个;
  3. 使用两个参数的递归方法,外加一个当前链表头节点的前一个结点的指针,在进一步递归之前处理好头节点和其前一个节点的关系。
复制代码
 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 }
复制代码


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
综合小区管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、车位管理、车位分配管理、出入管理、字典管理、房屋管理、物业费缴纳管理、公告管理、物业人员投诉管理、我的私信管理、物业人员管理、用户管理、管理员管理。用户的功能包括管理部门以及部门岗位信息,管理招聘信息,培训信息,薪资信息等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 综合小区管理系统管理系统可以提高综合小区管理系统信息管理问题的解决效率,优化综合小区管理系统信息处理流程,保证综合小区管理系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理综合小区管理系统信息,包括出入管理,报修管理,报修管理,物业费缴纳等,可以管理操作员。 出入管理界面,管理员在出入管理界面中可以对界面中显示,可以对招聘信息的招聘状态进行查看,可以添加新的招聘信息等。报修管理界面,管理员在报修管理界面中查看奖罚种类信息,奖罚描述信息,新增奖惩信息等。车位管理界面,管理员在车位管理界面中新增。公告管理界面,管理员在公告管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值