Inserting into Sorted LinkedList Java

前端 未结 7 1286
闹比i
闹比i 2021-01-02 11:59

I have this code below where I am inserting a new integer into a sorted LinkedList of ints but I do not think it is the \"correct\" way of doing things as I know there are s

相关标签:
7条回答
  • 2021-01-02 12:22

    If we use listIterator the complexity for doing get will be O(1).

    public class OrderedList<T extends Comparable<T>> extends LinkedList<T> {
    
        private static final long serialVersionUID = 1L;
    
    
        public boolean orderedAdd(T element) {      
            ListIterator<T> itr = listIterator();
            while(true) {
                if (itr.hasNext() == false) {
                    itr.add(element);
                    return(true);
                }
    
                T elementInList = itr.next();
                if (elementInList.compareTo(element) > 0) {
                    itr.previous();
                    itr.add(element);
                    System.out.println("Adding");
                    return(true);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-02 12:25

    You have to find where to insert the data by knowing the order criteria.

    The simple method is to brute force search the insert position (go through the list, binary search...).

    Another method, if you know the nature of your data, is to estimate an insertion position to cut down the number of checks. For example if you insert 'Zorro' and the list is alphabetically ordered you should start from the back of the list... or estimate where your letter may be (probably towards the end). This can also work for numbers if you know where they come from and how they are distributed. This is called interpolation search: http://en.wikipedia.org/wiki/Interpolation_search

    Also think about batch insert: If you insert a lot of data quickly you may consider doing many insertions in one go and only sort once afterwards.

    0 讨论(0)
  • 2021-01-02 12:31

    Have a look at com.google.common.collect.TreeMultiset.

    This is effectively a sorted set that allows multiple instances of the same value.

    It is a nice compromise for what you are trying to do. Insertion is cheaper than ArrayList, but you still get search benefits of binary/tree searches.

    0 讨论(0)
  • 2021-01-02 12:33

    @Atrakeur

    "sorting all the list each time you add a new element isn't efficient"

    That's true, but if you need the list to always be in a sorted state, it is really the only option.

    "The best way is to insert the element directly where it has to be (at his correct position). For this, you can loop all the positions to find where this number belong to"

    This is exactly what the example code does.

    "or use Collections.binarySearch to let this highly optimised search algorithm do this job for you"

    Binary search is efficient, but only for random-access lists. So you could use an array list instead of a linked list, but then you have to deal with memory copies as the list grows. You're also going to consume more memory than you need if the capacity of the list is higher than the actual number of elements (which is pretty common).

    So which data structure/approach to take is going to depend a lot on your storage and access requirements.

    [edit] Actually, there is one problem with the sample code: it results in multiple scans of the list when looping.

    int i = 0;
    while (llist.get(i) < val) {
        i++;
    }
    llist.add(i, val);
    

    The call to get(i) is going to traverse the list once to get to the ith position. Then the call to add(i, val) traverses it again. So this will be very slow.

    A better approach would be to use a ListIterator to traverse the list and perform insertion. This interface defines an add() method that can be used to insert the element at the current position.

    0 讨论(0)
  • This might serve your purpose perfectly:

    Use this code:

    import java.util.*;
    
    public class MainLinkedList {
        private static LinkedList<Integer> llist;
    
        public static void main(String[] args) {
            llist = new LinkedList<Integer>();
    
            addValue(60);
            addValue(30);
            addValue(10);
            addValue(-5);
            addValue(1000);
            addValue(50);
            addValue(60);
            addValue(90);
            addValue(1000);
            addValue(0);
            addValue(100);
            addValue(-1000);
            System.out.println("Linked List is: " + llist);
    
        }
    
        private static void addValue(int val) {
    
            if (llist.size() == 0) {
                llist.add(val);
            } else if (llist.get(0) > val) {
                llist.add(0, val);
            } else if (llist.get(llist.size() - 1) < val) {
                llist.add(llist.size(), val);
            } else {
                int i = 0;
                while (llist.get(i) < val) {
                    i++;
                }
                llist.add(i, val);
            }
    
        }
    
    }
    

    This one method will manage insertion in the List in sorted manner without using Collections.sort(list)

    0 讨论(0)
  • 2021-01-02 12:39

    Linked list isn't the better implementation for a SortedList

    Also, sorting all the list each time you add a new element isn't efficient. The best way is to insert the element directly where it has to be (at his correct position). For this, you can loop all the positions to find where this number belong to, then insert it, or use Collections.binarySearch to let this highly optimised search algorithm do this job for you.

    BinarySearch return the index of the object if the object is found in the list (you can check for duplicates here if needed) or (-(insertion point) - 1) if the object isn't allready in the list (and insertion point is the index where the object need to be placed to maintains order)

    0 讨论(0)
提交回复
热议问题