Inserting an element into a sorted list

我的梦境 提交于 2020-01-24 11:34:11

问题


Ok I'm using getSharedPreferences to store my high score but before I fill it up I wanted to sort the scores into ascending order via and array, but if it finds a Score less than it in the first pos then it wont check the rest for the smallest?

    //function to add score to array and sort it
    public void addscoretoarray(int mScore){
    for(int pos = 0; pos< score.length; pos++){
        if(score[pos]  > mScore){
            //do nothing
        }else {
                //Add the score into that  position
                score[pos] = mScore;
                break;
            }
    }
    sortArray(score);
}

should I call sortArray() before and after the loop to fix this problem or is there a better method to achieve the same results?

I should also mention that the sortArray(score) function is just calling Arrays.sort(score) where score is an array of mScore

EDIT: based on what @Vincent Ramdhanie posted I have revised the post:

    public void addscoretoarray(int mScore){
    int pos = score.length; 
    //sort the array (in ascending order)
    sortArray(score);

    //go though the array( in descending order) and check for a place that suits the conditions
    while(pos>=0 && score[pos] > mScore){ 
         pos--; //do nothing as score[pos] is larger than mScore
    }
     //so once a pos is found (e.g. broke out of the while loop)
     //check that it is still in the list
    if(pos >= 0){
        //if it is then move everything down 1 position
        for(int i = 0; i < pos; i++){
            score[i] = score[i+1];
        }
        //replace the initial pos with the new score
        score[pos] = mScore;
    }
}

I still believe that it will drop off the list when in the for(int i = 0; i < pos; i++){ loop.


回答1:


Why not keep the array of scores sorted. So your add score to array will assume that the array is sorted in descending order all the time. The new score to be inserted will simply push the lowest score off the array as it is inserted. You can then use an insert algorithm something like this:

   insertScore(int[] scores, int mscore){
        //find insert point
        int i = 0;
        while(i < scores.length && scores[i] > mscore){
            i++;
        }
        if(i < scores.length){
            //you found a place to insert the score
            for(int j = scores.length-1; j > i; j--){
                scores[j] = scores[j - 1];
            }
            scores[i] = mscore;
        }
   }

In this case there is no need to resort the array.




回答2:


If I understood your correctly then I suggest this

    int[] a1 = { 1, 2, 3, 4, 6 };
    int mScore = 5;

    int[] a2 = new int[a1.length + 1];
    Arrays.sort(a1);
    int p = Arrays.binarySearch(a1, mScore);
    if (p < 0) {
        p = -p - 1;
        System.arraycopy(a1, 0, a2, 0, p);
        System.arraycopy(a1, p, a2, p + 1, a1.length - p);
        a2[p] = mScore;
    }
    System.out.println(Arrays.toString(a2));

output

[1, 2, 3, 4, 5, 6]

Note that it inserts only unique values




回答3:


See javadoc to @return of binarySearch:

Returns the index of the search key, if it is contained in the list; otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size() if all elements in the list are less than the specified key. Note that this guarantees that the return value will be >= 0 if and only if the key is found.




回答4:


public void addscoretoarray(int mScore){
    for(int pos = 0; pos< score.length; pos++){
        if(score[pos]  > mScore){
            //do nothing
        }else {
                //Add the score into that  position
                score[pos] = mScore;
                break;
            }
    }
    sortArray(score);
}

there are some major bugs in the code.

  1. score[pos] = mScore; in this statement, you are assigning mScore at position pos which will result in the value stored at pos being lost.

  2. If you are using an array, then to store any element in between, you need to move all the remaining elements 1 position to the right, which you are not doing here.

  3. score[pos] = mScore; break;

the break will break the loop in the first iteration itself, after storing the element at pos.

Suggestion :

Use arraylist instead of native array. Modified pseudo code:

public void addscoretoarray(int mScore){
    int index = getFirstIndexOfScoreGreaterThanmScore(); // need to implement it
    if(index == -1){ // no element greater than mscore
    score.add(mScore);
    }else{
    score.add(index,mScore);
}
//   sortArray(score); // no need to call this if the list is initially empty as the insertion will be in sorted order itself
if(score.length == maxSize){
//do whateverwhen the list is full as per your requirements
}
}


来源:https://stackoverflow.com/questions/13776593/inserting-an-element-into-a-sorted-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!