为什么不是';bubbleDown方法是否按预期工作(堆排序)? 这是一个任务,我尝试了C++和java,但是在两个版本中,冒泡方法都没有按照预期的方式工作,尽管我相信逻辑应该是这样。我已经提交了两个版本,但是由于Java版本是最新的,我将在这里发布

为什么不是';bubbleDown方法是否按预期工作(堆排序)? 这是一个任务,我尝试了C++和java,但是在两个版本中,冒泡方法都没有按照预期的方式工作,尽管我相信逻辑应该是这样。我已经提交了两个版本,但是由于Java版本是最新的,我将在这里发布,java,heapsort,Java,Heapsort,以下是Java版本: import java.io.*; import java.util.Scanner; public class HeapSort { static int[] heap; Integer[] sorted; String in, out; int fullLength = 0; public HeapSort(String inf, String outf) throws FileNotFoundException {

以下是Java版本:

import java.io.*;
import java.util.Scanner;

public class HeapSort {
    static int[] heap;
    Integer[] sorted;
    String in, out;
    int fullLength = 0;

    public HeapSort(String inf, String outf) throws FileNotFoundException {
        in = inf;
        out = outf;

        Scanner scan = new Scanner(new File(in));
        while (scan.hasNextInt()) {
            fullLength++;
            scan.nextInt();
        }

        sorted = new Integer[fullLength];
        heap = new int[fullLength+1];
        heap[0] = 0;

        scan.close();
    }

    public boolean isFull() {
        return heap[0] == fullLength;
    }

    public boolean isEmpty() {
        return heap[0] == 0;
    }

    public void buildHeap() throws IOException {
        Scanner scan = new Scanner(new File(in));
        while (scan.hasNextInt())
            insertOneDataItem(scan.nextInt());

        scan.close();
    }

    public void deleteHeap() throws IOException {
        while (!isEmpty()) {
            deleteRoot();
            printHeap();
        }
    }

    public void deleteRoot() throws IOException {
        if (isEmpty())
            return;

        FileWriter f = new FileWriter(out, true);
        f.write("Deleting " + heap[1] + "\n");
        f.close();
        int i;
        for(i = 0; sorted[i] != null; i++);
        sorted[i] = heap[1];
        heap[1] = heap[heap[0]--];
        bubbleDown();
    }


    public void insertOneDataItem(int num) throws IOException {
        if (isFull()) {
            p("Heap is full");
            return;
        }

        heap[++heap[0]] = num;
        bubbleUp();
        printHeap();
    }

    public void printHeap() throws IOException {
        FileWriter f = new FileWriter(out, true);
        f.write("Current Heap:\t");
        for (int i = 1; i <= heap[0]; i++) {
            if (i > 10) break;
            f.write(heap[i] + " ");
        }
        f.write("\n");
        f.close();
    }

    public void printSorted() throws IOException {
        FileWriter f = new FileWriter(out, true);
        f.write("Current Sorted:\t");
        for (int i = 1; i <= sorted.length; i++) {
            if (i > 10) break;
            f.write(sorted[i] + " ");
        }
        f.write("\n");
        f.close();
    }

    public void bubbleUp() {
        int h = heap[0];
        while (h >= 2 && heap[h] < heap[h/2]) {
            int x = heap[h];
            heap[h] = heap[h/2];
            heap[h/2] = x;
            h = h/2;
        }
    }

    public void bubbleDown() {
        int k = 1;
        // make sure we have at least a left child
        // before continuing on
        while (2*k <= heap.length) {
            int left = 2*k;
            int right = 2*k+1;
            if (heap[k] >= heap[left]) {
                int x = heap[k];
                heap[k] = heap[left];
                heap[left] = x;
                k = left;
                continue;
            }
            if (right <= heap.length &&
                heap[k] >= heap[right]) {
                int x = heap[k];
                heap[k] = heap[right];
                heap[right] = x;
                k = right;
            } else {
                return;
            }
        }
    }

    public void begin() throws IOException {
        buildHeap();
        deleteHeap();
        printSorted();
    }

    public static void main(String[] args) throws IOException {
        if (args.length < 2) {
            p("Please start with: program file1.txt file2.txt");
            System.exit(1);
        }

        // empty the output file
        (new FileOutputStream(args[1])).close();

        (new HeapSort(args[0], args[1])).begin();

    }

