[Two sorting algorithm] Selection Sort

Selection Sort (Selection sort) is a straightforward sorting algorithm. Its working principle is: the first data element to be sorted from the selected minimum (or maximum) of an element stored in the starting position of the sequence, and then to find from the remaining unsorted elements to a minimum (large) elements, and then into the end of the sequence sorted. And so on, until all the number of data elements to be sorted is zero. Select sort is unstable sorting method.

Algorithm performance

  • Time complexity: O (n ^ 2), total number of cycles n (n-1) / 2. Data exchange times O (n), this point is better than the bubble sort, because the bubble is a data bit shift up, selecting the sort only once at the end of the mobile sub-cycles. In extreme cases bubbling, the number of exchanges is O (n ^ 2)
  • Stability: Unstable

Why say this cargo is unstable Nirvana

For example for instance, there is such an array [5, 2, 5 *], it is assumed 5*that 5, where an asterisk is added to distinguish the first 5. Use of this array selection sort, the end result is [2, 5* ,5], the destruction of 5this sort of element in the original array, so that this cargo is unstable.

Algorithm steps:

  • First, find the smallest sequence of unsorted (large) element, the starting position is stored in the sorted sequence.
  • From the remaining unsorted then continue to look for the minimum element (large) element, and then into the end of the sorted sequence.
  • The second step is repeated until all the elements are sorted completed.

And Pirates of the map, and request understanding again ...

The above algorithm steps have called word 未排序序列, explain a little here under:

Suppose there is a need to sort the array of 10 digits, 10 that initially this number is not ordered sequence,
after the first cycle, we will subscript Alternatively [0] in the array element to the smallest number, that this element has been sorted, and that the remaining subscripts [1-9] of nine digits is not sorted sequence.

To give an example, the array [1, 7, 4, 8]:

  1. Subscript for the 0element 1does not move, traversing behind the figures 7, 4, 8, find the minimum number is 4, the lower its record at index 2, because 1 < 4, so do not do anything, the array is still[1, 7, 4, 8]
  2. Subscript 1element 7does not move, the latter traverse the number 4, 8, the smallest number is found 4, the record is an index to it 2, because 7 > 4, so the subscripts 1and subscript for the 2element exchange, into an array[1, 4, 7, 8]
  3. ... Continue the above steps until all the elements traversed again

Thus look down, the process is very simple, that is, two nested code to achieve the following:

public void Sort1(int[] numbers)
{
    var count1 = 0;
    var count2 = 0;

    var length = numbers.Length;

    for (var i = 0; i < length; i++)
    {
        var minIndex = i;

        for (var j = i + 1; j < length; j++)
        {
            if (numbers[j] < numbers[minIndex])
            {
                minIndex = j;
            }

            count1++;
        }

        if (minIndex != i)
        {
            var temp = numbers[i];
            numbers[i] = numbers[minIndex];
            numbers[minIndex] = temp;

            count2++;
        }
    }

    Console.WriteLine($"结果:{string.Join(",", numbers)};循环次数:{count1};交换次数:{count2}");
}

Algorithm optimization

Select sort core idea is nothing less than unsorted compare with the first element in the sequence and other elements of the smallest element, if the first element is relatively large, then swap the two elements.
Diverge a bit, because it is a traversal, if both the minimum and maximum two elements to find out, are not sorted with the first element and the last element of the sequence comparison, not a one-time two elements are able to sort it? As a result, the number of traverse will need only half the length of the array can, think about the people excited.

Given the array [4, 7, 3, 8, 6]for the first time through the loop:

  • Minimum is found 3, it will be interchangeable with the first element[3, 7, 4, 8, 6]
  • Maximum is found 8, it will be interchangeable with the last element[3, 7, 4, 6, 8]

Thus in one cycle, we find the minimum and maximum values of the array, and placing them in the appropriate location in the array. In other words, an array of first and last elements are sorted, this time, did not become a sort sequence 7, 4, 6, then we only need these three elements can be re-sorted.

Of course, things are not always so some wind along, at first glance the above ideas are OK, but it is still a bit of pits.

