当前位置: 首页 > 知识库问答 >
问题:

在Java中使用max-heap对数组进行排序

楚俊杰
2023-03-14

我正在开发一个程序,通过将数组划分为较小的最大堆并从每个堆中提取最大整数,然后将其从堆中删除并再次运行,直到每个堆都为空,来对数组进行排序,但我似乎无法理解。

从我的立场来看,代码看起来不错,但我没有得到我想要的结果。我的输入是随机创建的,并生成512个整数的数组。下面是它为一个示例运行打印的内容-

Original Array  -391 176 -380 -262 -474 327 -496 214 475 -255 50 -351 179 -385 -442 -227 465 127 -293 288
Sorted Array 475 465 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 327 
n = 20 k = 2
The number of comparisons is 243

有人能发现我的代码有什么问题吗?我会非常高兴的。

(1) 主程序

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

 public class Project {
    static final int n = 20;
    static final int k = 2;
    static int counter = 0;
    private static Scanner scan;

    public static void main(String[] args) throws IOException {
        // Optional  - reading from a file containing 512 integers.
        InputCreator.main();
        File f = new File("random.txt");
        // File f = new File("increase.txt");
        // File f = new File("decrease.txt");
        try { scan = new Scanner(f);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace(); }
        int [] L = new int[n];
        System.out.print("Original Array ");
        for (int i = 0; i < n ; i++)
            { counter++; L[i] = scan.nextInt(); System.out.print(" " + L[i]); }
        Projectsort(L);
    }

    private static void Projectsort(int [] L) {
        // int [][] Li = new int [k] [n-(n/k*(k-1))]; // The size of the rest of the integers (n-(n/k*(k-1)) will always be bigger than n/k
        int [] temp = new int [n/k], extra = new int [n-(n/k)*(k-1)];
        int extraIndex = 0, max, maxIndex = 0, r = 0;
        ProjectMaxHeap [] Li = new ProjectMaxHeap [k];
        // The following loop's time effiency is O(k) * O(N/k) = O(N)
        for (int i=0; i<k-1; i++) { counter++; // copying all the integers from Array L into K-1 smaller arrays
            for (int j=0; j<n/k ; j++)
                 { counter++; temp [j] = L[i*(n/k)+j]; }
            Li[i] = new ProjectMaxHeap (temp); }

        for (int i=(n/k)*(k-1) ; i<n ; ++i) // The rest of the integers on array L
            { counter++; extra [extraIndex] = L[i]; extraIndex++; }
        Li[k-1] = new ProjectMaxHeap(extra);
        System.out.print("\nSorted Array ");
        for (int i = n ; i > 0 ; i--) { counter++;
            r = 0;
            do{max = Li[r].extractMax(); r++; }while(Li[r].isEmpty() && r < k - 1);
            for (int j = r; j < k; j++) // Time efficiency O(k)*O(N/k)
            { counter++;
              if(!Li[j].isEmpty()) {
                if (Li[j].extractMax() > max) { 
                    counter++;
                    max = Li[j].extractMax(); 
                    maxIndex = j; } 
            } 
        System.out.print(max + " ");
        Li[maxIndex].deleteMax(); } }
        System.out.println("\nn = " + n + " k = " + k +"\nThe number of comparisons is " + counter);
    }
 }

(2) 最大堆类

    public class ProjectMaxHeap
{
    private int [] _Heap;
    private int _size;

    public ProjectMaxHeap (int [] A){
        _size = A.length;
        _Heap = new int[A.length]; 
        System.arraycopy(A, 0, _Heap, 0, A.length);
        for (int i = _size / 2 ; i >=0 ; i--) {
            Project.counter++;
            maxHeapify(i); }
    }

    private int parent(int pos) 
    { return pos / 2; }

    private int leftChild(int pos)
    { return (2 * pos); }

    private int rightChild(int pos)
    { return (2 * pos) + 1; }

    private void swap(int fpos,int spos) {
        int tmp;
        tmp = _Heap[fpos];
        _Heap[fpos] = _Heap[spos];
        _Heap[spos] = tmp; }

    private void maxHeapify (int i) {
        int l = leftChild(i), r = rightChild(i), largest;
        if(l < _size && _Heap[l] > _Heap[i]) {
            Project.counter+=2;
            largest = l; }
            else largest = i;
        if(r < _size && _Heap[r] > _Heap[largest]) {
            largest = r;
            Project.counter+=2; }
        if (largest != i) {
            Project.counter++;
            swap(i, largest);
            maxHeapify (largest); }
        } 

    protected boolean isEmpty() { return _size == 0; }

    protected void deleteMax() {
        if (_size > 1) {
            Project.counter++;
            maxHeapify(0);
            int max = _Heap[0];
            _size--;
            swap(0, _size);
            maxHeapify(0); }
        else _size = 0;    
    }

    protected int extractMax() {
        maxHeapify(0);
        return _Heap[0];
    }
}

(3)输入创建者

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.io.FileReader;
import java.io.BufferedReader;

