为什么不是';bubbleDown方法是否按预期工作(堆排序)? 这是一个任务,我尝试了C++和java,但是在两个版本中,冒泡方法都没有按照预期的方式工作,尽管我相信逻辑应该是这样。我已经提交了两个版本,但是由于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 {
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]) {