【经典算法】直接插入排序

116 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

直接插入排序

思路过程:

原有序列的基础上,从左至右依次扫描,为每个扫描到元素找到在前面找到合适的位置。

算法图解:

b1399023378e407ec04f400b7d12e8cf

代码(c语言):

//直接插入排序法
#include <stdio.h>
 
void Compare(int arr[], int len)
{
    int i = 0;
    for (i = 0; i < len-1; i++)//len减一因为要插入的数是i+1
    {
        int M = i;//记录有序列表最后应该元素下标
        int num = arr[i + 1];//要插入的数
        while (M >= 0)
        {
            if (num < arr[M])//继续比较
            {
                arr[M + 1] = arr[M];//交换数值
                M--;
            }
            else
            {
                break;
            }
        }
        arr[M + 1] = num;
    }
}

评价:

适用于基本有序序列,元素个数较小的序列

实战演练:

题目链接:147. 对链表进行插入排序

题目思路:

从前往后找插入点,初始时有序序列只有一个元素,每次将一个新的元素插入到有序序列中,将有序序列的长度增加 1,直到全部元素都加入到有序序列中。

如果要操作的数据结构是数组,则要保证数组的前面部分是有序序列,在有序序列的后面寻找应该插入的位置,因为是数组,所以需要我们必须将确定位置的之后的元素全部向后移动,然后完成插入。

如果待操作的数据结构是链表,则在插入元素的时候,我们仅仅只需要更新相邻的节点的指针即可,不用像数组则需要从前到后的移动,所以链表的插入操作相比较而言是较为简单的。

代码:

struct ListNode *insertionSortList(struct ListNode *head) {
    if (head == NULL) {
        return head;
    }
    struct ListNode *dummyHead = malloc(sizeof(struct ListNode));
    dummyHead->val = 0;
    dummyHead->next = head;
    struct ListNode *lastSorted = head;
    struct ListNode *curr = head->next;
    while (curr != NULL) {
        if (lastSorted->val <= curr->val) {
            lastSorted = lastSorted->next;
        } else {
            struct ListNode *prev = dummyHead;
            while (prev->next->val <= curr->val) {
                prev = prev->next;
            }
            lastSorted->next = curr->next;
            curr->next = prev->next;
            prev->next = curr;
        }
        curr = lastSorted->next;
    }
    return dummyHead->next;
}