Merging two sorted linked lists

前端 未结 14 2139
半阙折子戏
半阙折子戏 2020-12-01 00:12

This is one of the programming questions asked during written test from Microsoft. I am giving the question and the answer that I came up with. Thing is my answer although l

相关标签:
14条回答
  • 2020-12-01 00:54

    My take, with a test case

    So far all of the answers have been interesting and well done. It's possible that this one is more like what an interviewer would like to see, featuring DRY/DIE, and TDD. :-)

    #include <stdio.h>
    
    typedef struct ns {
        int data;
        struct ns *next;
    } Node;
    
    Node l1[] = {
      { 1, &l1[1] },
      { 3, &l1[2] },
      { 5, &l1[3] },
      { 7, &l1[4] },
      { 9, &l1[5] },
      {11, 0 },
    };
    
    Node l2[] = {
      { 2, &l2[1] },
      { 4, &l2[2] },
      { 6, 0 },
    };
    
    Node* MergeLists(Node* list1, Node* list2) {
      Node *t, **xt;
      for(xt = &t; list1 || list2;) {
        Node **z = list1 == NULL ? &list2 :
                   list2 == NULL ? &list1 :
                   list1->data < list2->data ? &list1 : &list2;
        *xt = *z;
         xt = &(*z)->next;
        *z  = *xt;
      }
      *xt = NULL;
      return t;
    }
    
    int main(void) {
      for(Node *t = MergeLists(l1, l2); t; t = t->next) 
        printf("%d\n", t->data);
      return 0;
    }
    
    0 讨论(0)
  • 2020-12-01 00:58
    //I have used recursions .
    //Sorry for such a long code.
    //:) it works,hope it helps.
    #include<stdio.h>
    #include<malloc.h>
    #include<stdlib.h>
    struct node{
        int data;
        struct node *next ;
    };
    struct node *start1=NULL,*start2=NULL;
    struct node*start=NULL;
    struct node *create_ll1(struct node *start);
    struct node *create_ll2(struct node *start);
    void sorted_ll(struct node* node1,struct node* node2);
    
    struct node *display(struct node *start);
    void p(struct node*);
    main(){
        start1=create_ll1(start1);
        start2=create_ll2(start2);
        //start1=display(start1);
        printf("\n");
        //start2=display(start2);
        sorted_ll(start1,start2);
        //start=display(start);
    
    
    }
    struct node *create_ll1(struct node *start1){
        struct node *ptr,*new_node;
        int num;
        printf("Enter -1 for ending \n");
        printf("Enter data for list 1: \n");
        scanf("%d",&num);
        while(num!=-1){
            new_node=(struct node *)malloc(sizeof(struct node));
            new_node->data=num;
            if(start1==NULL){
                new_node->next=NULL ;
                start1=new_node;
            }
            else{
                ptr=start1 ;
                while(ptr->next!=NULL)
                ptr=ptr->next;
                ptr->next=new_node;
                new_node->next=NULL ;
            }
            printf("Enter data: \n");
            scanf("%d",&num);
        }
        return start1;
    
    }
    struct node *create_ll2(struct node *start2){
        struct node *ptr,*new_node;
        int num;
        printf("Enter -1 for ending \n");
        printf("Enter data for list 2: \n");
        scanf("%d",&num);
        while(num!=-1){
            new_node=(struct node *)malloc(sizeof(struct node));
            new_node->data=num;
            if(start2==NULL){
                new_node->next=NULL ;
                start2=new_node;
            }
            else{
                ptr=start2 ;
                while(ptr->next!=NULL)
                ptr=ptr->next;
                ptr->next=new_node;
                new_node->next=NULL ;
            }
            printf("Enter data: \n");
            scanf("%d",&num);
        }
        return start2;
    
    }
    
    struct node *display(struct node *start){
        struct node *ptr;
        ptr=start;
        while(ptr->next!=NULL){
            printf("\t %d",ptr->data);
            ptr=ptr->next;
        }
            printf("\t %d",ptr->data);
            printf("\n");
    
    
        return start ;
    }
    void sorted_ll(struct node* node1,struct node* node2)
    {
        if(!node1){
            p(node2);
            exit(0);
        }
        else if(!node2){
            p(node1);
            exit(0);
        }
        if(node1->data<node2->data){
            printf("%d\t",node1->data);
            sorted_ll(node1->next,node2);
    
    
        }
        else{
            printf("%d\t",node2->data);
            sorted_ll(node1,node2->next);
        }
    }
    void p(struct node* pme){
        while(pme->next!=NULL){
            printf("%d \t",pme->data);
            pme=pme->next;
        }
        printf("%d",pme->data);
    
    }
    
    0 讨论(0)
  • 2020-12-01 00:59

    Your code is overloaded with if-s inserted for handling "special" cases, which bloats it a lot and makes it difficult to read. This usually happens when you decide to handle special cases "by code" instead of finding a way to handle them "by data". A statement attributed to David Wheeler says "All problems in computer science can be solved by another level of indirection". That "extra level of indirection" usually works very well with lists, helping to significantly reduce clutter created by those ifs.

    To illustrate the above, here's what my code would look like

    #define SWAP_PTRS(a, b) do { void *t = (a); (a) = (b); (b) = t; } while (0)
    
    Node* MergeLists(Node* list1, Node* list2) 
    {
      Node *list = NULL, **pnext = &list;
    
      if (list2 == NULL)
        return list1;
    
      while (list1 != NULL)
      {
        if (list1->data > list2->data)
          SWAP_PTRS(list1, list2);
    
        *pnext = list1;
        pnext = &list1->next;
        list1 = *pnext;
      }
    
      *pnext = list2;
      return list;
    }
    

    Some might argue that the use of an extra level of indirection in pnext pointer actually makes the code more difficult to read. I'd agree that for a newbie the approach might pose some difficulties, but for an experienced programmer this should be easily digestible as an idiom.

    0 讨论(0)
  • 2020-12-01 01:01
    public void Merge(LinkList list1, LinkList list2) {
            if (list1.head == null && list2.head == null) {
                System.out.println("Empty list"); //Check if lists are empty
            }
            if (list1.head == null) { //If list1 is empty print list2
                list2.printList();
            }
            if (list2.head == null) { //If list2 is empty print list1
                list1.printList(); 
            }
            LinkList list3 = new LinkList(); //create a new LinkList object for merging
            Node a = list1.head; //Beginning of list1
            Node b = list2.head; //Beginning of list2
            while (a != null && b != null) { //Until list ends
                if (a.value <= b.value) { //Compare values of list1 against list2
                    list3.insert(a.value); //Insert values to new list
                    a = a.next;
                } else if (a.value >= b.value) {
                    list3.insert(b.value);
                    b = b.next;
                }  else if (a.value == b.value){ //Insert only unique values and discard repeated values
                list3.insert(a.value);
                a = a.next;
                b = b.next;
            }
            }
            if (a == null) {
                while (b != null) {
                    list3.insert(b.value); //If list1 becomes empty, attach rest of the list2 to list3
                    b = b.next;
                }
            }
            if (b == null) {
                while (a != null) {
                    list3.insert(a.value);
                    a = a.next;
                }
            }
            list3.printList(); //print merged list
        }
    }
    

    Hi guys ! I was preparing for an interview this month and while I was working on this problem, this is the solution I came up with. I compared my solution with many solutions you posted here and find my program extremely lengthy. Although I find this easier to understand and implement, is there a better solution in Java to the existing code. I'm looking for a better time complexity solution. Any help/direction/tip is appreciated.

    PS: I was unable to come up with a Java solution for the programs listed above in C which used pointers.

    0 讨论(0)
  • 2020-12-01 01:02

    Use recursion. The code is as follows:

    ListNode* mergeTwoSortedLists(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == NULL)
            return pHead2;
        else if(pHead2 == NULL)
            return pHead1;
    
        ListNode* pMergedHead = NULL;
    
        if(pHead1->m_nValue < pHead2->m_nValue)
        {
            pMergedHead = pHead1;
            pMergedHead->m_pNext = mergeTwoSortedLists(pHead1->m_pNext, pHead2);
        }
        else
        {
            pMergedHead = pHead2;
            pMergedHead->m_pNext = mergeTwoSortedLists(pHead1, pHead2->m_pNext);
        }
    
        return pMergedHead;
    }
    
    0 讨论(0)
  • 2020-12-01 01:05

    You may use Java 8, Stream API to merge, get Distinct and sort. Below is sample code for sorting and merging two list with Integer elements

    List<Integer> list1= Arrays.asList(2,3,5,8);
    List<Integer> list2 = Arrays.asList(3,6,8);
    
    List<Integer> finalList = new ArrayList<>();
    finalList.addAll(list1);
    finalList.addAll(list2);
    
    List<Integer>  mergeSortedList = 
      finalList.stream()
        .distinct()
        .sorted()
        .collect(Collectors.toList());
    System.out.println(mergeSortedList);
    
    0 讨论(0)
提交回复
热议问题