Java:遍历并将元素插入排名链表的最佳方法是什么?

时间:2018-04-15 20:30:58

标签: java linked-list

由于链表的头部和尾部频繁插入和删除,我选择使用Java API中的链表。链表将按降序排列,即100,98,97,95,90

LinkedList<MyObject> mylinkedlist = new LinkedList<MyObject>();

Myobject new_value = new MyObject(96);

偶尔我必须在此链接列表中插入元素(不在头部和尾部)。因为链接列表必须按降序排列,所以我必须从头部以降序遍历链接列表或从尾部升序遍历链接列表,然后将其插入到正确的列表中指数。

我想出了一个尝试如下

  int i;
  for(int i=0; i<mylinkedlist.size(); i++)
  {
      if(mylinkedlist.get(num).getInt() <= new_value.getInt()){
         break;
      }
  }

   mylinkedlist.add(i,new_value)

我可以告诉我上面的代码真的很差。但是,有没有办法优化我的代码并避免使用break同时避免遍历整个链表,因为它可能超长?

如果可以提供代码示例,将非常感激。感谢。

更新:真诚的道歉,没有正确地填写我的问题。我的问题应该是,鉴于链表目前包含100,98,97,95,90,如果我想插入一个新的不同的值,请说96。如何检测链表的索引,以便可以将新值96插入其中,同时保留链表的降序?

在此问题中保留列表的(1)降序和(2)列表中元素的唯一性非常重要。

2 个答案:

答案 0 :(得分:1)

如果您必须使用列表,则可以使用标准API获得相同的结果:Collections.binarySearch方法提供您正在寻找的功能。

所以代码类似于以下内容:

private static void insert(List<MyObject> items, MyObject newValue) {
  int insertionPoint =
      Collections.binarySearch(items, 
                               newValue, 
                               // reversed comparator is used because the items are in DESC order
                               Comparator.comparingInt(MyObject::getInt).reversed());
  // if newValue is not in the list, insertionPoint will be negative, see javadoc
  int i = (insertionPoint < 0) ? -insertionPoint - 1 : insertionPoint;
  // add it at i, even if duplicate (?)
  items.add(i, newValue);
}

javadoc提供了有关其效率的一些细节:

  

此方法在log(n)时间内运行“随机访问”列表(提供接近恒定时间的位置访问)。如果指定的列表没有实现RandomAccess接口并且很大,则此方法将执行基于迭代器的二进制搜索,该搜索执行O(n)链接遍历和O(log n)元素比较。

如果列表变得庞大并且您开始寻找效率,我建议切换到实现ArrayList的{​​{1}},并且只要遵守项目的顺序,它就会更有效。

如果您的集合不允许重复,那么使用排序集会更好。

答案 1 :(得分:1)

您应该考虑使用其他数据结构,TreeSet

此类实现SortedSet并使用自然排序或创建时提供的比较器。然后你只需添加对象,它就会自动排序。

使用自然排序

在MyObject类中:

public int compareTo(MyObject o) {
    return this.getInt() - o.getInt()
}

使用TreeSet:

SortedSet<MyObject> objectSet = new TreeSet<MyObject>();
Myobject newObject = new MyObject(95);
objectSet.add(newObject);

使用比较器

如果您不想修改MyObject类(例如):

class MyObjectComp implements Comparator<MyObject> {

    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getInt() - o2.getInt();
    }

}

SortedSet<MyObject> objectSet = new TreeSet<MyObject>(new MyObjectComp());
Myobject newObject = new MyObject(95);
objectSet.add(newObject);

降序集

对于降序集,可以使用TreeSet的descendingSet方法:

SortedSet<MyObject> objectSet = new TreeSet<MyObject>(new MyObjectComp()).descendingSet();
Myobject newObject = new MyObject(95);
objectSet.add(newObject);

有关Java中排序结构的更多信息,请阅读this question