Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将元素按降序插入数组列表_Java_Sorting_Arraylist - Fatal编程技术网

Java 将元素按降序插入数组列表

Java 将元素按降序插入数组列表,java,sorting,arraylist,Java,Sorting,Arraylist,我试图在按降序排序的数组列表中的正确位置插入一个元素。 找到正确位置的复杂性必须为O(LOGN)。 这就是为什么我尝试使用二进制搜索来找到正确的位置。 这就是我所做的: 我补充说: 中=(低+高)/2 if(q.get(middle).getPriority() < x.getPriority()) { return middle + 1 ; } return middle; } 在while循环之后 问题在于它是按升序插入元素的。而不是降序 p

我试图在按降序排序的数组列表中的正确位置插入一个元素。 找到正确位置的复杂性必须为O(LOGN)。 这就是为什么我尝试使用二进制搜索来找到正确的位置。 这就是我所做的:

我补充说:

中=(低+高)/2

    if(q.get(middle).getPriority() < x.getPriority()) {
        return middle + 1 ;
    }
    return middle;

}
在while循环之后

问题在于它是按升序插入元素的。而不是降序

public void insert(E x) {

    if(q.size()==0){
        q.add(0, x);
    }
    else{
        int place = binarySearch(x);
        q.add(place, x);
    }
}

private int binarySearch (E x) {
    int size = q.size();
    int low = 0;
    int high = size - 1;
    int middle = 0;

    while(high > low) {
        middle = (low + high) / 2;
        if(q.get(middle).getPriority() == x.getPriority()) {
            return middle;
        }
        if(q.get(middle).getPriority() < x.getPriority()) {
            low = middle + 1;
        }
        if(q.get(middle).getPriority() > x.getPriority()) {
            high = middle - 1;
        }
    }
公共作废插入(E x){
如果(q.size()==0){
q、 添加(0,x);
}
否则{
int place=binarySearch(x);
q、 加上(地点x);
}
}
私有int二进制搜索(ex){
int size=q.size();
int低=0;
int高=大小-1;
int-middle=0;
while(高>低){
中等=(低+高)/2;
if(q.get(中间).getPriority()==x.getPriority()){
返回中间;
}
if(q.get(中间).getPriority()x.getPriority()){
高=中-1;
}
}
中等=(低+高)/2;

    if(q.get(middle).getPriority() < x.getPriority()) {
        return middle + 1 ;
    }
    return middle;

}
if(q.get(中间).getPriority()
您的代码有几个问题:

  • 你所有的比较方式都是错误的,因此你是按升序插入的
  • 您应该在(高>=低)时循环
    ,否则不能插入小于所有现有元素的元素;此外,您不再需要插入
    中的
    if/else
  • 如果要处理领带,以便首先对最旧的元素进行排序,请删除“与中间元素相同”复选框,并反转循环中的
    if/else
    ;这样,在绑定的情况下,
    low
    绑定被提升,在旧元素之后插入新元素
  • 现在,在
    while
    循环之后,您可以返回
    low
这似乎是可行的(注意:对于测试,更改为
Integer
而不是
E
,用随机整数填充初始空列表):

公共作废插入(E x){
q、 添加(二进制搜索(x),x);
}
私有int二进制搜索(ex){
int低=0;
int high=q.size()-1;
而(高>=低){
int-middle=(低+高)/2;
if(q.get(中间).getPriority()
测试和示例输出:

@Data @AllArgsConstructor
class E {
    int id, priority;
    public String toString() { return String.format("%d/%d", id, priority); }
}

Random random = new Random();
int id = 0;
for (int i = 0; i < 50; i++) {
    test.insert(new E(id++, random.nextInt(20)));
}
System.out.println(test.q);
// [2/19, 3/19, 24/19, 32/19, 46/19, 18/18, 23/18, 39/18, 31/17, 10/16, 28/16, 40/16, 45/16, 7/15, 19/14, 33/14, 37/14, 38/14, 36/13, 44/13, 5/11, 12/11, 15/11, 20/11, 30/11, 9/10, 41/10, 48/10, 16/9, 34/9, 13/8, 1/7, 8/7, 35/7, 0/6, 6/6, 22/6, 29/6, 21/5, 26/5, 42/5, 14/4, 27/4, 47/4, 25/3, 4/1, 11/1, 17/1, 43/1, 49/0]
@Data@allargsconstuctor
E类{
int-id,优先级;
公共字符串toString(){return String.format(“%d/%d”,id,priority);}
}
随机=新随机();
int id=0;
对于(int i=0;i<50;i++){
test.insert(新的E(id++,random.nextInt(20));
}
系统输出打印LN(测试q);
// [2/19, 3/19, 24/19, 32/19, 46/19, 18/18, 23/18, 39/18, 31/17, 10/16, 28/16, 40/16, 45/16, 7/15, 19/14, 33/14, 37/14, 38/14, 36/13, 44/13, 5/11, 12/11, 15/11, 20/11, 30/11, 9/10, 41/10, 48/10, 16/9, 34/9, 13/8, 1/7, 8/7, 35/7, 0/6, 6/6, 22/6, 29/6, 21/5, 26/5, 42/5, 14/4, 27/4, 47/4, 25/3, 4/1, 11/1, 17/1, 43/1, 49/0]

使用此选项可能会简单得多。如果找到索引,这些方法将返回该索引,或者返回一个与以下位置匹配的负值:

搜索键的索引(如果它包含在列表中);否则,((插入点)-1)。插入点定义为将键插入列表的点:大于键的第一个元素的索引,或者如果列表中的所有元素都小于指定键,则为list.size()。注意,这保证了当且仅当找到键时,返回值将>=0

下面是一个
SortedList

class SortedList<E> extends ArrayList<E>{

    Comparator<E> comparator;

    public SortedList(Comparator<E> comparator) {
        this.comparator = comparator;
    }

    @Override
    public boolean add(E e) {
        int index = Collections.binarySearch(this, e, comparator);

        if(index < 0){
            index = -index - 1;
        }
        if(index >= this.size()){
            super.add(e);
        } else {
            super.add(index, e);
        } 
        return true;
    }
}
class SortedList扩展了ArrayList{
比较器;
公共分类列表(比较器比较器){
这个比较器=比较器;
}
@凌驾
公共布尔加法(E){
int index=Collections.binarySearch(this,e,comparator);
如果(指数<0){
指数=-指数-1;
}
如果(索引>=此.size()){
增订(e);
}否则{
super.add(索引e);
} 
返回true;
}
}
以及一个降序测试用例:

SortedList<Integer> list = new SortedList<>(
             (i1,  i2) -> i2 - i1
        );
list.add(10);
list.add(20);
list.add(15);
list.add(10);

System.out.println(list);
SortedList=新的SortedList(
(i1,i2)->i2-i1
);
增加(10);
增加(20);
增加(15);
增加(10);
系统输出打印项次(列表);
[20,15,10,10]


构造函数中的
比较器
允许您设置用于插入的顺序。这并不是说这不安全,这并不是覆盖所有方法,但这是一个快速的答案;)

我的意思是找到正确位置的复杂性必须是O(LOGN)。我编辑了帖子。再次检查答案。我编辑了它。你能扩展一下吗?它工作不正常。@如果我加上这个,你就不能了:中间=(低+高)/2;在while循环之后,它将按升序插入元素。与降序相反,“它不工作”不是问题描述。调试您的代码并尝试本地化错误。我如何更改它,即首先插入的元素将是具有相同值的元素之间的第一个元素?