将元素插入到Array List按降序排序

时间:2017-12-14 10:49:33

标签: java sorting arraylist

我正在尝试在按降序排序的数组列表中的正确位置插入元素。 找到正确位置的复杂性必须是O(LOGN)。 这就是我尝试使用二分搜索找到正确位置的原因。 这就是我所做的:

我补充说:

中=(低+高)/ 2;

在while循环之后

问题是它以升序插入元素。而不是降序

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

}

中=(低+高)/ 2;

class MailerController < ApplicationController
  def preview
    UserMailer.signup_confirmation # miss the user parameter
  end
end

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  • 所有比较都是错误的,因此您按升序插入
  • 你应该循环while (high >= low),否则你不能插入一个小于所有现有元素的元素;此外,您不再需要if/else
  • 中的insert
  • 如果您希望处理关系以使最旧的元素先排序,则删除“与中间相同”检查并反转循环中的if/else;这样,在绑定的情况下,low绑定被引发,在旧的元素之后插入新元素
  • 现在,在while循环之后,您可以返回low

这似乎有用(注意:更改为Integer而不是E进行测试,使用随机整数填充最初为空的列表。):

public void insert(E x) {
    q.add(binarySearch(x), x);
}

private int binarySearch (E x) {
    int low = 0;
    int high = q.size() - 1;
    while (high >= low) {
        int middle = (low + high) / 2;
        if (q.get(middle).getPriority() < x.getPriority()) {
            high = middle - 1;
        } else {
            low = middle + 1;
        }
    }
    return low;
}

测试和示例输出:

@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]

答案 1 :(得分:1)

使用Collections.binarySearch可能会更简单。如果找到索引,方法将返回索引,或返回与应该匹配的负值:

  

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

以下是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;
    }
}

以降序排列的测试用例:

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);
  

[20,15,10,10]

构造函数中的comparator允许您设置用于插入的顺序。并不是说这不安全,这并不是压倒每一种方法,但这是一个快速的答案;)