每日一算法|直接插入排序---第五天
Posted 江小湖资源分享平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一算法|直接插入排序---第五天相关的知识,希望对你有一定的参考价值。
插入排序
(直接插入排序)
算法
原理
直接插入排序的基本思想是:将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过为止。
插入算法较好理解,你可以类比成打扑克发牌时你整理手牌大小的过程,只是整理的过程要有顺序,具体算法描述如下:
①. 从第一个元素开始,该元素可以认为已经被排序
②. 取出下一个元素,在已经排序的元素序列中从后向前扫描
③. 如果该元素(已排序)大于新元素,将该元素移到下一位置
④. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
⑤. 将新元素插入到该位置后
⑥. 重复步骤②~⑤
插入算法里有一种优化算法,叫折半插入,也叫二分插入,和直接插入排序算法不同的是:在插入元素时,利用折半搜索法寻找插入位置。过程同直接插入排序,仅仅是在找插入位置时,不是顺序遍历,而是二分法查找位置。由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度。
初始状态:设5为有序,其中i为1,即:5 2 0 6 9
第一趟排序:low为0,high为0,则中间值下标为0((low+high)/2,下文都是如此计算),即5大于2,则插入到5前面,然后i自增。即:2 5 6 0 9
第二趟排序:low为0,high为1,则中间值下标为0,即2小于6,然后low等于中间值的下标加1,继续找中间值为5小于6,则插入到5后面,然后i自增。即:2 5 6 0 9
第三趟排序:low为0,high为2,则中间值下标为1,即5大于0,然后high等于中间值的下标减1,继续找中间值为2大于0,则插入到2前面,然后i自增。即:0 2 5 6 9
第四趟排序:low为0,high为3,则中间值下标为1,即2小于9,然后low等于中间值得下标加上1,继续找中间值为5小于9,然后low等于中间值得下标加上1,继续找中间值为6小于9,则插入到6后面,然后i自增,即:0 2 5 6 9
最终的答案为:0 2 5 6 9
C语言
直接插入排序
public class InsertSort {
public static void main(String[] args){
int arr[] = { 5 , 2 , 6 , 0 , 9};
System.out.println("排序前的数据:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
//直接插入排序
for (int i = 1; i < arr.length; i++) {
int j = i;
//待排序中的元素比已排序的元素小,则交换位置
while (j > 0 && arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
j--;
}
}
System.out.println();
System.out.println("排序后的数据:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
折半插入排序
#include<stdio.h>
int main()
{
int array[10] = {10,1,3,2,75,1000,379,0,-1,10};
//插入排序算法下标从一开始
for(int i=1;i<10;i++)
{
int start = 0; //有序数组的开头下标
int end = i-1; //有序数组的末尾下标
int dist = array[i]; //要被插入的数
int middle = 0;
//查找要被插入的下标
while(start <= end)
{
middle = (start+end)/2;
if(dist < array[middle])
{
end = middle-1;
}
else
{
//这里包含==的情况,当被插入的数大于或等于当前index的数时那么start的index就必须向右移
//向右移之后若符合条件则当前的下标即为目标数插入的下标,所以最后是array[start]=dist;
start = middle+1;
}
}
//所有数右移,移完之后插入目标数
for(int j=i;j>start;j--)
{
array[j] = array[j-1];
}
//交换array[i]与array[start]的位置
array[start] = dist;
}
for(int i=0;i<10;i++)
{
printf("%d ",array[i]);
}
return 0;
}
Java
直接插入排序
public class BinaryInsertSort {
public static void main(String[] args){
int arr[] = { 5 , 2 , 6 , 0 , 9 };
//打印排序前的数据
System.out.println("排序前的数据:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
//直接插入排序
binaryInsertSort(arr);
//打印排序后的数据
System.out.println();
System.out.println("排序后的数据:");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
private static void binaryInsertSort(int arr[]){
int low,high,m,temp,i,j;
for(i = 1;i<arr.length;i++){
//折半查找应该插入的位置
low = 0;
high = i-1;
while(low <= high){
m = (low+high)/2;
if(arr[m] > arr[i])
high = m - 1;
else
low = m + 1;
}
//统一移动元素,然后将这个元素插入到正确的位置
temp = arr[i];
for(j=i;j>high+1;j--){
arr[j] = arr[j-1];
}
arr[high+1] = temp;
}
}
}
折半插入排序
void Bin_Insert_Sort(int* a, int n)
{
int Low;
int High;
int Middle;
for (int i = 1; i < n; ++i)
{
Low = 0;
High = i - 1;
// 求取插入位置
while (Low <= High)
{
Middle = (Low + High) / 2;
if (a[Middle] > a[i])
High = Middle - 1;
else
Low = Middle + 1;
}
// 插入
for (int j = i - 1; j > High; --j)
{
swap(a[j], a[j + 1]); //这里也可以挨个移动元素后插入
}
}
}
Python
直接插入排序
def insertionSort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i]
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex+1] = arr[preIndex]
preIndex-=1
arr[preIndex+1] = current
return arr
折半插入排序
# -*- coding:utf-8 -*-
def binaryInsert(series,a):
low = 0
high = len(series) - 1
m = (low + high)//2
while low < high:
if series[m] > a:
high = m - 1
elif series[m] < a:
low = m + 1
else:
high = m
m = (low + high)//2
series.insert(high+1,a)
l = sorted([2,4,7,3,9,1,5,6,9])
binaryInsert(l,5)
print(l)
以上是关于每日一算法|直接插入排序---第五天的主要内容,如果未能解决你的问题,请参考以下文章