一尘不染

合并两个排序的链表

algorithm

这是Microsoft进行书面测试期间提出的编程问题之一。我给出了我想出的问题和答案。尽管看起来很全面(至少对我而言),这是我的答案,但我认为可以减少行数。它是用C语言询问的,我是Java语言的人,但我设法对其进行了编码(我的答案可能包含太多的Java语法)

好,这是问题。

您有两个已经排序的列表,您必须合并它们并返回一个没有任何新额外节点的新列表。返回的列表也应排序。

方法签名是

Node* MergeLists(Node* list1, Node* list2);

struct Node{
    int data;
    Node *next;
}

以下是我想出的解决方案,

Node* MergeLists(Node* list1, Node* list2){
    Node* mergedList;
    if(list1 == null && list2 ==null){//if both are null, return null
        return null;
    }
    if(list1 == null){//if list1 is null, simply return list2
        return list2;
    }
    if(list2 == null){//if list2 is null, simply return list1
        return list1;
    }
    if(list1.data < list2.data){//initialize mergedList pointer to list1 if list1's data is lesser
        mergedList = list1;
    }else{//initialize mergedList pointer to list2 if list2's data is lesser or equal
        mergedList = list2;
    }
    while(list1!=null && list2!=null){
        if(list1.data < list2.data){
            mergedList->next = list1;
            list1 = list1->next;
        }else{
            mergedList->next = list2;
            list2 = list2->next;
        }
    }
    if(list1 == null){//remaining nodes of list2 appended to mergedList when list1 has reached its end.
        mergedList->next = list2;
    }else{//remaining nodes of list1 appended to mergedList when list2 has reached its end
        mergedList->next = list1;
    }
    return mergedList;
}

我非常有信心可以改善这一点。请帮助我找到我添加的多余行。请随时批评我的语法错误和逻辑。

谢谢!


阅读 214

收藏
2020-07-28

共1个答案

一尘不染

您的代码过载,if插入-
s来处理“特殊”情况,这使它非常膨胀并且难以阅读。当您决定“按代码”处理特殊情况而不是找到“按数据”处理特殊情况时,通常会发生这种情况。大卫·惠勒(David
Wheeler)的声明说:“计算机科学中的所有问题都可以通过另一种间接解决方案来解决”。该“额外级别的间接”通常与列表配合使用,有助于显着减少由这些列表造成的混乱if

为了说明上述内容,这是我的代码的样子

#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;
}

有人可能会争辩说,在pnext指针中使用额外级别的间接寻址实际上会使代码更难以阅读。我同意对于新手来说,这种方法可能会遇到一些困难,但是对于有经验的程序员,这应该很容易理解。

2020-07-28