Interview often test the sorting algorithm

table of Contents

 

Preliminaries

Bubble Sort

algorithm

 Analysis bubble sort

Bubble sort of optimization

Selection Sort 

algorithm

Select sorting analysis 

Heapsort

algorithm

Analysis of Heap Sort

Direct insertion sort

algorithm

Analysis of insertion sort 

Shell sort

algorithm

Shell sort of analysis

Quick Sort

algorithm

Analysis of quicksort

Quick Sort optimization

Non-recursive quicksort


Preliminaries

Comparable sorted object belongs to the type, can be applied to sort the input data using the compatible ComparaTo method, except (reference) assignment operator, this is the only operation of the input data. Sort under these conditions is called based on the sort of comparison.

Sort Stability: 293513 '10, is a complete sorting 1233' 5910 then that is stable, the sort is complete 12,335,910 then that is unstable sort '. The method of determination is stable sort exchange jump does not occur. Stable sort sort can become unstable, unstable ordering can not become stable sort.

Sort sort of internal and external, internal sorting are ordered in memory for the number of elements in relatively small (less than a few million). External sort is sorted on the disk, a large number of elements specific to sorting. This article belongs to the former seven kinds of internal sorting, the last one is external sorting.

Bubble Sort

algorithm

For two cycles, the first for loop is the number of times i, is a second number of comparisons for loop j. Adjacent elements are compared, the condition to be exchanged. After comparing the number of p, p data will be ordered.

The original array 8 6 3 9 4 7 The number of comparisons
After the first trip 6 3 8 4 7 9 5
After the second trip 3 6 4 7 8 9 4
After the third trip 3 4 6 7 8 9 3
After the fourth trip 3 4 6 7 8 9 2
After the fifth trip 3 4 6 7 8 9 1
    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1 ; i++) {
            for (int j = 0; j < array.length-1-i; j++) {
                if (array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
        }
    }

 Analysis bubble sort

For two-cycle, the time complexity of O (N).
No extra space applications, the space complexity: O (1)
Stability: Stable

Bubble sort of optimization

We will find the above example, when the third trip has been ordered, and therefore do not have to be compared. So how orderly the code knows, it is in the process of comparison, if the exchange is not explained on the order. We can define a boolean variable as follows optimization.

public static void bubbleSort(int[] array) {
    boolean flg = false;
    for (int i = 0; i < array.length-1; i++) {
        for (int j = 0; j < array.length-1-i; j++) {
            if (array[j] > array[j+1]) {
                int tmp = array[j];
                array[j] = array[j+1];
                array[j+1] = tmp;
                flg = true;
            }
        }
        if (!flg) {
            break;
        }
    }
}

Selection Sort 

algorithm

i from the numeral 0, optionally followed by smaller than, and its switching element. Trip to the sorting is done on the first element of the order.

    public static void selectSort(int[] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = i+1; j < array.length; j++) {
                if (array[i] > array[j]) {
                    int tmp = array[i];
                    array[i] = array[j];
                    array[j] = tmp;
                }
            }
        }
    }

Select sorting analysis 

Time complexity: O (n ^ 2) [are the best and worst]
space complexity: O (1)
Stability: Unstable

Heapsort

algorithm

The stack array to create a sequence by traversing manner. To ascending order, to adjust to a large root heap. Then the topmost element is ordered, is the greatest element. If in descending order, to adjust to a small root heap, then the topmost element is ordered, is the smallest element.

