【问题标题】:Incorrect implementation of QuickSort快速排序的错误实现
【发布时间】:2014-08-08 23:49:02
【问题描述】:

我正在从 Youtube 了解 Quick Sort 并尝试实施该实现,其中枢轴将与左侧标记之前的 1 个元素交换

这是快速排序算法的伪代码

Method
Divide-and-conquer
Pick an element (pivot) from the list
Pivot is arbitrarily chosen
Normally, the first element is selected
Partition the list into two halves such that:
All the elements in the first half is smaller than the pivot
All the elements in the second half is greater than the pivot
After the rearrangement, the pivot element (pivot) occupies a proper position in a sorting of the list.
Recursively
Quick-sort the 1st half
Quick-sort the 2nd half

Java 代码

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;



public class QuickSort 
{
    public static void main(String args[])
    {
        Vector<Integer> container = new Vector<Integer>();

        String userinput = "data1.txt";
        Scanner myScanner = new Scanner("foo"); // variable used to read file

        try
        {
            //open filename

            File inputfile = new File("C:\\Users\\8382c\\workspace\\AdvanceAlgorithmA3_Quicksort\\src\\" + userinput);
             myScanner = new Scanner(inputfile);

        }
        catch(FileNotFoundException e)
        {
            System.out.println("File cant be found");
        }


         String line = myScanner.nextLine(); //read 1st line which contains the number of numbers to be sorted

         while(myScanner.hasNext())
         {
             container.add(myScanner.nextInt());
         }


        System.out.println(line);

        /*container.add(7);
        container.add(2);
        container.add(3);
        container.add(4);
        container.add(8);
        container.add(6);
        container.add(8);
        container.add(9);*/

        quickSort(container,0,7);

        for (int i =0;i<container.size();i++)
        {
            System.out.println(container.get(i));
        }

        //http://www.algolist.net/Algorithms/Sorting/Quicksort




    }


    public static int partition(Vector<Integer> container, int left, int right)
    {
          int i = left, j = right;
          int tmp;


          int pivot = container.get(left);

          i++;

          while (i <= j) 
          {
                while ( container.get(i) < pivot)
                      i++;
                while ( container.get(j) > pivot)
                      j--;
                if (i <= j) 
                {
                      tmp =  container.get(i);

                      container.set(i, container.get(j));
                      container.set(j, tmp);

                      i++;
                      j--;
                }
          };

          tmp = container.get(left);

          container.set(left, container.get(i-1));
          container.set(i-1, tmp);

          return i-1;
    }

    public static void quickSort(Vector<Integer> container, int left, int right) 
    {
          int index = partition(container, left, right);
          if (left < index - 1)
                quickSort(container, left, index - 1);
          if (index+1 < right)
                quickSort(container, index+1, right);
    }


}

该算法适用于以下数字:{7,23,4,8,6,8,9}

但是,当我尝试对包含 10000 个数字的 text file 进行排序时,它不起作用

我在算法中做错了什么???

【问题讨论】:

  • 您是否尝试在调试器中单步执行代码?
  • @rob 没关系,我已经知道了,谢谢!!!

标签: java debugging sorting quicksort


【解决方案1】:

更新

首先,这个声明:

quickSort(container,0,7);

应阅读:

quickSort(container,0,container.size()-1);

我不确定这是否是问题所在。现在让我们清理您的代码。

你的核心职能:

public static void quickSort(Vector<Integer> container, int left, int right) 
{
      int index = partition(container, left, right);
      if (left < index - 1)
            quickSort(container, left, index - 1);
      if (index+1 < right)
            quickSort(container, index+1, right);
}

在索引的加/减 1 方面似乎有一个错误。这看起来更合适:

public static void quickSort(Vector<Integer> container, int left, int right) 
{
      if (left < right)
      {
          int index = partition(container, left, right);
          quickSort(container, left, index);
          quickSort(container, index+1, right);
      }
}

您的分区函数也需要一些清理。我第一次发帖的时候就搞砸了。现在我测试了它,我知道它可以工作。

public static int partition(Vector<Integer> container, int left, int right)
{
      int i = left-1;
      int j = right+1;

      int pivot = container.get(left);

      while (true) 
      {
          do
          {
              i++;
          } while (container.get(i) < pivot);

          do
          {
              j--;
          } while (container.get(j) > pivot);

          if (i < j) 
          {
                int tmp =  container.get(i);
                container.set(i, container.get(j));
                container.set(j, tmp);
          }
          else
          {
              break;
          }
      };
      return j;
}

【讨论】:

  • 谢谢,我想知道这个方法是否交换了左标记之前的枢轴和一个元素??
  • 不能发生“左标记之前的一个”,因为i = left - 1 的初始分配是由调用i++ 的while 循环中的第一条语句补充的。如果 j 小于 i,则永远不会发生交换。顺便说一句,此代码只是从 this book 的格式 Quicksort/Partition 定义转换而来。
【解决方案2】:

Selbie 答案确实按预期工作,但这不是我正在寻找的实现。我正在寻找快速排序的版本,其中枢轴与左标记之前的一个交换,导致每次迭代后一个元素就位。

经过多次试验和错误,我意识到我原来的算法有效,我不知道为什么当我第一次在问题中发布算法时它最初不起作用

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;



public class QuickSort 
{
    public static void main(String args[])
    {
        Vector<Integer> container = new Vector<Integer>();


        container.add(7);
        container.add(2);
        container.add(3);
        container.add(4); // 7 2 3 4 8 6 8 9
        container.add(8); // 7 2 3 4 6 8 8 9        
        container.add(6); // 6 2 3 4 7 8 8 9
        container.add(8);
        container.add(9);

        quickSort(container,0,container.size()-1);

        for (int i =0;i<container.size();i++)
        {
            System.out.println(container.get(i));
        }



    }


    public static int partition(Vector<Integer> container, int left, int right)
    {
          int i = left, j = right;
          int tmp;


          int pivot = container.get(left);

          i++;

          while (i <= j) 
          {
                while ( container.get(i) < pivot)
                      i++;
                while ( container.get(j) > pivot)
                      j--;
                if (i <= j) 
                {
                      tmp =  container.get(i);

                      container.set(i, container.get(j));
                      container.set(j, tmp);

                      i++;
                      j--;
                }
          };

          tmp = container.get(left);

          container.set(left, container.get(i-1));
          container.set(i-1, tmp);

          return i-1;





    }

    public static void quickSort(Vector<Integer> container, int left, int right) 
    {
          int index = partition(container, left, right);
          if (left < index - 1)
                quickSort(container, left, index - 1);
          if (index+1 < right)
                quickSort(container, index+1, right);



    }


}

【讨论】:

    猜你喜欢
    • 2013-08-09
    • 2016-12-08
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多