• 02-线性结构1 两个有序链表序列的合并


    本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。

    函数接口定义:

    List Merge( List L1, List L2 );
    

    其中List结构定义如下:

    typedef struct Node *PtrToNode;
    struct Node {
        ElementType Data; /* 存储结点数据 */
        PtrToNode   Next; /* 指向下一个结点的指针 */
    };
    typedef PtrToNode List; /* 定义单链表类型 */
    

    L1L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的链表头指针。

    本题自己测试了一上午了吧,在VS2013下是可以通过的,但是提交只是部分正确。

    /*!
     * file 02-线性结构1 两个有序链表序列的合并.cpp
     *
     * author ranjiewen
     * date 2017/03/12 20:23
     *
     * 
     */
    
    #include<stdio.h>
    #include <stdlib.h>
    
    typedef int ElementType;
    typedef struct Node *PtrToNode;
    struct Node
    {
        ElementType Data;
        PtrToNode Next;
    }Node;
    
    typedef PtrToNode List;  //定义单链表类型
    
    List Read()
    {
        printf("请输入一个链表的元素个数:
    ");
        int n = 0;
        scanf("%d", &n);
    
        List pHead = (List)malloc(sizeof(Node));
        List pCur = pHead;
        pCur->Next = NULL;
        if (pHead == NULL)
        {
            printf("pHead malloc faied!");
            exit(-1);
        }
    
        printf("请依次输入元素:
    ");
        int i, data = 0;
        for (i = 0; i < n; i++)
        {
            scanf("%d", &data);
            List pNode = (List)malloc(sizeof(Node));
            pNode->Data = data;
            pNode->Next = NULL;
            pCur->Next = pNode;
            //pCur++; 错误写法
            pCur = pNode; //移动当前节点到下一位置
        }
        return pHead;
    }
    void Print(List L) //空链表时输出null
    {
        List pCur = L->Next;
        if (pCur == NULL)
        {
            printf("NULL");
        }
        while (pCur != NULL)//
        {
            printf("%d ", pCur->Data);
            pCur = pCur->Next;
        }
    }
    
    //L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;
    //函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的链表头指针。
    List Merge(List L1, List L2);
    List Merge_(List L1, List L2);
    int main()
    {
        List L1, L2, L;
        L1 = Read();
        L2 = Read();
        L = Merge(L1, L2);
        Print(L);
        printf("
    ");
        L1->Next = NULL;
        L2->Next = NULL;
        Print(L1);
        printf("
    ");
        Print(L2);
        printf("
    ");
        return 0;
    }
    
    List Merge(List L1, List L2)
    {
        List L;
        if (L1->Next == NULL)
        {
            L = L2;
            return L;
        }
        else if (L2->Next == NULL)
        {
            L = L1;
            return L;
        }
    
        List pCur1 = L1->Next;
        List pCur2 = L2->Next;
    
        while (pCur1!= NULL&&pCur2!= NULL) //
        {
            List pTemp, p1 = L1;
            while (pCur1->Data < pCur2->Data)
            {
                p1 = pCur1;   //记录当前结点之前的结点
                pCur1 = pCur1->Next;
                if (pCur1 == NULL||pCur2 == NULL)
                {
                    break;
                }
            }
            pTemp = pCur2;
            pCur2 = pCur2->Next;
            pTemp->Next = pCur1;  //pTemp要插入pCur1之前
            p1->Next = pTemp;
    
            pCur1=L1->Next; //回到链表头             
        }
    
        if (pCur2 != NULL)
        {
            while (pCur1->Next)
            {
                pCur1 = pCur1->Next;
            }
            pCur1->Next = pCur2;
        }
        L = L1;
        return L;
    }
    
    List Merge_(List L1, List L2)
    {
        List L=NULL;
        if (L1->Next==NULL )
        {
            return L2;
        }
        if (L2->Next==NULL)
        {
            return L1;
        }
        List pCur1 = L1->Next;
        List pCur2 = L2->Next;
        if (pCur1->Data<pCur2->Data)
        {
            L = pCur1;
            pCur1 = pCur1->Next;
        }
        else
        {
            L = pCur2;
            pCur2 = pCur2->Next;
        }
    
        List temp=L;
        while (pCur1&&pCur2)
        {
            if (pCur1->Data<pCur2->Data)
            {
                temp->Next = pCur1;
                pCur1 = pCur1->Next;
            }
            else
            {
                temp->Next = pCur2;
                pCur2 = pCur2->Next;
            }
            temp = temp->Next;
        }
        if (pCur1)
        {
            temp->Next = pCur1;
        }
        if (pCur2)
        {
            temp->Next = pCur2;
        }
        return L;
    }  

    测试结果:

    很方。。。

    等找到原因在更新了!

    针对链表的操作,不同的方法难易程度不一样,我写了两种方法,其中第一种方法,很多坑,自己针对每种测试点都进行了修改;然后第二种方法应该和以前课本学的差不多;理解起来也简单。

     在网上找的这种写法可以过:

    List Merge1(List L1, List L2){
        if (L1->Next == NULL){
            List temp, L;
            L = (List)malloc(sizeof(struct Node));
            temp = L2;
            L2 = L2->Next;
            L->Next = L2;
            while (L2){
                temp->Next = L2->Next;
                L2 = L2->Next;
            }
            return L;
        }
        else if (L2->Next == NULL){
            List temp, L;
            L = (List)malloc(sizeof(struct Node));
            temp = L1;
            L1 = L1->Next;
            L->Next = L1;
            while (L1){
                temp->Next = L1->Next;
                L1 = L1->Next;
            }
            return L;
        }
        else{
            List LL = (List)malloc(sizeof(struct Node));
            List LLL = LL;
            List temp1, temp2;
            temp1 = L1; 
            temp2 = L2;
            L1 = L1->Next; 
            L2 = L2->Next;
            while (L1 && L2){
                if (L1->Data < L2->Data){
                    LL->Next = L1;
                    LL = LL->Next;
                    temp1->Next = L1->Next;
                    L1 = L1->Next;
                }
                else{
                    LL->Next = L2;
                    LL = LL->Next;
                    temp2->Next = L2->Next;
                    L2 = L2->Next;
                }
            }
            while (L1){
                LL->Next = L1;
                LL = LL->Next;
                temp1->Next = L1->Next;
                L1 = L1->Next;
            }
            while (L2){
                LL->Next = L2;
                LL = LL->Next;
                temp2->Next = L2->Next;
                L2 = L2->Next;
            }
            return LLL;
        }
    }

    另外的写法:

    #include<stdio.h>
    #include<stdlib.h>
    typedef struct node *ptrNode;
    typedef ptrNode LinkList;
    //头结点
    typedef ptrNode Position;
    //中间节点
    typedef int ElementType;
    struct node
    {
        ElementType Element;
        Position next;
    };
    int IsEmpty(LinkList L)
    {
        return L->next == NULL;
    }
    LinkList creatList(void)
    {
        LinkList head, r, p;
        int x;
        head = (struct node*)malloc(sizeof(struct node));   //生成新结点
        r = head;
        scanf("%d", &x);
        while (x != -1)
        {
            p = (struct node*)malloc(sizeof(struct node));
            p->Element = x;
            r->next = p;
            r = p;
            scanf("%d", &x);
        }
        r->next = NULL;
        return head;
    }
    LinkList mergeList(LinkList a, LinkList b)
    {
        Position ha, hb, hc;
        LinkList c, r, p;
        ha = a->next;
        hb = b->next;
        c = (struct node*)malloc(sizeof(struct node));
        r = c;
        while ((ha != NULL) && (hb != NULL))
        {
            p = (struct node*)malloc(sizeof(struct node));
            if (ha->Element <= hb->Element)
            {
                p->Element = ha->Element;
                ha = ha->next;
            }
            else{
                p->Element = hb->Element;
                hb = hb->next;
            }        
            r->next = p;
            r = p;
        }
        if (ha == NULL){
            while (hb != NULL)
            {
                p = (struct node*)malloc(sizeof(struct node));
                p->Element = hb->Element;
                hb = hb->next;
                r->next = p;
                r = p;
            }
        }
        if (hb == NULL){
            while (ha != NULL){
                p = (struct node*)malloc(sizeof(struct node));
                p->Element = ha->Element;
                ha = ha->next;
                r->next = p;
                r = p;
            }
        }
        r->next = NULL;
        return c;
    }
    void printList(LinkList L){
        LinkList hc;
        int flag = 0;
        hc = L->next;
        if (hc == NULL)
            printf("NULL");
        while (hc != NULL){
            if (flag)
                printf(" ");
            else
                flag = 1;
            printf("%d", hc->Element);
            hc = hc->next;
        }
    }
    
    int main(void){
        LinkList L1, L2, L3;
        L1 = creatList();
        L2 = creatList();
        L3 = mergeList(L1, L2);
        printList(L3);
        return 0;
    }

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

                     PAT 两个有序链表序列的合并

  • 相关阅读:
    快速排序就这么简单
    Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】
    SpringDataJPA入门就这么简单
    递归就这么简单
    SpringBoot就是这么简单
    Activiti就是这么简单
    Lucene就是这么简单
    过来人告诉你,去工作前最好还是学学Git
    给女朋友讲解什么是Git
    我终于看懂了HBase,太不容易了...
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/6542018.html
Copyright © 2020-2023  润新知