Comparison of Sorting Algorithms and Implementation in Java

Bubble sort
basic idea:

Compare adjacent elements. If the first is bigger than the second, swap them both.
Do the same for each pair of adjacent elements, from the first pair at the beginning to the last pair at the end. At this point, the last element should be the largest number.
Repeat the above steps for all elements except the last one. Continue repeating the above steps for fewer and fewer elements each time until there are no pairs of numbers to compare.

Java implementation
   
Add the flag state flag If there is no exchange in a bubbling, it means that you can stop reducing the runtime

public static void bubbleSort(int[] numbers) {
    
    
    int temp = 0;
    int size = numbers.length;
    boolean flag = true;
    for (int i = 0; i < size - 1&&flag; i++) {
    
    
        flag = false;
        for (int j = 0; j < size - 1 - i; j++) {
    
    
            if (numbers[j] > numbers[j + 1]) // 交换两数位置
            {
    
    
                temp = numbers[j];
                numbers[j] = numbers[j + 1];
                numbers[j + 1] = temp;
                flag = true;
            }
        }
    }
}

Time complexity O(n*n)

selection sort algorithm

Basic idea:
In a set of numbers to be sorted, select the smallest number to exchange with the number in the first position; then find the smallest number among the remaining numbers to exchange with the number in the second position, and so on. The penultimate number is compared with the last number.

Java implementation

public static void selectSort(int[] numbers) {
    
    
    int size = numbers.length; // 数组长度
    int temp = 0; // 中间变量
    for (int i = 0; i < size-1; i++) {
    
    
        int k = i; // 待确定的位置
        // 选择出应该在第i个位置的数
        for (int j = size - 1; j > i; j--) {
    
    
            if (numbers[j] < numbers[k]) {
    
    
                k = j;
            }
        }
        // 交换两个数
        temp = numbers[i];
        numbers[i] = numbers[k];
        numbers[k] = temp;
    }
}

Time complexity O(n*n) performance is better than bubble sorting with fewer exchanges

insertion sort algorithm

Basic idea: In each step, insert a record to be sorted into the appropriate position of the previously sorted word sequence according to its sequence code size (after finding the appropriate position from back to front), until all insertion and sorting is completed.

Java implementation

public static void insertSort(int[] numbers) {
    
    
    int size = numbers.length;
    int temp = 0;
    int j = 0;
    for (int i = 1; i < size; i++) {
    
    
        temp = numbers[i];
        // 假如temp比前面的值小,则将前面的值后移
        for (j = i; j > 0 && temp < numbers[j - 1]; j--) {
    
    
            numbers[j] = numbers[j - 1];
        }
        numbers[j] = temp;
    }
}

Time complexity
O(n*n) performance is better than bubble sort and selection sort

Hill sort algorithm

Basic idea:
first divide the entire record sequence to be sorted into several subsequences for direct insertion sorting, and when the records in the entire sequence are "basically in order", then perform direct insertion sorting for all records in turn.

Java implementation

  • The principle of Hill sorting: According to the requirements, if you want the results to be arranged from small to large, it will first group the array, then move the smaller value to the front, and the larger value
  • Move to the back, and finally perform insertion sort on the entire array, which reduces the number of data exchanges and movements compared to using insertion sort at the beginning,
  • It can be said that Hill sorting is an enhanced version of insertion sorting. Take the array 5, 2, 8, 9, 1, 3, 4 as an example, the length of the array is 7, when the increment is 3, the array is divided into two sequences
  • 5, 2, 8 and 9, 1, 3, 4, first sorting, 9 and 5 comparison, 1 and 2 comparison, 3 and 8 comparison, 4 and the array value smaller than its subscript value increment
  • This example is arranged from small to large, so the small ones will be ranked first. After the first sorting, the array is 5, 1, 3, 4, 2, 8, 9
  • After the first time, the value of increment becomes 3/2=1, at this time, the array is inserted and sorted, and the array is sorted from large to small