Due to the simultaneous operation of two maximum and minimum elements, so we need to traverse after a two swap operations, the general order is processed minimum, maximum and then deal with that problem comes,
when no sort of sequence one than the other items are large in the case, such as: [9, 8, 7, 6]our general idea is this:

  • The first element, the subscript 0value9
  • Declares two variables, save for the minimum value of the remaining elements and subscripts, the first element of the initialization point var min = 9; var minIndex = 0;
  • Declares two variables, for holding the maximum value and the remaining elements of the subscript, point to initialize the first element var max = 9; var maxIndex = 0;
  • Traversal8, 7, 6
  • Find the minimum value for the 6index is 3, the minimum update their indexesmin = 6; minIndex = 3;
  • Ratio did not find 9a larger element, so in this case the maximum value and the index is stillmax = 9; maxIndex = 0;
  • Processed first minimum found 9 > 6required both (subscript is [0] element and subscripts [3] elements) exchange, then swap into the array [6,8,7,9]
  • Then deal with the maximum, our idea is that the index is maxIndexthe last element of interchangeable elements, then the maximum value of the subscript is 0the last element of the index is 3, what if the two straight swap will happen situation? Since the first [0] elements have already taken place with the first exchange [3] elements, the current array already [6,8,7,9], and back again, then change back to [9,8,7,6], which is obviously not , in fact, when the end of the previous step, the maximum value of [9] has become a subscript minIndex, so there need to take care maxIndex point, it refers to [9] the current positionmaxIndex = minIndex

Rory it repetitious pile he saw all dizziness, or directly on the bar code

public void Sort3(int[] arr)
{
    var len = arr.Length;
    var left = 0;
    var right = len - 1;

    var count1 = 0;
    var count2 = 0;

    while (left < right)
    {
        int max = left;//记录无序区最大元素下标
        int min = left;//记录无序区最小元素下标
        int j = 0;
        for (j = left + 1; j <= right; j++)
        {
            //找最大元素下标
            if (arr[j] < arr[min])
            {
                min = j;
            }
            //找最小元素下标
            if (arr[j] > arr[max])
            {
                max = j;
            }

            count1++;
        }

        //最小值如果是第一个则没有必要交换
        if (min != left)
        {
            int tmp = arr[left];
            arr[left] = arr[min];
            arr[min] = tmp;

            count2++;
        }

        // 手动高亮
        // left 是第一个元素的下标,max是最大值的下标,
        // left == max 说明第一个元素的值比剩余元素都大,这时就需要更新索引
        if (max == left)
        {
            max = min;
        }

        //最大值如果是最后一个则没必要交换
        if (max != right)
        {
            int tmp = arr[right];
            arr[right] = arr[max];
            arr[max] = tmp;

            count2++;
        }
        left++;
        right--;
    }

    Console.WriteLine($"结果:{string.Join(",", arr)};循环次数:{count1};交换次数:{count2}");
}

The above code is copied from my other blog, because feeling than I realized a little better, here is my own writing:

public void Sort2(int[] numbers)
{
    var count1 = 0;
    var count2 = 0;

    for (var i = 0; i < numbers.Length / 2; i++)
    {
        var left = i;
        var right = numbers.Length - i - 1;

        var minIndex = left;
        var maxIndex = left;

        for (var j = left + 1; j <= right; j++)
        {
            if (numbers[j] < numbers[minIndex])
            {
                minIndex = j;
            }

            if (numbers[j] > numbers[maxIndex])
            {
                maxIndex = j;
            }

            count1++;
        }

        if (left != minIndex)
        {
            var temp = numbers[minIndex];
            numbers[minIndex] = numbers[left];
            numbers[left] = temp;

            count2++;
        }
        
        // 如果第一个就是最大的,因为已经把他移动到minIndex上了,所以这里要更新下索引
        if (left == maxIndex)
        {
            maxIndex = minIndex;
        }

        if (right != maxIndex)
        {
            var temp = numbers[right];
            numbers[right] = numbers[maxIndex];
            numbers[maxIndex] = temp;

            count2++;
        }
    }

    Console.WriteLine($"结果:{string.Join(",", numbers)};循环次数:{count1};交换次数:{count2}");
}

In fact, the last two versions of operating results of the code is the same, only the third version of the second does not look as intuitive, do only record, after all, also took some mental engage in out, do not pull out yo ~ ~ feel a little pity Manual Behind his

Guess you like

Origin www.cnblogs.com/diwu0510/p/12334101.html