    public static void p(String s) {
        System.out.println(s);
    }
}
import java.io.*;
导入java.util.Scanner;
公共类堆{
静态int[]堆;
整数[]排序;
串入,串出;
int fullLength=0;
公共HeapSort(字符串inf,字符串outp)抛出FileNotFoundException{
in=inf;
out=out;
扫描仪扫描=新扫描仪(新文件(in));
while(scan.hasNextInt()){
全长++;
scan.nextInt();
}
排序=新整数[全长];
heap=newint[fullLength+1];
堆[0]=0;
scan.close();
}
公共布尔值isFull(){
返回堆[0]==全长;
}
公共布尔值为空(){
返回堆[0]==0;
}
public void buildHeap()引发IOException{
扫描仪扫描=新扫描仪(新文件(in));
while(scan.hasNextInt())
insertOneDataItem(scan.nextInt());
scan.close();
}
public void deleteHeap()引发IOException{
而(!isEmpty()){
deleteRoot();
printcheap();
}
}
public void deleteRoot()引发IOException{
if(isEmpty())
返回;
FileWriter f=新的FileWriter(out,true);
f、 写入(“删除”+堆[1]+“\n”);
f、 close();
int i;
for(i=0;排序的[i]!=null;i++);
排序后的[i]=堆[1];
堆[1]=堆[heap[0]--];
泡泡镇();
}
public void insertOneDataItem(int num)引发IOException{
如果(isFull()){
p(“堆已满”);
返回;
}
堆[++堆[0]]=num;
泡泡蛋白();
printcheap();
}
public void printHeap()引发IOException{
FileWriter f=新的FileWriter(out,true);
f、 写入(“当前堆:\t”);
对于(inti=1;i10)中断;
f、 写入(堆[i]+“”);
}
f、 写入(“\n”);
f、 close();
}
public void printSorted()引发IOException{
FileWriter f=新的FileWriter(out,true);
f、 写入(“当前排序:\t”);
对于(inti=1;i10)中断;
f、 写入(已排序的[i]+“”);
}
f、 写入(“\n”);
f、 close();
}
公共空间泡泡(){
int h=堆[0];
而(h>=2&&heap[h]
具有的输入文件(args[0])在文件中仅包含整数,其中一些整数位于同一行和不同的行上。args[1]是输出文件名


当程序通过bubbleDown时,它开始按照开始时的预期工作,但随后它跳过了一些数字,在接近结束时,我最终会看到一个应该在顶部的数字。有人能解释一下我在这个函数中做错了什么吗?

您的代码看起来可疑,原因有很多。1--您将实际的数据结构实现与读取毫无意义的文件混为一谈。很难理解。那么这件事就不对了:

sorted[i] = heap[1];
heap[1] = heap[heap[0]--];
第一行表示堆数组包含实际的数据元素。 但第二行是将堆内容作为某种索引处理?heap[0]--将递减存储在堆数组位置0处的值,但首先它将使用它将heap[0]]的内容移动到heap[1]?什么?您是否将heap[0]用作存储数组中最后一个元素的索引的特殊工具?我建议您从重写代码开始,不要像这样进行黑客攻击,这样应该更容易理解和修复。实际上,堆应该从元素0开始,左侧节点将在2k+1,右侧节点将在2k+2

现在这闻起来好像是错的:

right <= heap.length
所以代码应该是

if (heap[k] >= heap[left] && heap[left] < heap[right]) {
if(heap[k]>=heap[left]&&heap[left]

不客气。你的教授还欠我一顿午餐,感谢我为他做的工作。

我们在课堂上学习的方法是使用heap[0]作为当前堆中的元素总数,从heap[1]开始实际堆,左子使用2k,右子使用2k+1。说真的,这太可怕了。顺便说一句,在互联网出现之前的30年里,你应该考虑如何解决这个问题。(提示:这需要在每次操作后打印你的树,手动查看以验证它是否仍然满足堆树的不变量)
for (int i = 0; i < sorted.length; i++) {
   6
 /   \
7     4
if (heap[k] >= heap[left] && heap[left] < heap[right]) {