Specifically:
1. To adjust a large root heap (in ascending order). It is to ensure that each sub-trees are a large root heap, adjusted from the top down, that is adjusted downward. Adjust the way, about their father node and comparing the maximum child (provided there is a right child), to ensure that children have the right, it is to determine the child + 1 is less than the length. If the child node is greater than the father node, you can swap the two. It's just [a] second adjustment to adjust just have to let the root -1 to continue to adjust.
2. sorts, the first element and the last element to be exchanged, the last element on the order. 0 adjust the subject under the tree is large root heap. A defined end, each time switching end--, be adjusted downwards. When the end = 0 described adjustment is completed.

 //向下调整
    public static void adjustDown(int[] array, int root, int len) {
        int parent = root;
        int child = 2*parent+1;
        while (child < len) {
            if (child+1 < len && array[child] < array[child+1]) {
                child++;
            }
            //此时child就是指向子孩子的较大值
            if (array[child] > array[parent]) {
                int tmp = array[child];
                array[child] = array[parent];
                array[parent] = tmp;
                //调整子树也要是大根堆
                parent = child;
                child = 2*parent+1;
            } else {
                break;
            }
        }
    }

    //每棵树都向下调整
    public static void creatHeap(int[] array) {
        for (int i = (array.length-1-1)/2; i >= 0; i--) {
            adjustDown(array, i, array.length);
        }
    }

    //进行排序
    public static void heapSort(int[] array) {
        creatHeap(array);
        int end = array.length-1;
        while (end > 0) {
            int tmp = array[0];
            array[0] = array[end];
            array[end] = tmp;
            //adjustDown取不到len 所以先调整后end--
            adjustDown(array, 0, end);
            end--;
        }
    }

    public static void main(String[] args) {
        int[] array = new int[]{27, 15, 19, 18, 28, 34, 65, 49, 25, 37};
        heapSort(array);
        System.out.println(Arrays.toString(array));
    }

Analysis of Heap Sort

Time Complexity: Since the number of leaf nodes and the root node is about 1: 1, the root node is selected from N / 2, each of the root node must be adjusted downward log2N. Coupled with the sorting O (N), i.e. is log2N (2 to bottom) * N / 2 + O (N) == Nlog2N

Space complexity: O (1)

The best, the worst, the average complexity are Nlog2N

Built heap of time complexity: Nlog2N

An adjustment time complexity: log2N

Stability: Unstable

 

Direct insertion sort

algorithm

Sort sorting times have N-1 composition, for p = 1 to p = N-1, the elements on insertion sort to ensure a position of 0-p sorted state. Sort follows:

The original array 34 8 64 51 32 21
After Run p = 1 8 34 64 51 32 21
After Run p = 2 8 34 64 51 32 21
Then p = 3 times 8 34 51 64 32 21
After p = 4 times 8 32 34 51 64 21
P = 5 times after 21 32 34 51 64

