对于编程分配,我一直在创建一个程序来读取输入文件,并使用自制的最大堆优先级队列对数据进行排序。数据文件包含读取"插入[名称] [数字]"或"删除"的行。对于此优先级队列,我们需要创建一个插入和删除对象的函数。队列中的每个对象都包含名称作为字符串,优先级作为整数。我必须基于一个大小为255的数组来实现这个堆。
我的问题是,我在执行插入操作时遇到了困难,并且删除了按指定工作的功能。我将提供1)他们需要如何工作,2)我做过的伪代码,以及3)我实现的实际Java代码。我的两个函数都不能完全按照我的意图工作,所以我可以使用更有经验的程序员的指导。
1)insert(name,priority):此函数应采用string类型的名称和integer类型的优先级,并将它们插入优先级队列。 remove():此函数应删除具有最高优先级值的对象,并从对象返回名称字符串。
2)作为背景,我有三个课程:第一,"主要"包含用于读取文件和使用函数的实现的类。第二,"名称" class,用于创建包含名称字符串和优先级int的名称对象,构造函数和compareTo方法,用于比较两个对象的优先级值。第三," priorityqueue" class,包含insert和remove函数。现在,这是我为这两个函数制作的伪代码:
插入:
删除:
3)这是我到目前为止的代码。我会提供我的姓名和优先级队列课程,以防我的名字课给我带来麻烦。
优先级队列类:
public class PriorityQueue
{
int num; //amount of things in array
int idx; //index of current name object
Name[] names = new Name[255];
public void insert(String name, int priority)
{
while (num != 255)
{
Name addName = new Name(name, priority);
names[num] = addName;
num++;
while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp;
idx = (idx-1)/2;
}
}
}
public Name remove()
{
Name temp2 = names[0];
//Save first element
names[0] = names[idx];
//Move last element to first
num--;
while(idx < Math.max(2*idx+1,2*idx+2))
{
if(names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp3 = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp3;
}
}
return temp2;
}
}
名称类:
public class Name implements Comparable
{
String name;
int priority;
public Name(String n, int i)
{
name = n;
priority = i;
}
public boolean CompareTo(Name obj)
{
if(priority < obj.priority)
{
return false;
}
else if(priority > obj.priority)
{
return true;
}
return true;
}
}
我感谢任何帮助。谢谢!
答案 0 :(得分:0)
几个问题。首先,在您的#Ecto.Changeset<action: :insert, changes: %{cnpj: "01578216908926", roles: [#Ecto.Changeset<action: :insert, changes: %{}, errors: [name: {"is invalid", [type: :string]}], data: #Module.Role<>, valid?: false>], name: "xxx"}, errors: [], data: #Module.User<>, valid?: false>
方法中:
insert
public void insert(String name, int priority)
{
while (num != 255)
{
Name addName = new Name(name, priority);
names[num] = addName;
num++;
while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
{
Name temp = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp;
idx = (idx-1)/2;
}
}
}
不应该在那里。您应该检查是否while (num != 255)
,如果是,则抛出异常。
然后,您需要初始化num == 255
。那就是:
idx
您的 Name addName = new Name(name, priority);
names[num] = addName;
idx = num;
num++;
条件应使用while
而不是&&
。否则,每当||
不等于0时,您就会进行交换。
在idx
方法中:
remove
你不希望public Name remove()
{
Name temp2 = names[0];
//Save first element
names[0] = names[idx];
//Move last element to first
num--;
while(idx < Math.max(2*idx+1,2*idx+2))
{
if(names[idx].CompareTo(names[(idx-1)/2]) > 0)
{
Name temp3 = names[idx];
names[idx] = names[(idx-1)/2];
names[(idx-1)/2] = temp3;
}
}
return temp2;
}
出现在那里,因为你不知道names[idx]
是什么。你想要:
idx
这里的names[0] = names[num-1]; // get last item in the heap
条件很愚蠢。 while
将始终返回Math.max(2*idx+1,2*idx+2)
,除非2*idx+2
为否定。而且,你甚至没有初始化idx
。你想要的是:
idx
现在,您要做的是查看idx = 0;
while (idx < num)
是否小于其中一个孩子。如果是这样,请选择两个孩子中最大的孩子进行交换。所以:
names[idx]
我建议在两种方法中使while (idx < num)
{
int largestChild = idx*2+1;
if (largestChild >= num) break; // idx is at a leaf level
if (largestChild+1 < num)
{
// compare the two children
if (names[largestChild].compareTo(names[largestChild+1]) < 0)
{
largestChild = largestChild+1;
}
}
if (names[idx] < names[largestChild])
{
// swap, moving the item down
temp = names[idx];
names[idx] = names[largestChild];
names[largestChild] = temp;
idx = largestChild;
}
else
{
// item is in the proper place
break;
}
}
成为方法范围的变量。它不需要它是全局的,并且使它在方法本地强制您在使用它之前初始化它,而不是潜在地(如在现有代码中)使用陈旧值。
我认为您需要更改idx
班级Name
功能。 $project CompareTo
函数必须返回:
负整数,零或正整数,因为此对象小于,等于或大于指定对象。
所以你应该:
compareTo