Top Ten Basic Algorithms

1. Selection sort

A brief description of the process:
First, find the smallest element in the array, and second, exchange it with the first element of the array (if the first element is the smallest element, then it will exchange itself). Second, find the smallest element among the remaining elements and swap it with the second element of the array. And so on, until the entire array is sorted. We call this method selection sort .

For the convenience of understanding, I also prepared animations:

.

public class SelectionSort {

    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};
        //定义内外两层循环,从最外层循环第一个值开始匹配,内层循环从外层循环加以开始向后匹配
        //如果遇到小的值就进行交换
        //外层循环到倒数第二为止,内层循环到倒数第一为止
        for (int i = 0; i < arr.length-1; i++) {
            int min = i;
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i]>=arr[j]){
                    min = j;
                    int temp = arr[i];
                    arr[i] = arr[min];
                    arr[j] = temp;
                }
            }
        }
        CommonUtils.print(arr);
    }
}

Properties: 1. Time complexity: O(n2) 2. Space complexity: O(1) 3. Unstable sorting 4. In-place sorting

2. Insertion sort

How did you organize the cards when we were playing poker? A simple way to do this is to do it one by one, inserting each card into its proper place among the other already ordered cards. When we sort an unordered array, in order to insert an element, we need to make room and move all the remaining elements to the right before inserting. This algorithm is called insertion sort .

Brief description of the process:

1. Extract elements from the second element of the array.

2. Compare it with the first element on the left. If the first element on the left is larger than it, continue to compare it with the second element on the left until it encounters an element that is not larger than it, and then insert it to the right of this element.

3. Continue to select the 3rd, 4th, ... n elements, repeat step 2, and select an appropriate position to insert.

For the convenience of understanding, I also prepared animations:

public class InsertionSort {
    public static void main(String[] args) {
        int[] a = { 9, 3, 1, 4, 6, 8, 7, 5, 2 };
        for (int i = 1; i < a.length; i++) {
            //内层比较是从外层的赋值为起始点
            //该值会和它前面的值比较,如果比前面的值小就交换
            for (int j = i;j>0; j--) {
                if(a[j]<a[j-1]){
                    CommonUtils.swap(a,j,j-1);
                }
            }
        }
        CommonUtils.print(a);
    }
}

3. Bubble sort

1. Compare the first element with the second element, and if the first element is larger than the second element, exchange their positions. Then continue to compare the second and third elements, if the second is greater than the third, exchange their positions....

We do the same for each pair of adjacent elements, from the first pair at the beginning to the last pair at the end, so that after a comparison and exchange, the rightmost element will be the largest number.

Remove the rightmost element, we do the same for the remaining elements, and so on, until the sorting is complete.

For the convenience of understanding, I also prepared animations:

public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};
        for (int i = 0; i < arr.length; i++) {
            //内层循环像指针一样指导着程序运行
            for (int j = 0; j < arr.length-i-1; j++) {

                if(arr[j]>arr[j+1]){
                    CommonUtils.swap(arr,j,j+1);
                }
            }
        }

        CommonUtils.print(arr);
    }
}

4. Hill sort

Hill sort can be said to be a variant of insertion sort . Whether it is insertion sorting or bubble sorting, if the maximum value of the array happens to be at the first place, n - 1 moves are required to move it to the correct position. In other words, if an element of the original array is far away from its correct position, it needs to be exchanged with adjacent elements many times to reach the correct position, which is relatively time-consuming.

Hill sorting simply improves insertion sorting for speed, exchanging non-adjacent elements to sort parts of the array.

The idea of ​​Hill sorting is to adopt the method of insertion sorting , first let the elements of any interval h in the array be ordered, the size of h can be h = n / 2 at the beginning, then let h = n / 4, let h keep shrinking , when h = 1, that is, the elements with any interval of 1 in the array at this time are in order, and the array at this time is in order.

For easy understanding, I also prepared pictures:

public class ShellSort {
    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 1, 7, 9, 4, 2};
        int h = arr.length/2;
        for (int gap = h; gap > 0; gap--) {//间隔的循环
            for (int j = 0; j < arr.length-gap; j++) {
                if(arr[j]>arr[j+gap]){
                    CommonUtils.swap(arr,j,j+gap);
                }
            }

        }

        CommonUtils.print(arr);
    }
}

5. Merge sort

To order a large unordered array, we can divide the large array into two, then sort the two arrays separately, and then merge the two arrays into an ordered array. Since the two small arrays are sorted, merging is fast.

Divide the large array recursively until the size of the array is 1. At this time, there is only one element, then the array is in order, and then merge the two arrays with a size of 1 into one with a size of 2 , and then merge the two sizes of 2 into 4... until all the small arrays are merged.

For the convenience of understanding, I also prepared animations:

public class MergeSort {

