Java 插入到已排序的列表中
对于Java,我有一个名为TestClass的类,它有一个名为Name的成员,这是一个字符串。我还有一个这种类型的ArrayList,它已经按名称的字母顺序排序了。我想做的是找到放置TestClass新实例的最佳索引。到目前为止,我能想到的最佳方法是:Java 插入到已排序的列表中,java,arraylist,alphabetical,sorted,Java,Arraylist,Alphabetical,Sorted,对于Java,我有一个名为TestClass的类,它有一个名为Name的成员,这是一个字符串。我还有一个这种类型的ArrayList,它已经按名称的字母顺序排序了。我想做的是找到放置TestClass新实例的最佳索引。到目前为止,我能想到的最佳方法是: public static int findBestIndex(char entry, ArrayList<TestClass> list){ int desiredIndex = -1; int oldPivot =
public static int findBestIndex(char entry, ArrayList<TestClass> list){
int desiredIndex = -1;
int oldPivot = list.size();
int pivot = list.size()/2;
do
{
char test = list.get(pivot).Name.charAt(0);
if (test == entry)
{
desiredIndex = pivot;
}
else if (Math.abs(oldPivot - pivot) <= 1)
{
if (test < entry)
{
desiredIndex = pivot + 1;
}
else
{
desiredIndex = pivot - 1;
}
}
else if (test < entry)
{
int tempPiv = pivot;
pivot = oldPivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
else
{
int tempPiv = pivot;
pivot = pivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
} while (desiredIndex < 0);
return desiredIndex;
}
public static int findBestIndex(char条目,ArrayList列表){
int desiredIndex=-1;
int oldpoint=list.size();
int pivot=list.size()/2;
做
{
char test=list.get(pivot.Name.charAt(0);
如果(测试==条目)
{
desiredIndex=枢轴;
}
else if(Math.abs(oldprovot-pivot)您应该使用像PriorityQueue这样已经有秩序感的东西。插入到有秩序感的集合中会自动以最短的时间(通常为log(n)或更少)将元素放置在正确的位置
如果您希望在没有此选项的情况下执行任意插入,那么我建议使用不必重新引用或完全复制的LinkedList来插入单个项目,如您当前拥有的ArrayList。而为LinkedList找到正确的插入位置将需要高达O(n)实际上,它仍然比使用日志(n)搜索ArrayList中的正确位置要快,但随后需要对其进行复制或排序
此外,在链表中查找插入位置的代码要简单得多
if (next != null && next.compareTo(insertElement) > 0){
// You have the right location
}
可以使用其他数据结构代替列表,如树、优先级队列等。如前所述,没有理由自己实现,简单的代码示例:
class FooBar implements Comparable<FooBar> {
String name;
@Override
public int compareTo(FooBar other) {
return name.compareTo(other.name);
}
}
TreeSet<FooBar> foobarSet = new TreeSet<>();
FooBar f1;
foobarSet.add(new FooBar("2"));
foobarSet.add(f1 = new FooBar("1"));
int index = foobarSet.headSet(f1).size();
类FooBar实现了可比较的{
字符串名;
@凌驾
公共int比较(FooBar其他){
返回name.compareTo(其他.name);
}
}
TreeSet foobarSet=新树集();
福巴f1;
添加(新的FooBar(“2”));
添加(f1=新的FooBar(“1”));
int index=foobarSet.headSet(f1).size();
(基于)我认为问题在于这段代码:
else if (test < entry)
{
int tempPiv = pivot;
pivot = oldPivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
else
{
int tempPiv = pivot;
pivot = pivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
else if(测试
无论是testentry,您都在执行相同的操作。当您搜索的项目位于数组的开头时,这将导致线性搜索
我更喜欢使用(低和高)像
high=list.size();
低=0;
做{
枢轴=(高+低)/2;
如果(测试<输入){
低=枢轴;
}否则如果(测试>输入){
高=枢轴
}否则{
....
}
}而。。。;
制作自己的列表实现,在add方法中有以下几行:
wrappedList.add(object);
Collections.sort(wrappedList);
为此,使用SortedSet(例如TreeSet)可能不是一个好主意,因为集合不允许重复的元素。如果有重复的元素(例如同名的TestClass实例),则应使用列表。将元素插入到已排序的列表中非常简单:
void insert(List<TestClass> list, TestClass element) {
int index = Collections.binarySearch(list, element, Comparator.comparing(TestClass::getName));
if (index < 0) {
index = -index - 1;
}
list.add(index, element);
}
void插入(列表,TestClass元素){
int index=Collections.binarySearch(列表、元素、比较器.comparing(TestClass::getName));
如果(指数<0){
指数=-指数-1;
}
添加(索引、元素);
}
此代码需要Java 8或更高版本,但也可以重写以在较旧的Java版本中工作。为什么不插入所有元素,然后使用Collections.sort()
?也许我没有看到这一点,但如果您确定该值在所选(测试)之后point,你能检查一下数组的后半部分吗?@fge,每次插入后重新尝试可能是最慢的方式,尽管速度不是我最关心的,因为不太可能有很多对象被快速移入移出。@mbrach,这是我试图做的,但我这样做的尝试可能是完全错误的,一个nd是我遇到问题的地方。@user2423158这取决于访问此排序列表的频率。如果不是那么频繁,您可以在需要时重新构建该列表。我还认为我们应该使用可排序列表。在回答中,我们使用Comparable。另一个选项是使用Comparator。我不确定PriorityQueue或LinkedList是否最适合我所说的我必须说,你不想使用LinkedList b/c的原因是把ArrayList翻译成c会更容易些,这是不正确的。两种方法都同样容易翻译(我甚至会说LinkedList更容易些)。但最重要的是,如果不移动ArrayList后面的所有元素,就无法将元素插入ArrayList的中间。这涉及到复制ArrayList的该部分,速度明显慢于LinkedList插入。基本上,如果您是为了提高效率,则使用的数据结构是错误的。我选择ArrayList是因为熟悉,并且易于访问任何给定元素。然而,另一个数据结构可能是个好主意,尽管我必须先做一些研究。为什么这不是公认的答案(如果@user2423158想要接受一个…?它有在O(log(n))中工作的键)关于数组。谢谢!@Matthieu谢谢你的支持投票,我怀疑用户希望他的问题得到回答,之后就没有兴趣了。这与树无关。Set不允许重复元素谢谢你指出这一点。我相应地更改了措辞。
void insert(List<TestClass> list, TestClass element) {
int index = Collections.binarySearch(list, element, Comparator.comparing(TestClass::getName));
if (index < 0) {
index = -index - 1;
}
list.add(index, element);
}