【问题标题】:Is it possible to change my recursive method to iterative?是否可以将我的递归方法更改为迭代?
【发布时间】:2021-03-30 20:54:39
【问题描述】:

我正在编写一个快速排序算法来使用随机枢轴对数字进行排序。如何将我的快速排序方法从递归更改为迭代?我有一种递归的排序方法,但我需要迭代方法。是否可以仅在排序方法中从递归更改为迭代,还是我必须更改整个代码?

这是我所有的代码

public class Main {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        ArrayList time = new ArrayList();
        for (int k = 1; k < 1000000; k++) {
            time.add(k);
        }

        int[] tall = new int[1000000];
        int index = 0;
        int n = 1000000;

        File text = new File("/Users/sasan/IdeaProjects/File.txt");

        try {
            Scanner scan = new Scanner(text);

            while (scan.hasNextLine() && index < 1000000) {
                tall[index] = scan.nextInt();
                index++;
            }
            scan.close();
        } catch (IOException e) {
            System.out.println("Problem with file");
            e.printStackTrace();
        }

        int l = tall.length;

        sort(tall, 0, l-1);

        System.out.println("Sorted array");
        printArray(tall);

        System.out.println("");

        long end = System.currentTimeMillis();
        System.out.print("Execution Time is: ");
        System.out.print((end - start));
    }

    static void random(int tall[],int low,int high)
    {
        Random rand= new Random();
        int pivot = rand.nextInt(high-low)+low;

        int temp1=tall[pivot];
        tall[pivot]=tall[high];
        tall[high]=temp1;
    }

    /* This function takes last element as pivot,
    places the pivot element at its correct
    position in sorted array, and places all
    smaller (smaller than pivot) to left of
    pivot and all greater elements to right
    of pivot */
    static int partition(int tall[], int low, int high)
    {
        // pivot is choosen randomly
        random(tall,low,high);
        int pivot = tall[high];

        int i = (low-1); // index of smaller element
        for (int j = low; j < high; j++)
        {
            // If current element is smaller than or
            // equal to pivot
            if (tall[j] < pivot)
            {
                i++;

                // swap arr[i] and arr[j]
                int temp = tall[i];
                tall[i] = tall[j];
                tall[j] = temp;
            }
        }

        // swap arr[i+1] and arr[high] (or pivot)
        int temp = tall[i+1];
        tall[i+1] = tall[high];
        tall[high] = temp;

        return i+1;
    }

    /* The main function that implements QuickSort()
    tall[] --> Array to be sorted,
    low --> Starting index,
    high --> Ending index */
    static void sort(int tall[], int low, int high)
    {
        if (low < high)
        {
            /* pi is partitioning index, tall[pi] is
            now at right place */
            int pi = partition(tall, low, high);

            // Recursively sort elements before
            // partition and after partition
            sort(tall, low, pi-1);
            sort(tall, pi+1, high);
        }
    }

    /* A utility function to print array of size n */
    static void printArray(int tall[])
    {
        int n = tall.length;
        for (int i = 0; i < n; ++i)
            System.out.print(tall[i]+" ");
        System.out.println();
    }

    // Driver Code
}

【问题讨论】:

  • 我在你的 main 方法中看不到任何递归代码。请编辑您的问题以显示sort 方法。
  • @sorifiend 问题说:“我有一个递归的 sort 方法”,所以你应该看看 sort 方法,而不是main 方法,查找递归方法。
  • 请在询问之前做一些研究,例如quicksort iterative网络搜索 会为您找到答案。问题因缺乏研究而被否决。

标签: java algorithm recursion iteration quicksort


【解决方案1】:

您通常总是可以将递归方法转换为迭代方法,尽管使用递归的要点是您通常会在最方便的时候选择它。诸如快速排序之类的分治算法正是递归的理想选择。

要将递归方法转换为迭代方法,您基本上使用“堆栈”对象(Java 提供了 Stack 类来帮助实现这一点):它实质上存储了每次迭代需要操作的参数。然后,在调用递归方法之前,将用于调用它的参数放在堆栈顶部。通过从堆栈顶部获取最新参数,每次迭代都相当于从方法“返回”。 (本质上,您是在模拟 Java 在调用方法时所经历的过程。)

所以模式看起来像这样:

Stack<Paraneters> stack = new Stack();
stack.push(new Parameters(0, size);
while (!stack.empty()) {
    Parameters params = stack.pop();
    int lo = params.lo;
    int hi = params.hi;
    
    if (lo < hi) {
        int pivot = partition(lo, hi);
        stack.push(new Parameters(lo, pivot-1));
        stack.push(new Parameters(pivot+1, hi));
    }
}

对于这个简单的示例,Parameters 对象实际上可能只是一个长度为 2 的 int 数组,但对于更复杂的参数组合,您最终可能会构造一个包装类。 (使用递归在实践中更方便的另一个原因。)

【讨论】:

  • 真的应该借此机会提到确保日志空间使用的优化,并在此上下文中讨论快速排序。 (提示:这是关于将两个东西压入堆栈的顺序)。
猜你喜欢
  • 2021-09-10
  • 2015-04-23
  • 2019-03-01
  • 2013-04-15
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多