public static void shellSort(int[] data) {
    
    
    int j = 0;
    int temp = 0;
    // 每次将步长缩短为原来的一半
    for (int increment = data.length / 2; increment > 0; increment /= 2) {
    
    
        for (int i = increment; i < data.length; i++) {
    
    
            temp = data[i];
            for (j = i; j >= increment; j -= increment) {
    
    
                if (temp < data[j - increment])// 从小到大排
                {
    
    
                    data[j] = data[j - increment];
                } else {
    
    
                    break;
                }
            }
            data[j] = temp;
        }
    }
}

Time complexity O(n^1.5)

The basic idea of ​​the heap sort algorithm
:
heap sort is a tree selection sort, which is an effective improvement to the direct selection sort.

Under the definition of a heap: a sequence (h1, h2, ..., hn) with n elements, if and only if (hi>=h2i, hi>=h2i+1) or (hi<=h2i, hi<=h2i +1) (i=1,2,...,n/2) is called a heap. Only heaps satisfying the former condition are discussed here. It can be seen from the definition of the heap that the top element of the heap (that is, the first element) must be the largest item (big top heap). A complete binary tree can represent the structure of the heap very intuitively. The top of the heap is the root, and the others are the left subtree and the right subtree.

Idea: At the beginning, the sequence of numbers to be sorted is regarded as a sequentially stored binary tree, and their storage order is adjusted to make it a heap. At this time, the number of root nodes of the heap is the largest. Then swap the root node with the last node of the heap. Then readjust the previous (n-1) numbers to make it a heap. And so on until there are only two nodes in the heap, and they are exchanged, and finally an ordered sequence with n nodes is obtained. From the algorithm description, heap sorting requires two processes, one is to build a heap, and the other is to exchange positions between the top of the heap and the last element of the heap. So heap sorting consists of two functions. One is the permeation function that builds the heap, and the other is the function that repeatedly calls the permeation function to achieve sorting.

Java implementation

public static void heapSort(int[] a){
    
    
    int arrayLength = a.length;
    // 循环建堆
    for (int i = 0; i < arrayLength - 1; i++) {
    
    
        // 建堆
        buildMaxHeap(a, arrayLength - 1 - i);
        // 交换堆顶和最后一个元素
        swap(a, 0, arrayLength - 1 - i);
        System.out.println(Arrays.toString(a));
    }
}
// 对data数组从0到lastIndex建大顶堆
public static void buildMaxHeap(int[] data, int lastIndex) {
    
    
    // 从lastIndex处节点(最后一个节点)的父节点开始
    for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
    
    
        // k保存正在判断的节点
        int k = i;
        // 如果当前k节点的子节点存在
        while (k * 2 + 1 <= lastIndex) {
    
    
            // k节点的左子节点的索引
            int biggerIndex = 2 * k + 1;
            // 如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
            if (biggerIndex < lastIndex) {
    
    
                // 若果右子节点的值较大
                if (data[biggerIndex] < data[biggerIndex + 1]) {
    
    
                    // biggerIndex总是记录较大子节点的索引
                    biggerIndex++;
                }
            }
            // 如果k节点的值小于其较大的子节点的值
            if (data[k] < data[biggerIndex]) {
    
    
                // 交换他们
                swap(data, k, biggerIndex);
                // 将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
                k = biggerIndex;
            } else {
    
    
                break;
            }
        }
    }
}
// 交换
private static void swap(int[] data, int i, int j) {
    
    
    int tmp = data[i];
    data[i] = data[j];
    data[j] = tmp;
}

Time complexity O(nlogn) is not suitable for situations where there are few sequences to be sorted

quick sort algorithm

Basic idea:
Divide the records to be sorted into two independent parts by one-pass sorting, and the keywords of one part of the records are smaller than those of the other part, and then continue to sort the two parts until the whole sequence is in order.

Java implementation

