排序算法(五.插入排序2-二分插入排序和单链表插入排序)

排序算法(五.插入排序2)

  • 二分插入排序
    • 算法思想
    • Java实现
  • 单链表直接插入排序
    • 算法描述
    • Java实现

二分插入排序

二分法插入排序,简称二分排序,是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半进行折半,直到left

算法思想

二分法没有排序,只有查找。所以当找到要插入的位置时。移动必须从最后一个记录开始,向后移动一位,再移动倒数第2位,直到要插入的位置的记录移后一位。
1、查找
二分法查找插入位置
如果R 2、后移
有点迷惑,什么时候需要后移呢?有哪些记录需要移动呢?
虽然我们很清楚的知道,我们需要后移那些排序码大于R的记录,但难免会问自己这样几个问题。其实它相当于需要移动从i-1到左指针的记录。
3、插入
由1中得到的左指针其实就是元素要插入的位置。

Java实现

/**
 * 二分插入排序
 *
 * @param nums
 * @return
 */
public static int[] binaryInsertSort(int[] nums){
    if(null == nums || nums.length == 0){
        System.out.println("输入的数组为空!");
        return null;
    }
    for (int i = 1; i < nums.length; i++) {
        int temp = nums[i];
        int low = 0, high = i - 1;
        int mid = -1;
        while (low <= high) {
            mid = low + (high - low) / 2;
            if (nums[mid] > temp) {
                high = mid - 1;
            } else { // 元素相同时,也插入在后面的位置
                low = mid + 1;
            }
        }
        for(int j = i - 1; j >= low; j--) {
            nums[j + 1] = nums[j];
        }
        nums[low] = temp;
    }
    return nums;
}

单链表直接插入排序

算法描述

单链表插入排序和数组插入排序的不同:数组插入排序是从排好序的部分的最后一个节点往前找,找到第一个比它小的数,然后插到其后面;而单链表只能从前往后遍历,找到第一个比当前节点大的值结束,因此在遍历已经排好序的链表部分的时候,需要两个指针,一个指针用于往前遍历(该指针假设为遍历指针),一个指针用于记录遍历指针指向的当前节点的前一个节点(该指针假设为遍历指针),这样当遍历指针找到第一个比待插入节点的值大的节点的时候,就可以将待插入节点插入到记录指针的后面。(之所以使用两个指针,是因为单链表不能反指)
插入排序分两种情况,一种是当前节点的值比已经排好序的尾节点的值大,则直接将当前节点挂在已排序的节点即可;一种是当前节点值比已经排好序的尾节点的值小,则需将已排好序的链表部分从头到尾遍历,找到第一个比当前节点值大的节点,插入到其前面即可。因为可能待插入的节点可能在第一个节点的前面,因此另外创建一个头结点,指向已经排好序的链表的第一个节点。这样可以每次插入新的节点的时候,将上面所提到的记录节点初始化为新创建的头结点,这样便于在第一个节点前面插入新节点。

Java实现

单链表的实现在此不赘述,有想了解的朋友可以查看https://blog.csdn.net/u014229347/article/details/88966409

/**
 * 

@filename SingleLinkedListInsertSort

*

*

@description 单链表直接插入排序

* * @author Java猿人一枚 * @version 1.0 * @since 2019/4/1 16:42 **/ public class SingleLinkedListInsertSort { public static void main(String[] args) { int[] nums = new int[]{100,34,52,6,8,78,95}; SingleLinkedList singleLinkedList = new SingleLinkedList<>(); for (int i = 0; i < nums.length; i++) { singleLinkedList.addNode(nums[i], i); } System.out.print("排序前:"); singleLinkedList.print(); System.out.println(); singleLinkedList = singleLinkedListInsertSort(singleLinkedList); System.out.print("排序后:"); singleLinkedList.print(); } /** * 单链表插入排序 * * @param singleLinkedList * @return */ public static SingleLinkedList singleLinkedListInsertSort(SingleLinkedList singleLinkedList){ SingleLinkedList.Node head = singleLinkedList.getHead(); if(head == null || head.next == null){ return singleLinkedList; }else{ SingleLinkedList newSingleLinkedList = new SingleLinkedList<>(); newSingleLinkedList.addHead(head.value); while(head.next != null){ head = head.next; SingleLinkedList.Node newHead = newSingleLinkedList.getHead(); for (int i = 0; i < newSingleLinkedList.size(); i++){ if(head.value < newHead.value){ newSingleLinkedList.addNode(head.value, i); newSingleLinkedList.print(); System.out.println(); break; }else{ newHead = newHead.next; } } } singleLinkedList = newSingleLinkedList; } return singleLinkedList; } }

以上代码均为个人实现,有问题欢迎一起交流探讨!

你可能感兴趣的:(算法与数据结构)