• 【剑指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

    本文完。

  • 相关阅读:
    innerHTML和outerHTML的区别
    递归,汉诺塔
    js 中的 Math.ceil() Math.floor Math.round()
    JS中的异常exception
    CSS样式中visited,hover,active , focus这四个分别表示什么意思?
    用户在设置密码时,提醒请输入半角字符(vue+element+valid)
    设置用户密码时,将全角转换为半角
    后台返回对象数组,对象属性相同时,只取一个对象
    远程链接mongoDB robomongo
    mongodb 入坑
  • 原文地址:https://www.cnblogs.com/xfxu/p/4588337.html
Copyright © 2020-2023  润新知