获取堆排序以升序打印
该程序采用一个长度为 n 的数组,并使用堆排序来取出最小的 k 个元素。我已经从数组中取出了 k 个最小元素,但我已经尝试了几个小时才能让它们按升序打印。几乎完整的二叉树正在正确构建,基于father > 。儿子。如果有人可以帮助我弄清楚我需要做什么,我将不胜感激。
另外,这是一项家庭作业,我并不是要求代码来修复它。我确实被难住了,只想设置在正确的路径上以使其正常工作。预先感谢您的任何意见。
编辑-我有点让它按升序输出,对于我目前正在进行的基本测试: 5,6,31,34,29,
import java.lang.*;
import java.util.*;
public class heap {
/*
* Definitions of the parameters
* 1) tree: the array where the sweeping window is implemented
* 2) newEle: the new element to insert
* 3) pos: where to insert the new element initially.
* note it does not mean newEle is going to
* stay at pos after this function
* 4) increment
* a) true: insert newEle, that is all
* b) false: insert newEle and then remove the root
*/
static void insertHeapTreeAt(int[] tree, int newEle,
int pos, boolean increment) {
int temp;
//place first element in, no need to start tree yet
if (tree[0] == 0) {
tree[0] = newEle;
}
//increment is true, sliding window isn't full yet
if (increment == true) {
tree[pos] = newEle;
//create tree
createTree(tree);
} else {
//increment is false, if larger than root do nothing
//place in pos (being k+1), then swap with root.
//then createTree slides everything so father > son
if (newEle < tree[0]) {
tree[pos] = newEle;
temp = tree[0];
tree[0] = tree[pos];
tree[pos] = 0;
createTree(tree);
}
}
//Then need to compare the root down the tree to check for father>=son
}
static void createTree(int[] tree) {
int i, father, son;
for (i = 1; i < tree.length; i++) {
int leaf = tree[i];
son = i;
father = (son - 1) / 2;
while (son > 0 && tree[father] < tree[son]) {
tree[son] = tree[father];
tree[father] = leaf;
son = father;
father = (son - 1) / 2;
}
}
// sort(tree);
}
static void sort(int[] tree) {
int father, larger, temp;
//father = 0;
for (int i = tree.length - 1; i > 0; i--) {
//No need to bubble down bc only 1 node
if (i - 1 == 0) {
break;
}
//two nodes, root and son
if (i - 1 == 1) {
//then the larger son has to be left (index = 1)
larger = 1;
} else {
//compare left/right sons for larger
larger = (tree[1] > tree[2]) ? 1 : 2;
}
//bubble down from root
father = 0;
while (tree[father] < tree[larger]) {
temp = tree[father];
tree[father] = tree[larger];
tree[larger] = temp;
father = larger;
if (2 * father + 1 > i - 1) {
break; //no son, rofl
} else if (2 * father + 1 > i - 1) {
larger = 2 * father + 1; //only left son
} else {
larger = (tree[2 * father + 2] > tree[2 * father + 1]) ? 2 * father + 2
: 2 * father + 1;
}
}
}
}
static void sortAscending(int[] x){
int father, son, temp;
for (int i = 0; i < x.length-1; i++) {
son = i;
father = (son - 1) / 2;
//while (son > 0 && x[father] > x[son]) {
while(x[father] > x[son]){
temp = x[son];
x[son] = x[father];
x[father] = temp;
son = father;
father = (son - 1) / 2;
}
}
}
/*
* get the smallest k elements in array x in O(nlogn) time, where
* n is the size of array x.
*
* It is supposed to return an array, containing the smallest k elements
* in the increasing order.
*/
static int[] getSmallestK(int x[], int k) {
if (k > x.length) {
return null;
}
int[] result = new int[k + 1];
// use the first k elements in x to construct an
// almost complete binary tree, where father>=sons
result[0] = x[0];
for (int i = 1; i < k; i++) {
insertHeapTreeAt(result, x[i], i, true);
}
// for each element in the rest of array x,
// insert it in the almost complete binary tree, and then
// remove the root in the tree.
for (int i = k; i < x.length; i++) {
insertHeapTreeAt(result, x[i], k, false);
}
// now the first k elements in result are the smallest k elements in x
// sort the first k elements in result in O(klogk) time
sortAscending(result);
//sort(result);
return result;
}
public static void main(String[] args) {
// Basic Testing
int[] data = {31, 44, 64, 5, 61,
43, 6, 88, 59, 90,
39, 97, 77, 62, 99,
34, 57, 53, 60, 29};
int[] smallestK = getSmallestK(data, 5);
for (int i = 0; i < 5; i++) {
System.out.print(smallestK[i] + ",");
}
System.out.println();
// More Complete Testing
Random random = new Random();
List<Integer> numsList = new ArrayList<Integer>();
int[] numsArray = new int[1000];
for (int i = 0; i < 1000; i++) {
int rand = 0;
do {
rand = random.nextInt(1000);
} while (numsList.contains(rand));
numsList.add(rand);
numsArray[i] = rand;
}
Collections.sort(numsList);
int[] smallest100 = getSmallestK(numsArray, 100);
for (int i = 0; i < 100; i++) {
System.out.print(smallest100[i] + ",");
}
System.out.println();
for (int i = 0; i < 100; i++) {
System.out.print(numsList.get(i) + ",");
}
for (int i = 0; i < 100; i++) {
if (numsList.get(i) != smallest100[i]) {
throw new RuntimeException("Error");
}
}
}
}
This program takes an array of n length, and uses heapsort to pull the smallest k elements back out. I have gotten the k number smallest elements out of the array, but I have been trying for several hours now to get them to print in ascending order. The almost complete binary tree is building correctly, based upon father > son. If someone could help me figure out what I need to do I would greatly appreciate it.
Also, this is a homework assignment and I'm not asking for the code to fix it. I am legitimately stumped, and would just like to be set on the correct path to get it working correctly. Thanks in advance for any input.
Edit - I kind of have it to output in ascending order, for the basic test I currently am getting:
5,6,31,34,29,
import java.lang.*;
import java.util.*;
public class heap {
/*
* Definitions of the parameters
* 1) tree: the array where the sweeping window is implemented
* 2) newEle: the new element to insert
* 3) pos: where to insert the new element initially.
* note it does not mean newEle is going to
* stay at pos after this function
* 4) increment
* a) true: insert newEle, that is all
* b) false: insert newEle and then remove the root
*/
static void insertHeapTreeAt(int[] tree, int newEle,
int pos, boolean increment) {
int temp;
//place first element in, no need to start tree yet
if (tree[0] == 0) {
tree[0] = newEle;
}
//increment is true, sliding window isn't full yet
if (increment == true) {
tree[pos] = newEle;
//create tree
createTree(tree);
} else {
//increment is false, if larger than root do nothing
//place in pos (being k+1), then swap with root.
//then createTree slides everything so father > son
if (newEle < tree[0]) {
tree[pos] = newEle;
temp = tree[0];
tree[0] = tree[pos];
tree[pos] = 0;
createTree(tree);
}
}
//Then need to compare the root down the tree to check for father>=son
}
static void createTree(int[] tree) {
int i, father, son;
for (i = 1; i < tree.length; i++) {
int leaf = tree[i];
son = i;
father = (son - 1) / 2;
while (son > 0 && tree[father] < tree[son]) {
tree[son] = tree[father];
tree[father] = leaf;
son = father;
father = (son - 1) / 2;
}
}
// sort(tree);
}
static void sort(int[] tree) {
int father, larger, temp;
//father = 0;
for (int i = tree.length - 1; i > 0; i--) {
//No need to bubble down bc only 1 node
if (i - 1 == 0) {
break;
}
//two nodes, root and son
if (i - 1 == 1) {
//then the larger son has to be left (index = 1)
larger = 1;
} else {
//compare left/right sons for larger
larger = (tree[1] > tree[2]) ? 1 : 2;
}
//bubble down from root
father = 0;
while (tree[father] < tree[larger]) {
temp = tree[father];
tree[father] = tree[larger];
tree[larger] = temp;
father = larger;
if (2 * father + 1 > i - 1) {
break; //no son, rofl
} else if (2 * father + 1 > i - 1) {
larger = 2 * father + 1; //only left son
} else {
larger = (tree[2 * father + 2] > tree[2 * father + 1]) ? 2 * father + 2
: 2 * father + 1;
}
}
}
}
static void sortAscending(int[] x){
int father, son, temp;
for (int i = 0; i < x.length-1; i++) {
son = i;
father = (son - 1) / 2;
//while (son > 0 && x[father] > x[son]) {
while(x[father] > x[son]){
temp = x[son];
x[son] = x[father];
x[father] = temp;
son = father;
father = (son - 1) / 2;
}
}
}
/*
* get the smallest k elements in array x in O(nlogn) time, where
* n is the size of array x.
*
* It is supposed to return an array, containing the smallest k elements
* in the increasing order.
*/
static int[] getSmallestK(int x[], int k) {
if (k > x.length) {
return null;
}
int[] result = new int[k + 1];
// use the first k elements in x to construct an
// almost complete binary tree, where father>=sons
result[0] = x[0];
for (int i = 1; i < k; i++) {
insertHeapTreeAt(result, x[i], i, true);
}
// for each element in the rest of array x,
// insert it in the almost complete binary tree, and then
// remove the root in the tree.
for (int i = k; i < x.length; i++) {
insertHeapTreeAt(result, x[i], k, false);
}
// now the first k elements in result are the smallest k elements in x
// sort the first k elements in result in O(klogk) time
sortAscending(result);
//sort(result);
return result;
}
public static void main(String[] args) {
// Basic Testing
int[] data = {31, 44, 64, 5, 61,
43, 6, 88, 59, 90,
39, 97, 77, 62, 99,
34, 57, 53, 60, 29};
int[] smallestK = getSmallestK(data, 5);
for (int i = 0; i < 5; i++) {
System.out.print(smallestK[i] + ",");
}
System.out.println();
// More Complete Testing
Random random = new Random();
List<Integer> numsList = new ArrayList<Integer>();
int[] numsArray = new int[1000];
for (int i = 0; i < 1000; i++) {
int rand = 0;
do {
rand = random.nextInt(1000);
} while (numsList.contains(rand));
numsList.add(rand);
numsArray[i] = rand;
}
Collections.sort(numsList);
int[] smallest100 = getSmallestK(numsArray, 100);
for (int i = 0; i < 100; i++) {
System.out.print(smallest100[i] + ",");
}
System.out.println();
for (int i = 0; i < 100; i++) {
System.out.print(numsList.get(i) + ",");
}
for (int i = 0; i < 100; i++) {
if (numsList.get(i) != smallest100[i]) {
throw new RuntimeException("Error");
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
传递 比较器< /a> 到实现堆的函数。要更改排序顺序,请传递不同的
Comparator
。然后
等等
Pass a Comparator to functions that implement the heap. To change the sort order, pass a different
Comparator
.then
etc.