簡體   English   中英

將元素插入到數組列表的降序排列

[英]Insert an element to Array List sorted descending order

我正在嘗試將元素按降序排列的數組列表中的正確位置插入。 查找正確位置的復雜度必須為O(LOGN)。 這就是為什么我嘗試使用二進制搜索來找到正確的位置的原因。 這是我所做的:

我補充說:

中=(低+高)/ 2;

在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;
        }
    }

中=(低+高)/ 2;

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

}

您的代碼存在一些問題:

  • 您所有的比較都是錯誤的方式,因此您以升序插入
  • 您應while (high >= low)循環while (high >= low) ,否則不能插入小於所有現有元素的元素; 同樣,您不再需要在insert使用if/else
  • 如果您希望處理關系以使最早的元素排在最前面,則刪除“與中間相同”檢查,並在循環內反轉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]

使用Collections.binarySearch可能會容易得多。 如果找到索引,這些方法將返回索引,或者返回一個與之匹配的負值:

搜索關鍵字的索引(如果包含在列表中); 否則為(-(插入點)-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;
    }
}

還有一個降序測試用例:

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允許您設置插入順序。 並不是說這並不安全,不是覆蓋所有方法,而是一個快速的答案;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM