输入两个递增排序的链表,合并这两个链表并使新链表中的结点按照递减排序

同学问到的简单的涉及单链表的问题,就当温习C语言语法了,希望面试可以用的上。

Sample:

list1: 1->3->6->9;

list2: 2->4->5->12->19;

result: 19->12->9->6->5->4->3->2->1;

使用C语言实现,因为最近练C++比较多,C语言查语法查哭了。

我的思路就是简单的做个归并,得到一个递增的新链表,然后再将链表反转,得到一个递减排序的链表;

这里单链表反序采用插头法实现,即每次将原链表的下一个节点作为新链表的链表头。因为C语言无法传引用,所以链表反序的函数应该返回一个指向新链表头的指针。

测试样例主要考虑的特殊情况就是某个链表长度为0

#include <stdio.h>
#include <malloc.h>

typedef struct ListNode //c结构体作为节点;
{
    int val;
    struct ListNode* next;
}ListNode;


ListNode* listMerge(ListNode* list1, ListNode* list2) //归并两个链表
{
    ListNode* list3 = (ListNode*)malloc(sizeof(ListNode));
    list3->val = 0;
    list3->next = NULL;
    ListNode* temp = list3;
    while (list1 != NULL || list2 != NULL){
        if (list1 == NULL || (list2 != NULL && list2->val <= list1->val)){ //链表1到头,或者链表2头结点元素小于链表1,插入链表1头结点
            temp->next = (ListNode*)malloc(sizeof(ListNode));
            temp = temp->next;
            temp->val = list2->val;
            temp->next = NULL;
            list2 = list2->next;
        }
        else if (list2 == NULL || (list1 != NULL && list1->val < list2->val)){ //同理
            temp->next = (ListNode*)malloc(sizeof(ListNode));
            temp = temp->next;
            temp->val = list1->val;
            temp->next = NULL;
            list1 = list1->next;
        }
    }
    temp = list3;
    list3 = list3->next;
    return list3;
}

//插头法
ListNode* reverseList(ListNode* list)
{
    ListNode* p = list->next; //原链表的下一个结点;
    ListNode* q = NULL; //每次从原链表上剥离下来的结点,也就是新链表的头结点;
    list->next = NULL;
    while (p != NULL){
        q = p;
        p = p->next;
        q->next = list;
        list = q;
    }
    return q;
}

main(void)
{
    ListNode* list1;
    ListNode* list2;
    ListNode* list3;
    ListNode* temp;
    list1 = (ListNode*)malloc(sizeof(ListNode));
    list2 = (ListNode*)malloc(sizeof(ListNode));
    list1->val = 0;
    list1->next = NULL;
    list2->val = 0;
    list2->next = NULL;

    int val;
    printf("Input list1 (ctrl+z to end):\n");
    temp = list1;
    while (scanf("%d", &val) != EOF){
        temp->next = (ListNode*)malloc(sizeof(ListNode));
        temp = temp->next;
        temp->val = val;
        temp->next = NULL;
    }
    temp = list1;
    list1 = list1->next;
    free(temp);

    printf("Input list2 (ctrl+z to end):\n");
    temp = list2;
    while (scanf("%d", &val) != EOF){
        temp->next = (ListNode*)malloc(sizeof(ListNode));
        temp = temp->next;
        temp->val = val;
        temp->next = NULL;
    }
    temp = list2;
    list2 = list2->next;
    free(temp);

    ListNode* listTemp = listMerge(list1, list2);
    list3 = reverseList(listTemp);
    temp = list3;
    printf("Result is: ");
    while (temp != NULL){
        printf("%d ", temp->val);
        temp = temp->next;
    }
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值