public class InputCreator {
    public static void main() {
        randomizer();
        decrease();
        increase();
    }
    private static void randomizer() {
        // The target file
        File out = new File("random.txt");
        FileWriter fw = null;
        int n = 0;
        // Try block: Most stream operations may throw IO exception
        try {
            // Create file writer object
            fw = new FileWriter(out);
            // Wrap thק writer with buffered streams
            BufferedWriter writer = new BufferedWriter(fw);
            int line;
            Random random = new Random();
            while (n < Project.n) {
                // Randomize an integer and write it to the output file
                line = random.nextInt(1000)-500;
                writer.write(line + "\r\n");
                n++;
            }
            // Close the stream
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
    private static void increase() {
        // The target file
        File out = new File("increase.txt");
        FileWriter fw = null;
        int n = 0;
        int temp = 0;
        // Try block: Most stream operations may throw IO exception
        try {
            // Create file writer object
            fw = new FileWriter(out);
            // Wrap thק writer with buffered streams
            BufferedWriter writer = new BufferedWriter(fw);
            int line;
            Random random = new Random();
            while (n < Project.n) {
                // Randomize an integer and write it to the output file
                line = random.nextInt((n+1)*10);
                if(line > temp) {
                writer.write(line + "\r\n");
                n++; 
                temp = line; }
            }
            // Close the stream
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
        private static void decrease() {
        // The target file
        File out = new File("decrease.txt");
        FileWriter fw = null;
        int n = 0;
        int temp = 10000;
        // Try block: Most stream operations may throw IO exception
        try {
            // Create file writer object
            fw = new FileWriter(out);
            // Wrap thק writer with buffered streams
            BufferedWriter writer = new BufferedWriter(fw);
            int line;
            Random random = new Random();
            while (n < Project.n) {
                // Randomize an integer and write it to the output file
                line = 10000 - random.nextInt((n+1)*20);
                if(line < temp) {
                writer.write(line + "\r\n");
                n++; 
                temp = line; }
            }
            // Close the stream
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
}

共有1个答案

华阳秋
2023-03-14

问题出在max=Li[0]. extetMax();您没有检查Li[0]是否为空。

始终检查前提条件并快速失败。如果您开始使用

if (_size == 0) {
    throw new IllegalStateException("empty heap");
}

这是固定的最终循环

for (int i = 0; i < n; i++) {
    int maxIndex = -1;           // remove these variable declarations from top of method
    int max = Integer.MIN_VALUE; // it's best to confine variables to narrow scope
    for (int j = 0; j < k; j++) {
        if (!Li[j].isEmpty()) {
            int current = Li[j].extractMax();
            if (maxIndex == -1 || current > max) {
                maxIndex = j;
                max = current;
            }
        }
    }
    assert maxIndex != -1;
    Li[maxIndex].deleteMax();
    System.out.print(max + " ");
}
 类似资料:
  • 本文向大家介绍Java Max Heap(堆),包括了Java Max Heap(堆)的使用技巧和注意事项,需要的朋友参考一下 最大堆是一个完整的二叉树,其中,每个步骤中根节点的值都大于或等于子节点中的值。 以下是使用库函数实现的Max Heap。 示例 输出结果 名为Demo的类,在主函数中,定义了优先级队列的实例,并使用“add”函数将元素添加到其中。定义了一个迭代器 用于迭代优先级队列中的元

  • 我试图返回一系列流媒体数据的运行中值。为此,我使用了一个最大堆(它存储序列下半部分的值)和一个最小堆(它保存序列上半部分的数值)。 特别是,我使用的是来自heapq模块的Python(2.0)内置最小堆数据结构(https://docs.python.org/2/library/heapq.html). 相反,为了构建最大堆,我只需使用需要推入堆中的数字的负数。 我的Python代码如下: 下面是

  • 我知道堆排序中BUILD-MAX-HEAP的运行时间是O(n)。但是,如果我们有一个已经按降序排序的数组,为什么对于BUILD-MAX-HEAP的运行时间仍然有O(n)<它不是应该是类似于O(1)的吗?它已经从最大值到最小值排序,因此我们不需要MAX-HEAPIFY。 我的理解正确吗?谁能给我解释一下吗?

  • 问题内容: 我的数组不包含任何字符串。但是它包含对象引用。每个对象引用都通过toString方法返回名称,id,作者和发布者。 现在,我需要按名称对对象数组进行排序。我知道如何排序,但是我不知道如何从对象中提取名称并对它们进行排序。 问题答案: 你有两种方法可以使用Arrays实用程序类 实现一个Comparator并将数组与比较器一起传递给sort方法,该方法将其作为第二个参数。 在对象所属的类

  • 问题内容: 允许用户使用字符串数组进行演奏。他们可以将字符串添加到数组中,从数组中删除字符串,在数组中搜索字符串,最终他们将能够对数组进行排序。排序使我很困惑。我尝试了几种不同的方法。第一种方法是将数组转换为ArrayList并使用Collections对ArrayList进行排序,然后将其转换回静态类数组。没用 我尝试的第二种方法是遍历数组,并尝试仅对用户添加的字符串进行排序,而不是对数组中的所

  • 我有一个JSON数组: 结果为“数据”: 我怎么能有一个升序按“datesurder”? THX