This sort of approach we can expose analogous to poker. The first data has been ordered, i should start from 1. The subscript number i data into tmp. Comparison of the foregoing standard element No. i, subscripts j = i-1. subscripts j number elements tmp and compared. If j is larger than the number of elements tmp index, the index of the element number j into subscript j + 1, J,, when j is less than 0, indicating that no element of the foregoing. Tmp then put the data in the position j + 1. This trip is quick sort. Note that if tmp is larger than the number of elements j, description has already been ordered directly to the tmp into j + 1.

    public static void insertSort(int[] array) {
        int j = 0;
        for (int i = 1; i < array.length; i++) {
            int tmp = array[i];
            for (j = i-1; j >= 0; j--) {
                if (tmp < array[j]) {
                    array[j+1] = array[j];
                } else {
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

Analysis of insertion sort 

There are two for loops, if the input data is ordered, testing of the inner loop is always terminated immediately determination is not satisfied, so the best time complexity is O (N), the worst is O (N ^ 2), i.e., is disordered time. And the more ordered data faster.

Application no extra space, so the space complexity is O (1)

The sorting is stable, if the conditions if (tmp <array [j]) to if (tmp <= array [j]) of the sort of instability becomes a sort.

Shell sort

algorithm

Hill sorting directly into the optimized sorting. Packet ordering, the faster the more ordered the direct insertion sort. Incremental must be relatively prime, the last increment must be 1. We can use the packet jump packet, the packet will skip data behind a relatively large, relatively small data in front (in the case of ascending order), so that the data having better ordering.

    public static void shell(int[] array, int gap) {
        for (int i = gap; i < array.length; i++) {
            int tmp = array[i];
            int j = 0;
            for (j = i-gap; j >= 0; j -= gap) {
                if (array[j] > tmp) {
                    array[j+gap] = array[j];
                } else {
                    break;
                }
            }
            array[j+gap] = tmp;
        }
    }

    public static void shellSort(int[] array) {
        //分的组数
        int[] drr = {5,3,1};
        for (int i = 0; i < drr.length; i++) {
            shell(array, drr[i]);
        }
    }

 

Practices were grouped 5,3,1, with the change in the packet of data increasingly orderly. 

Shell sort of analysis

Time complexity: O (n ^ 1.3 - n ^ 1.5)

Space complexity: O (1)

Stability: Unstable

Quick Sort

algorithm

Get reference: 0 is defined as the low index, high length-1 for the index number. The low number of elements of the subject into the tmp to find data elements tmp is smaller than from the back, into the low position numbers; tmp is larger than the front to back find data elements, the position of the target into the high number. When the low and high met, the tmp into them. This place is the reference position. Left baseline than the small base, the right baseline than the benchmark large. pivot [trip] quick sort - "give a range [low, high], recursive find other benchmark!

 

    public static int partion(int[] array, int start, int end) {
        int tmp = array[start];
        while (start < end) {
            while ((start < end) && array[end] >= tmp) {  //9 3 2 9 10
             end--;
            }
            if (start >= end) {
               array[start] = tmp;
               break;
            } else {
                array[start] = array[end];
            }

            while ((start < end) && array[start] <= tmp) {  //9 3 2 9 10
               start++;
            }
            if (start >= end) {
                array[start] = tmp; //
                break;
            } else {
                array[end] = array[start];
            }

        }
        return start;
    }

    public static void quick(int[] array, int low, int high) {
        //递归的终止条件:只有一个元素
        if (low >= high) { //=zuo  >you
            return;
        }
        //1.写一个函数把待排序序列分为两部分
        int pivot = partion(array, low, high); //low和high是局部变量
        //开始递归 左右
        quick(array, low, pivot-1);
        quick(array, pivot+1, high);
    }

    public static void quickSort(int[] array) {
        quick(array, 0, array.length-1);
    }

Analysis of quicksort

Time complexity: O (nlog2n)

The best time complexity:

The worst time complexity: [where data ordered] O (n ^ 2)

Space complexity: O (log2n) [left tree height]

Stability: Unstable

Quick Sort optimization

Optimization 1:

When the process quick sort of data may be becoming more and more ordered, for direct insertion sort, the more ordered the data faster. O (n) - "n-" small. When the sorting process, the amount of data in a section is small, the threshold value - "100 direct insertion sort

public class QuickSortbetter1 {
    public static int partion(int[] array, int start, int end) {
        int tmp = array[start];
        while (start < end) {
            while ((start < end) && array[end] >= tmp) {  //9 3 2 9 10
                end--;
            }
            if (start >= end) {
                array[start] = tmp;
                break;
            } else {
                array[start] = array[end];
            }

            while ((start < end) && array[start] <= tmp) {  //9 3 2 9 10
                start++;
            }
            if (start >= end) {
                array[start] = tmp; //
                break;
            } else {
                array[end] = array[start];
            }

        }
        return start;
    }

    public static void insertSort2(int[] array, int low, int high) {
        int j = 0;
        for (int i = low+1; i <= high; i++) {
            int tmp = array[i];
            for (j = i-1; j >= low; j--) {
                if (array[j] > tmp) {
                    array[j+1] = array[j];
                } else {
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

    public static void quick(int[] array, int low, int high) {
        //递归的终止条件
        if (low >= high) {
            return;
        }

        if (high-low+1 < 100) {
            insertSort2(array, low, high);
            return;
        }
        //1.写一个函数把待排序序列分为两部分
        int pivot = partion(array, low, high); //low和high是局部变量
        //开始递归 左右
        quick(array, low, pivot-1);
        quick(array, pivot+1, high);
    }

    public static void quickSortBetter1(int[] array) {
        quick(array, 0, array.length-1);
    }

 

Optimization 2:

If 12345678910 to find a reference the degradation of a bubble sort

Divide and Conquer Algorithm - "fast row -" best case is to be divided evenly ordered sequence.

If you want 12345678910 uniform segmentation: taking three digital France 9/4 = 2. . Taking the median of three digits in the middle as a reference

That is the time to take the low and high sequence to be sorted median, array [mid] <= array [low] <= array [high]. That result is to be the subject of an element that is at low median number of three.

 

public class QuickSortBetter2 {
    public static int partion(int[] array, int start, int end) {
        int tmp = array[start];
        while (start < end) {
            while ((start < end) && array[end] >= tmp) {  //9 3 2 9 10
                end--;
            }
            if (start >= end) {
                array[start] = tmp;
                break;
            } else {
                array[start] = array[end];
            }

            while ((start < end) && array[start] <= tmp) {  //9 3 2 9 10
                start++;
            }
            if (start >= end) {
                array[start] = tmp; //
                break;
            } else {
                array[end] = array[start];
            }

        }
        return start;
    }

    public static void swap(int[] array, int low, int high) {
        int tmp = array[low];
        array[low] = array[high];
        array[high] = tmp;
    }

    public static void ThreeNumOfMiddle(int[] array, int low, int high) {
        //array[mid] <= array[low] <= array[high];
        int mid = (low+high)/2;
        if (array[mid] > array[high]) {
            swap(array, mid, high);
        }
        if (array[mid] > array[low]) {
            swap(array, mid, low);
        }
        if (array[low] > array[high]) {
            swap(array, low, high);
        }
    }


    public static void quick(int[] array, int low, int high) {
        //递归的终止条件
        if (low >= high) {
            return;
        }

        ThreeNumOfMiddle(array, low, high);
        //1.写一个函数把待排序序列分为两部分
        int pivot = partion(array, low, high); //low和high是局部变量
        //开始递归 左右
        quick(array, low, pivot-1);
        quick(array, pivot+1, high);
    }

    public static void quickSort(int[] array) {
        quick(array, 0, array.length-1);
    }

Optimization 3: 

Gather the same basis element method.

Non-recursive quicksort

public static int partion(int[] array, int start, int end) {
    int tmp = array[start];
    while (start < end) {
        while ((start < end) && array[end] >= tmp) {  //9 3 2 9 10
            end--;
        }
        if (start >= end) {
            array[start] = tmp;
            break;
        } else {
            array[start] = array[end];
        }

        while ((start < end) && array[start] <= tmp) {  //9 3 2 9 10
            start++;
        }
        if (start >= end) {
            array[start] = tmp; //
            break;
        } else {
            array[end] = array[start];
        }

    }
    return start;
}

public static void quick(int[] array, int low, int high) {
  int pivot = partion(array, low, high);
  Stack<Integer> stack = new Stack<>();

  if (pivot > low+1) { //左边有两个元素可以入栈
      stack.push(low);
      stack.push(pivot-1);
  }
  if (pivot < high-1) { //右边有两个元素可以入栈
      stack.push(pivot+1);
      stack.push(high);
  }

  while (!stack.empty()) {
      high = stack.pop();
      low = stack.pop();
      pivot = partion(array, low, high);
      if (pivot > low+1) { //左边有两个元素可以入栈
          stack.push(low);
          stack.push(pivot-1);
      }
      if (pivot < high-1) { //右边有两个元素可以入栈
          stack.push(pivot+1);
          stack.push(high);
      }
  }

}

public static void quickSort(int[] array) {
    quick(array, 0, array.length-1);
}

 The last day of 2019, make a wish, right here. I hope that in 2020 this wonderful year, to get a satisfactory offer, red white duck! To dream, to go on. Goodbye 2019, 2020 hello hehehe O (∩_∩) O ~ ha

 

 

 

 

 

 

 

 

Published 51 original articles · won praise 14 · views 2303

Guess you like

Origin blog.csdn.net/qq_41185460/article/details/104044153