zoukankan      html  css  js  c++  java
  • 【剑指offer】面试题17、合并两个排序的链表

    题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图中的链表 1 和链表 2,则合并之后的升序链表如链表 3 所示。链表结点定义如下:
    typedef struct Node
    {
        int m_nValue;
        struct Node *m_pNext;
    }ListNode;

     一、创建有序链表

    创建有序链表的一般步骤:
    1、初始化链表为空;
    2、生成新的结点指针 pNew;
    3、找到该结点值对应的位置,有两种可能:头部,非头部;
    4、插入该结点。

    假设一链表L现在两个结点,结点值分别为 3、5,现在欲插入的结点值分别为 4,7:

    1、现在我们欲插入值为 4 的结点pNew,遍历指针为 pNode,初始值指向值为 3 的头结点pHead;

    2、遍历原有链表 L 时,发现 4 > 3,于是 pNode 变为指向值为5的结点pTail;

    3、继续比较,由于5 > 4,因此值为 5 的结点的位置就是我们要找的位置;

    4、执行插入操作;

    注意:在插入的过程中,由于需要连接链表,需要把pNode的前一个链表结点保存下来。

    代码如下:

     1 void createOrderedList(ListNode **pHead, int len)
     2 {
     3     while(len--)
     4     {
     5         ListNode *pNew = (ListNode*)malloc(sizeof(ListNode));
     6         pNew->m_nValue = rand()%100;
     7         pNew->m_pNext = NULL;
     8 
     9         if(*pHead == NULL) //
    10             *pHead = pNew;
    11         else //非空
    12         {
    13             ListNode *pNode = *pHead;
    14             ListNode *pPre = NULL;
    15             while(pNode != NULL)
    16             {
    17                 if(pNode->m_nValue < pNew->m_nValue)
    18                 {
    19                     pPre = pNode;
    20                     pNode = pNode->m_pNext;
    21                 }
    22                 else
    23                     break;
    24             }
    25             // 插入的位置
    26             if(pPre == NULL) // 头结点位置
    27             {
    28                 pNew->m_pNext = *pHead;
    29                 *pHead = pNew;
    30             }
    31             else // 其他位置
    32             {
    33                 pNew->m_pNext = pNode; // 连接链表
    34                 pPre->m_pNext = pNew;
    35             }
    36         }
    37     }
    38 }
    View Code

    二、两个有序链表的合并(顺序从小到大依次排列)

    思路:设有 X 和 Y两个链表;

    1、分别遍历 X和Y这两个链表;

    2、若 Px 的结点值小于 Py 的结点值,则将结点 Px 结点放入到 合并之后的链表中;否则,执行3;

    3、将结点 Px 结点放入到 合并之后的链表中;

    4、若while循环中 Px==NULL,则说明链表Px已空,这时,直接将Py的后续结点加入到链表中即可;

    5、反之, 若while循环中 Py==NULL,则说明链表Py已空,这时,直接将Px的后续结点加入到链表中即可。

     完整的代码如下:

      1 #include "stdio.h"
      2 #include "stdlib.h"
      3 #include "time.h"
      4 
      5 #define N 10
      6 
      7 typedef struct Node
      8 {
      9     int m_nValue;
     10     struct Node *m_pNext;
     11 }ListNode, *pListNode;
     12 
     13 // 创建有序链表
     14 void createOrderedList(ListNode **pHead, int len)
     15 {
     16     while(len--)
     17     {
     18         ListNode *pNew = (ListNode*)malloc(sizeof(ListNode));
     19         pNew->m_nValue = rand()%100;
     20         pNew->m_pNext = NULL;
     21 
     22         if(*pHead == NULL) //
     23             *pHead = pNew;
     24         else //非空
     25         {
     26             ListNode *pNode = *pHead;
     27             ListNode *pPre = NULL;
     28             while(pNode != NULL)
     29             {
     30                 if(pNode->m_nValue < pNew->m_nValue)
     31                 {
     32                     pPre = pNode;
     33                     pNode = pNode->m_pNext;
     34                 }
     35                 else
     36                     break;
     37             }
     38             // 插入的位置
     39             if(pPre == NULL) // 头结点位置
     40             {
     41                 pNew->m_pNext = *pHead;
     42                 *pHead = pNew;
     43             }
     44             else // 其他位置
     45             {
     46                 pNew->m_pNext = pNode;
     47                 pPre->m_pNext = pNew;
     48             }
     49         }
     50     }
     51 }
     52 
     53 void printList(ListNode *pHead)
     54 {
     55     while(pHead != NULL)
     56     {
     57         printf("%3d ", pHead->m_nValue);
     58         pHead = pHead->m_pNext;
     59     }
     60     printf("
    ");
     61 }
     62 
     63 // 合并有序链表
     64 ListNode *Merge(ListNode *leftHead, ListNode *rightHead)
     65 {
     66     if(!leftHead)
     67         return rightHead;
     68     else if(!rightHead)
     69         return leftHead;
     70 
     71     ListNode *mergeHead, *mergeTail;
     72     mergeHead = mergeTail = NULL;
     73     ListNode *pLeft = leftHead;
     74     ListNode *pRight = rightHead;
     75     while(pLeft != NULL && pRight != NULL)
     76     {
     77         if(pLeft->m_nValue < pRight->m_nValue) // 左链表结点值比右链表结点值大
     78         {
     79             if(mergeHead == NULL) // 头结点
     80             {
     81                 mergeHead = mergeTail = pLeft;
     82             }
     83             else // 非头结点
     84             {
     85                 mergeTail->m_pNext = pLeft;
     86                 mergeTail = pLeft;
     87             }
     88             pLeft = pLeft->m_pNext;
     89         }
     90         else// 右链表结点值比左链表结点值大
     91         {
     92             if(mergeHead == NULL) // 头结点
     93             {
     94                 mergeHead = mergeTail = pRight;
     95             }
     96             else // 非头结点
     97             {
     98                 mergeTail->m_pNext = pRight;
     99                 mergeTail = pRight;
    100             }
    101             pRight = pRight->m_pNext;
    102         }
    103 
    104     }
    105 
    106     if(pLeft != NULL)
    107         mergeTail->m_pNext = pLeft;
    108     if(pRight != NULL)
    109         mergeTail->m_pNext = pRight;
    110 
    111     return mergeHead;
    112 }
    113 
    114 int main(int argc, char const *argv[])
    115 {
    116     srand(time(NULL));
    117 
    118     ListNode *pHead1 = NULL;
    119     ListNode *pHead2 = NULL;
    120 
    121     createOrderedList(&pHead1, N);
    122     printf("List1: ");
    123     printList(pHead1);
    124 
    125     createOrderedList(&pHead2, N);
    126     printf("List2: ");
    127     printList(pHead2);
    128 
    129     ListNode *pMergeHead = Merge(pHead1, pHead2);
    130     if(pMergeHead != NULL)
    131     {
    132         printf("The Merge Node: %d
    ", pMergeHead->m_nValue);
    133     }
    134     printf("MergedList: ");
    135     printList(pMergeHead);
    136 
    137     return 0;
    138 }
    View Code

    本文完。

  • 相关阅读:
    虚函数和纯虚函数
    MS CRM 2011中PartyList类型字段的实例化
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(4)
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(2)
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第二部分)——IOrganizationService(二)
    MS CRM 2011 SDK 5.08已经发布
    MS CRM 2011 Q2的一些更新
    最近很忙
    Microsoft Dynamics CRM 2011最近的一些更新
    补一篇,Update Rollup 12 终于发布了
  • 原文地址:https://www.cnblogs.com/xfxu/p/4588337.html
Copyright © 2011-2022 走看看