美文网首页
插入排序

插入排序

作者: Jackpot_0213 | 来源:发表于2021-03-11 11:43 被阅读0次

    启发:像接扑克牌,每次拿一张插到合适的位置


    image.png

    插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

    过程看似和冒泡、选择很像。
    冒泡是每次冒大小顺序不对就交换,一趟就把最小/最大的放在正确的位置了。
    选择每趟找最小/大放在前面,一趟交换一次。

    插入排序时每次拿到一个数把他插到相应的位置,有个插入操作,所以就多一个后面元素要往后移动一个位置的操作。


    image.png

    算法步骤

    1. 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

    2. 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

    Python

    class Solution:
        def MySort(self , arr ):
            # write code here
            for i in range(len(arr)):
                
                # 记录前面已有序元素的位置
                preIndex = i - 1
                # 获取当前要插入的元素
                current = arr[i]
                
                # 第一个元素默认有序,依次和前面的比较,先和最大,比他小就让大的往后移
                while preIndex >= 0 and arr[preIndex] > current:
                    # 第一次循环时 arr[preIndex+1] 就是 current,不用担心覆盖
                    # 一直和前面有序的比较,比他小就把拍好的往后移动一个
                    arr[preIndex + 1] = arr[preIndex]
                    preIndex -= 1
                
                # 插入
                arr[preIndex+1] = current
                
            return arr
    

    Java

    public class InsertSort implements IArraySort {
    
        @Override
        public int[] sort(int[] sourceArray) throws Exception {
            // 对 arr 进行拷贝,不改变参数内容
            int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
    
            // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
            for (int i = 1; i < arr.length; i++) {
    
                // 记录要插入的数据
                int tmp = arr[i];
    
                // 从已经排序的序列最右边的开始比较,找到比其小的数
                int j = i;
                while (j > 0 && tmp < arr[j - 1]) {
                    arr[j] = arr[j - 1];
                    j--;
                }
    
                // 存在比其小的数,插入
                if (j != i) {
                    arr[j] = tmp;
                }
    
            }
            return arr;
        }
    }
    

    二分排序(优化插入排序)

    二分查找是在有序的数列里查找某一个元素
    而插入排序的时候,前面排好的部分都是有序的,所以可以在插入的时候使用二分搜素的思想找到相应位置进行插入。

    二分搜索Java

        public static int binarySearch(int[] arrayA, int key) {
            int low = 0;
            int high = arrayA.length - 1;
            int mid = 0;
    
            while (low <= high) {
                mid = (low + high) / 2;
    
                if (key < arrayA[mid]) {
                    high = mid - 1;
                } else if (key > arrayA[mid]) {
                    low = mid + 1;
                } else
                    break;
            }
    
            return mid;
        }
    

    二分排序Java

        public static int[] binarySort(int[] array) {
    
            for (int i = 1; i < array.length; i++) {
                int temp = array[i];
                int low = 0;
                int high = i - 1;
                int mid = -1;
    
                while (low <= high) {
                    mid = (low + high) / 2;
    
                    if (temp < array[mid]) {
                        high = mid - 1;
                    } else { // temp >= array[mid])
                        low = mid + 1;
                    }
                }
    
                // 将low下标以后的元素全部向后移一位
                for (int j = i - 1; j >= low; j--) {
                    array[j + 1] = array[j];
                }
    
                if (low != i)// 若待插入元素的插入位置不等于当前位置,则插入
                    array[low] = temp;
            }
    
            return array;
        }
    

    Python

    def insertion_sort2(arr):
        '''
        二分法插入排序原理:
        外层循环控制循环次数,第二层确定待插入的位置与范围,最后一层循环向后挪动元素的位置,插入待插入的元素。
        count 和 print(arr)为了便于观察过程,可省略。
        '''
        for i in range(1, len(arr)):
            tem = arr[i]
            left = 0
            right = i-1
            count = 0
            
            #待插入的值与已排序区域的中间值比较,不断缩小区域范围,直到left和right相遇。
            while left <= right:
                count += 1
                mid = (left+right)//2
                if arr[i] < arr[mid]:
                    right = mid-1 
                else:
                    left = mid+1
                    
            #当left和right相遇的时候,待插入的位置其实就是left的位置,此时要将left到有序序列的最后一个元素都向后移动一个位置,才能插入元素。
            #这里一定要用left-1,否则当left的位置就是有序序列的最后一个位置时,j取不到值,后面的元素会被这个位置的元素值覆盖。
            for j in range(i-1, left-1 ,-1):
                arr[j+1] = arr[j]
                
            #插入元素
            if left != i:
                arr[left] = tem
                print(arr)
        print('共循环%i次' % count)
        return arr
    }

    相关文章

      网友评论

          本文标题:插入排序

          本文链接:https://www.haomeiwen.com/subject/qiynqltx.html