    public static void main(String[] args) {
        int[] arr = {1,4,7,8,3,6,9};
        sort(arr, 0, arr.length-1);

        CommonUtils.print(arr);
    }
    static void sort(int[] arr, int left, int right) {
        if(left==right){
            return;
        }
        int mid = left + (right-left)/2;
        sort(arr,left,mid);
        sort(arr,mid+1,right);
        merge(arr,left,mid+1,right);
    }


    //先定义合并的方法
    static void merge(int[] arr, int leftPtr, int rightPtr, int rightBound) {
        int i = leftPtr;
        int j = rightPtr;
        int mid = rightPtr -1;
        int[] temp = new int[rightBound - leftPtr + 1];
        int tempPtr = 0;

        //进行比较赋值
        while (i<=mid&&j<=rightBound){
            if(arr[i]>arr[j]){
                temp[tempPtr]=arr[j];
                j++;
                tempPtr++;
            }else {
                temp[tempPtr]=arr[i];
                i++;
                tempPtr++;
            }
        }

        //将未放入临时数组的数放入临时数组
        while(i<=mid) temp[tempPtr++] = arr[i++];
        while(j<=rightBound) temp[tempPtr++] = arr[j++];

        //数组复制
        for (int i1 = 0; i1 < temp.length; i1++) {
            arr[leftPtr+i1]=temp[i1];
        }
    }
}

Six, quick sort

We select an element from the array, let's call this element the axis element , and then put all the elements in the array that are smaller than the axis element on the left, and all the elements that are greater than or equal to the axis element on the right. Obviously, the positions of the central axis elements are in order at this time . In other words, we no longer need to move the position of the axis element.

Starting from the central axis element, the large array is cut into two small arrays (both arrays do not contain the central axis element), and then we recursively make the array on the left and right of the central axis element repeat the same operate until the size of the array is 1, at which point each element is in an ordered position .

For the convenience of understanding, I also prepared animations:

public class QuickSort {

    public static void main(String[] args) {
        int[] arr = {1,5,7,6,4};
        sort(arr,0,arr.length-1);

        CommonUtils.print(arr);
    }

    static void sort(int[] arr, int leftBound, int rightBound) {
        if(leftBound>=rightBound) {
            return;
        }
        int mid = partition(arr, leftBound, rightBound);
        sort(arr,leftBound,mid-1);
        sort(arr,mid+1,rightBound);
    }

    static int partition(int[] arr, int leftBound, int rightBound) {
        int left = leftBound;
        int mid = rightBound;
        int right = rightBound-1;

        while (left<=right){
            //1、这两个指针分别寻找小于标杆和大于标杆的数,找到以后指针停止
            //2、交换两边指针停止位置的数
            //3、将标杆放到中间的位置
            while (left<=right&&arr[left]<=arr[mid]){
                left++;
            }
            while (left<=right&&arr[right]>arr[mid]){
                right--;
            }
            if(left<right){
                CommonUtils.swap(arr,left,right);
            }
        }
        //把标杆放中间
        CommonUtils.swap(arr,left,rightBound);
        return left;
    }
}

7. Counting and sorting

Counting sort is a kind of sorting suitable for the difference between the maximum value and the minimum value is not not too large.

The basic idea is to use the array element as the subscript of the array, and then use a temporary array to count the number of occurrences of the element, for example, temp[i] = m, indicating that the element i appears m times in total. Finally, the data of the temporary array statistics are aggregated from small to large. At this time, the data is in order.

For the convenience of understanding, I also prepared animations:

public class CountSort {
    public static void main(String[] args) {

        int[] arr = {2, 4, 2, 3, 7, 1, 1, 0, 0, 5, 6, 9, 8, 5, 7, 4, 0, 9};

        int[] result = sort(arr);

        CommonUtils.print(result);

    }
    public static int[] sort(int[] arr) {
        int[] temp = new int[10];
        for (int a : arr) {
            temp[a]++;
        }

        int[] result = new int[arr.length];
        int r = 0;
        for (int i = 0; i < temp.length; i++) {

            while (temp[i]>0){
                result[r]=i;
                r++;
                temp[i]--;
            }
        }
        return result;
    }
}

Eight, bucket sort

Bucket sorting is to divide the number between the maximum value and the minimum value, for example, into 10 intervals, 10 intervals correspond to 10 buckets, we put each element into the bucket of the corresponding interval, and then sort the elements in each bucket Data can be sorted by merge sort or quick sort.

After that, the data in each bucket is in order, and we are merging and summarizing.

For easy understanding, I also prepared pictures:

public class BucketSort {

    public static void main(String[] args) {

        int[] arr = {2, 4, 2, 3, 7,0};

        int[] result = sort(arr);

        CommonUtils.print(result);

    }

