【面试题】两个有序链表的合并问题

题目描述:

给定两个无头有序单链表(都是从小到大的顺序排列),请合并为一个链表,使新链表也有序。

pHead1:-2、3、9、10
pHead2:2、5、9
pNewHead:-2、2、3、5、9、9、10


  • 题目分析:

这道题目很重点,所以分析会在代码注释中体现。
如果面试过程中被提问,要明确是带头单链表,还是不带头结点单链表。

方法一:递归写法
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<malloc.h>


typedef struct Node
{
    int data;
    struct Node *Next;
}Node, *pNode;



void InitNode(pNode pHead)     //初始化
{
    pHead = NULL;
}


void PrintNode(pNode pHead)    //打印
{
    while (pHead)
    {
        printf("%d -> " ,pHead->data);
        pHead = pHead->Next;
    }
    printf("NULL\n");
}


pNode BuyNewNode(int data)     //新建节点
{
    pNode temp = (pNode)malloc(sizeof(Node));
    if (temp)
    {
        temp->data = data;
        temp->Next = NULL;
    }
    return temp;
}


void PushFront(pNode *pHead, int data)
{
    pNode tempNode = NULL;
    assert(pHead);
    if (NULL == *pHead)
        *pHead = BuyNewNode(data);
    else
    {
        tempNode = BuyNewNode(data);
        tempNode->Next = *pHead;
        *pHead = tempNode;
    }
}



pNode TwoOrderList(pNode pList1, pNode pList2)
{
    pNode tempHead = NULL;
    if (pList1 == NULL)
        return pList2;
    if (pList2 == NULL)
        return pList1;
    if (pList1->data < pList2->data)
    {
        tempHead = pList1;
        tempHead->Next = TwoOrderList(pList1->Next, pList2);
    }
    else    //(pList1->data > pList2->data)
    {
        tempHead = pList2;
        tempHead->Next = TwoOrderList(pList1, pList2->Next);
    }
    return tempHead;
}


int main()
{
    pNode pHead1 = NULL;
    pNode pHead2 = NULL;
    pNode pNewHead = NULL;

    InitNode(pHead1);
    InitNode(pHead2);


    PushFront(&pHead1, 12);
    PushFront(&pHead1, 10);
    PushFront(&pHead1, 8);
    PushFront(&pHead1, 6);
    PushFront(&pHead1, 1);

    PushFront(&pHead2, 11);
    PushFront(&pHead2, 9);
    PushFront(&pHead2, 6);
    PushFront(&pHead2, 3);
    PushFront(&pHead2, -9);

    pNewHead = TwoOrderList(pHead1, pHead2);


    printf("Node1: ");
    PrintNode(pHead1);

    printf("\nNode2: ");
    PrintNode(pHead2);

    printf("\nNewNode: ");
    PrintNode(pNewHead);
    //



    return 0;

}
方法二:非递归写法
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<malloc.h>

typedef int DataType;

typedef struct Node
{
    DataType data;
    struct Node *_pNext;
}Node, *pNode;


void InitNode(pNode pHead)
{
    pHead = NULL;
}


pNode BuyNewNode(DataType data)
{
    pNode tempNode = NULL;
    tempNode = (pNode)malloc(sizeof(Node));
    if (tempNode)
    {
        tempNode->data = data;
        tempNode->_pNext = NULL;
    }
    return tempNode;
}


void PushFront(pNode *pHead, DataType data)
{
    assert(pHead);
    pNode tempNode = NULL;
    if (NULL == *pHead)
    {
        *pHead = BuyNewNode(data);
    }
    else
    {
        tempNode = BuyNewNode(data);
        tempNode->_pNext = *pHead;
        *pHead = tempNode;
    }
}


void printNode(pNode pHead)
{
    while (pHead)
    {
        printf("%d -> ", pHead->data);
        pHead = pHead->_pNext;
    }
    printf("NULL");
}

pNode TwoOrderListToOne(pNode pList1, pNode pList2)
{
    pNode pTail = NULL;
    pNode NewHead = NULL;

    if (pList1 == NULL)
        return pList2;
    else if (pList2 == NULL)
        return pList1;

    else
    {
        if (pList1->data < pList2->data)       //确定头
        {
            NewHead = pList1;
            pList1 = pList1->_pNext;        
        }
        else
        {
            NewHead = pList2;
            pList2 = pList2->_pNext;
        }

        pTail = NewHead;       //pTail保存头指针
        while (pList1 && pList2)
        {
            if (pList1->data <= pList2->data)
            {
                pTail->_pNext = pList1;
                pList1 = pList1->_pNext;    //指向链表的第二个结点
            }
            else
            {
                pTail->_pNext = pList2;
                pList2 = pList2->_pNext;
            } 
            pTail = pTail->_pNext;
        }
        if (NULL == pList1)
        {
            pTail->_pNext = pList2;
        }
        else if(NULL == pList2)
        {
            pTail->_pNext = pList1;
        }
        return NewHead;
    }
}

void test()
{
    pNode pHead1 = NULL;
    pNode pHead2 = NULL;
    pNode pNewHead = NULL;

    InitNode(pHead1);
    InitNode(pHead2);
    InitNode(pNewHead);

    PuhFront(&pHead1, 10);
    PushFront(&pHead1, 8);
    PushFront(&pHead1, 7);
    PushFront(&pHead1, -2);

    PushFront(&pHead2, 16);
    PushFront(&pHead2, 13);
    PushFront(&pHead2, 11);
    PushFront(&pHead2, 6);
    PushFront(&pHead2, -16);
    pNewHead = TwoOrderListToOne(pHead1, pHead2);

    printf("pHead1: ");
    printNode(pHead1);
    printf("\nPhead2: ");
    printNode(pHead2);
    printf("\npNewNode: ");
    printNode(pNewHead);
}

int main()
{
    test();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

askunix_hjh

谢谢请我吃糖~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值