/**
 * 快速排序
 * 
 * @param numbers
 *            带排序数组
 */
public static void quick(int[] numbers) {
    
    
    if (numbers.length > 0) // 查看数组是否为空
    {
    
    
        quickSort(numbers, 0, numbers.length - 1);
    }
}
/**
 * 
 * @param numbers
 *            带排序数组
 * @param low
 *            开始位置
 * @param high
 *            结束位置
 */
public static void quickSort(int[] numbers, int low, int high) {
    
    
    if (low >= high) {
    
    
        return;
    }
    int middle = getMiddle(numbers, low, high); // 将numbers数组进行一分为二
    quickSort(numbers, low, middle - 1); // 对低字段表进行递归排序
    quickSort(numbers, middle + 1, high); // 对高字段表进行递归排序
}
/**
 * 查找出中轴(默认是最低位low)的在numbers数组排序后所在位置
 * 
 * @param numbers
 *            带查找数组
 * @param low
 *            开始位置
 * @param high
 *            结束位置
 * @return 中轴所在位置
 */
public static int getMiddle(int[] numbers, int low, int high) {
    
    
    int temp = numbers[low]; // 数组的第一个作为中轴
    while (low < high) {
    
    
        while (low < high && numbers[high] > temp) {
    
    
            high--;
        }
        numbers[low] = numbers[high];// 比中轴小的记录移到低端
        while (low < high && numbers[low] < temp) {
    
    
            low++;
        }
        numbers[high] = numbers[low]; // 比中轴大的记录移到高端
    }
    numbers[low] = temp; // 中轴记录到尾
    return low; // 返回中轴的位置
}

Time complexity O(nlogn)
quick sorting is less efficient when there are few elements in the sequence, and it is not as good as insertion sorting. Therefore, insertion sorting is generally used when there are few elements in the sequence, which can improve the overall efficiency.

Merge Sort Algorithm

Basic idea:
The Merge sorting method is to merge two (or more than two) ordered lists into a new ordered list, that is, divide the sequence to be sorted into several subsequences, and each subsequence is ordered. Then the ordered subsequences are merged into an overall ordered sequence.

Java implementation

/**
 * 归并排序
 * 简介:将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列
 * 时间复杂度为O(nlogn)
 * 稳定排序方式
 * @param nums 待排序数组
 * @return 输出有序数组
 */
public static int[] sort(int[] nums, int low, int high) {
    
    
    int mid = (low + high) / 2;
    if (low < high) {
    
    
        // 左边
        sort(nums, low, mid);
        // 右边
        sort(nums, mid + 1, high);
        // 左右归并
        merge(nums, low, mid, high);
    }
    return nums;
}
/**
 * 将数组中low到high位置的数进行排序
 * @param nums 待排序数组
 * @param low 待排的开始位置
 * @param mid 待排中间位置
 * @param high 待排结束位置
 */
public static void merge(int[] nums, int low, int mid, int high) {
    
    
    int[] temp = new int[high - low + 1];
    int i = low;// 左指针
    int j = mid + 1;// 右指针
    int k = 0;
    // 把较小的数先移到新数组中
    while (i <= mid && j <= high) {
    
    
        if (nums[i] < nums[j]) {
    
    
            temp[k++] = nums[i++];
        } else {
    
    
            temp[k++] = nums[j++];
        }
    }
    // 把左边剩余的数移入数组
    while (i <= mid) {
    
    
        temp[k++] = nums[i++];
    }
    // 把右边边剩余的数移入数组
    while (j <= high) {
    
    
        temp[k++] = nums[j++];
    }
    // 把新数组中的数覆盖nums数组
    for (int k2 = 0; k2 < temp.length; k2++) {
    
    
        nums[k2 + low] = temp[k2];
    }
}

Time complexity O(nlogn)

Performance comparison of various algorithms such as time complexity
insert image description here

Guess you like

Origin blog.csdn.net/weixin_45817985/article/details/130705050