    public static int[] sort(int[] arr) {
        int max = findMax(arr);
        int mini = findMini(arr);
        int group = (max-mini)/5+1;
        List<List<Integer>> totalBucket = new LinkedList<>();

        //初始化桶
        for (int i = 0; i < group; i++) {
            totalBucket.add(new LinkedList<Integer>());
        }

        for (int i = 0; i < arr.length; i++) {
            //得到所在区间
            int i1 = (arr[i] - mini) / (max - mini);
            //向所在区间添加元素
            totalBucket.get(i1).add(arr[i]);
        }

        //复制结果
        for (List<Integer> integers : totalBucket) {
            Collections.sort(integers);
        }




        //复制结果
        int[] result = new int[arr.length];
        int r = 0;
        for (int i = 0; i < totalBucket.size(); i++) {
            for (int i1 = 0; i1 < totalBucket.get(i).size(); i1++) {
                result[r]= totalBucket.get(i).get(i1);
                r++;
            }
        }
        return result;
    }

    public static int findMax(int[] arr) {
        int max = arr[0];
        for (int i : arr) {
            if(i>max){
                max = i;
            }
        }
        return max;
    }

    public static int findMini(int[] arr) {
        int mini = arr[0];
        for (int i : arr) {
            if(i<mini){
                mini = i;
            }
        }
        return mini;
    }
}

Nine, radix sorting

The sorting idea of ​​radix sorting is as follows: first sort the data by the size of the single digit, then sort the majority by the size of the tens digit, and then sort by the size of the hundreds digit...

At the end, it is a set of ordered elements. However, when he sorts by a certain number of digits, he uses "buckets" to sort.

Since a certain digit (units/tens...., not a whole number) ranges from 0-9, we need 10 buckets, and then put numbers with the same value into the same bucket, and then put The numbers in the buckets are taken out in the order from bucket 0 to bucket 9, so that after one trip, they are sorted according to a certain number of digits.

For the convenience of understanding, I also prepared animations:

public class RadioSort {
    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 100, 7, 9, 4, 20};
        sort(arr);
        CommonUtils.print(arr);
    }

    public static int[] sort(int[] arr) {
       if(arr==null||arr.length==2) {
           return arr;
       }
       int max = findMax(arr);
       int num = 1;
       while (max/10>0){
           max= max/10;
           num++;
       }

        List<List<Integer>> totalBucket = new LinkedList<>();

        //初始化桶
        for (int i = 0; i < 10; i++) {
            totalBucket.add(new LinkedList<Integer>());
        }
        for (int i = 0; i < num; i++) {
            //放入对应的桶
            for (int j = 0; j < arr.length; j++) {
                int location = (arr[j] / (int)Math.pow(10,i)) % 10;
                totalBucket.get(location).add(arr[j]);
            }


            int k = 0;
            for (List<Integer> integers : totalBucket) {
                for (Integer integer : integers) {
                    arr[k++]=integer;
                }
                integers.clear();
            }


        }



        return arr;
    }


    public static int findMax(int[] arr) {
        int max = arr[0];
        for (int i : arr) {
            if(i>max){
                max = i;
            }
        }
        return max;
    }
}

10. Heap sort

The characteristic of the heap is that the element at the top of the heap is a maximum value , the top of the large top heap is the maximum value, and the small top heap is the minimum value.

Heap sorting is to exchange the top element of the heap with the last element. After the exchange, the characteristics of the heap are destroyed. We then form a large top heap with the remaining elements in the heap, and then exchange the top element with the last second element. .... Going on like this, until there is only one element left, the array at this time is in order.

For the convenience of understanding, I also prepared animations:

public class HeadSort {
    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 100, 7, 9, 4, 20};
        int n = arr.length;
         //构建大顶堆
         for (int i = (n - 2) / 2; i >= 0; i--) {
             sort(arr, i, n - 1);
         }

         //进行堆排序
        for (int i = n - 1; i >= 1; i--) {
            // 把堆顶元素与最后一个元素交换
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;
            // 把打乱的堆进行调整,恢复堆的特性
            sort(arr, 0, i - 1);
         }

        CommonUtils.print(arr);
    }


    public static void sort(int[] arr,int parent, int n) {
        int child = 2*parent+1;

        while (child<n){

            //如果右节点大于左节点这把指针只想左节点
            if(child+1<n&&arr[child]<arr[child+1]){
                child++;
            }
            //比较子节点和父节点的大小
            if(arr[child]>arr[parent]){
                CommonUtils.swap(arr,child,parent);
            }
            parent = child;
            child = 2*parent+1;
        }
    }

}

Summarize

Use a picture to summarize the properties of the top 10 sorting algorithms

Reference article:

Detailed diagram of heap sorting (easy to understand) - The Right Minister's Blog - CSDN Blog

https://www.cnblogs.com/itsharehome/p/11058010.html

Guess you like

Origin blog.csdn.net/weixin_55229531/article/details/131264468