创建一个接受链表作为输入的合并排序

时间:2015-02-19 02:04:12

标签: c++

以下是我的一些代码

listnode *mergesort(struct listnode *list){
    struct listnode *L, *R, *head;
    int i = 0;
    head = list;
    while (list->next != NULL){
        if (i%2 == 0){              //it splits the linkedlist into 2 segments
                                    //it adds the elements in the linked list                                        
                                    // alternatively.
                                    //to a linked list R & L
            L=list->next;
            list->next = L->next;
            i=i+1;
        }
        else{
            R= list->next;
            list->next = R->next;
            i=i+1;
        }
        list = list->next;

    }
    MergeLists(mergesort(L),mergesort(R));
}

我不断收到细分错误,无法弄清问题是什么。

2 个答案:

答案 0 :(得分:0)

我发现了两件事: 1. int i = 0;意味着我将永远是平等的。 'i'是否意味着列表节点中的值? 2.返回MergeLists(L,R);在while语句中,因此循环将退出。

答案 1 :(得分:0)

首先,你计算的是什么'正在进行的是在计数为偶数时将left移动一个,并在计数为奇数时对right执行相同操作。更不用说如果列表中只有一个项目,则leftright未初始化,并且循环的最后一行可能会导致您取消引用null。

其次,你需要一些方法来标记left列表的结尾,否则你的mergesort将一遍又一遍地做同样的事情,直到你溢出堆栈。

我们可以通过将左半部分中的最后一个指针设置为NULL来实现。请记住,MergeLists必须修复所有这些才能重新制作一个好的列表。

尝试这样的事情:

listnode *mergesort(listnode *list) {
  listnode *left = list, *right = list, *prev, *end = list;

  if (list == 0) { return list; }

  // move right once for every two we move end, so that we divide the middle
  while (end != 0) {
    end = end->next;
    prev = right; // keep track of the node before the start of right
    right = right->next;

    if (end != 0) {
      end = end->next;
    }
  }


  if (left->next == right) {
    // TODO swap items if necessary
    return left;
  }

  prev->next = 0; // split the list
  left = mergesort(left);
  right = mergesort(right);
  // TODO join left and right by calling MergeLists or whatever
  return left;
}

工作指针图:

prev->next = 0 removes -----|
                            v
list  -> [1] -> [2] -> [3] -> [4] -> [5] -> [6]
left  ----^                    ^
right -------------------------|