递归算法中的无限循环

时间:2012-11-03 22:25:17

标签: java algorithm sorting recursion pivot

我需要制作一个数据透视排序算法,其中你基本上取一个链表的第一项,将其分为两个单独的列表,一个项目大于或等于第一个项目,一个项目小于第一个项目,然后递归地对它们进行排序,直到你到达已经排序的大小为1的链表,然后将小于和大于列表合并在一起形成一个排序列表。

我的算法一直停留在无限循环中的最后一项,我现在已经睡了大约23个小时,需要一双新眼睛来找出我犯错的地方。如果你能帮忙,我会非常感激。

链接列表类很简单,有两个项目,第一个只是一个正整数,第二个当然是列表中的下一个项目。当代码到达最后一个项目时,它会被Sort()函数捕获,然后不会将最后一个项目附加在一起

public class PivotSort {
   public static void main(String[] args) {
      try {
         intList x = intList.CreateFromUserInput(); // just makes a linked list
                                                    // from numbers I type in
         x = Sort(x);
         x.PrintList();
      } catch (Exception e) {
         System.out.println(e);
      }
   }

   public static intList Sort(intList list) {
      if (list == null || list.item == null)
         return list;
      return Append(Sort(Part_Less(list.item, list)),
            Sort(Part_Greater(list.item, list)));
   }

   public static intList Part_Less(int N, intList L1) {
      if (L1 == null)
         return null;
      if (L1.item < N)
         return new intList(L1.item, Part_Less(N, L1.next));
      else
         return Part_Less(N, L1.next);
   }

   public static intList Part_Greater(int N, intList L1) {
      if (L1 == null)
         return null;
      if (L1.item >= N)
         return new intList(L1.item, Part_Greater(N, L1.next));
      else
         return Part_Greater(N, L1.next);
   }

   public static intList Append(intList L1, intList L2) {
      try {
         if (L1 == null)
            return L2;
         if (L2 == null)
            return L1;
         for (intList curr = L1; curr != null; curr = curr.next) {
            if (curr.next == null) {
               curr.next = L2;
               break;
            }
         }
         return L1;
      } catch (Exception e) {
         System.out.println(e);
         return null;
      }
   }
}

1 个答案:

答案 0 :(得分:2)

问题是,第二次通话永远无法达到Sort的基本情况:

Sort(Part_Greater(list.item, list))

Part_Greater()函数将首先构造一个列表,其中包含大于或等于第一个项目的所有项目。让我们说这是你的原始列表:

10 5 7 11 15 7 16 20

Part_Greater()将构建一个包含10 11 15 16 20的列表。当您将其传递给Sort时,它会再次在该列表上调用Part_Greater(),这会产生该列表。

由于在第一次调用Part_Greater()后没有删除任何元素,因此输入无限递归。

您需要做的是从列表中删除pivot元素。这确保了,在每个递归步骤中,您的数字列表至少缩短一个,最终在列表为空时达到基本情况。

return Append(
    Sort(Part_less(list.item, list.next)),
    new intList(list.item, Sort(Part_Greater(list.item, list.next)))
);