(经典)直接插入排序based on 二分查找

#include<stdio.h>
// 查找第一个大于key的元素,成功则返回该元素的下标,否则返回数组末元素的下一位
int findFirstLarger(int A[],int n, int key)
{
    int left = 0;
    int right = n-1;

    // 这里必须是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (A[mid] > key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return left;
}

void insert(int a[],int n)
{   int flag,temp,j,i,k;

    //3个元素要进行2趟排序
    for(j=1;j<n;j++){  //对位序1,2,3....n分别进行插入,bug隐藏在这,应该是1,2,3,n-1

        //对[0,j-1]进行插入排序,将j指向的元素插入
        flag = findFirstLarger(a,j,a[j]);

        if(flag ==j) continue ;
        temp = a[j]; //保存将要插入的元素
        //将i(flag待插入的那个位置)之后的元素后移动一位
        for(k=j;k>flag;k--){
            a[k]=a[k-1];
        }
        //将temp插入到i这个位置
        a[flag] = temp;

    }

}

int main()
{   int tt;
    int a[] = {1,90,90,4,4,4,9,9,10,20,20,-1010,222,666};
    insert(a,14);
    for(tt=0;tt<14;tt++){
        printf("%d\n",a[tt]);
    }
    return 0;
}

典型错误:

//顺序查找第一个比key大的元素

int position1(int a[],int n,int key)//传入有序表和要查找的元素位置
{
    int i;
    for(i=0;i<n;i++){
        if(a[i]>key)  return i; //这样做就不行了
    }
    return i+1;
}

//这个才是正确的
int position(int a[],int n,int key)//传入有序表和要查找的元素位置
{
    int i,index=-1;
    for(i=0;i<n;i++){
        if(a[i]>key)  index = i ; break; //从前往后是大于符号
    }
    if(index == -1)
        return n;
    else return index;
}
时间: 2024-10-24 10:10:31

(经典)直接插入排序based on 二分查找的相关文章

经典算法系列之:二分查找

1.前言 算法,在计算机中的地位,就相当于人类大脑的决策中枢系统,哪怕最简单的算法,其精妙的思维方式,都可以让人开启一扇新的视窗. 算法,它不仅仅只是狭义的用来解决计算机科学领域的问题,更是一种"思维方式".算法思维,是一种深度思考和创造的过程. 算法,只有真正理解了,而不只是所谓的知道,并将应用到生活.工作.学习等各个方面,它将一定使人受益终生. 2.原理推导 二分查找,前提是在排好序的基础上,每次查找,将数据集合分成两个部分,取中间索引数值与被查找的数值比较,逐次缩小查找范围,直到

最优雅的二分查找

今天复习以前的代码,突然发现插入排序用的二分查找算法实现得很别扭,于是试试重写一个,没想到相当顺利,几分钟就写好并测试通过了: static int BinarySearch(int[] array, int value, int start, int end) { if(start == end) return start; var middle = (start + end)/2 + 1; if(value >= array[middle]) return BinarySearch(arra

Java学习 (七)、数组,查找算法,二分查找法,冒泡排序,选择排序,插入排序

一.常用数组查找算法 工作原理:它又称为顺序查找,在一列给定的值中进行搜索,从一端的开始逐一检查每个元素,知道找到所需元素的过程. 例1:查找指定的数在数组中出现的位置,找到返回下标,找不到返回-1 1 import java.util.Scanner; 2 public class LinearSearch{ 3 public static void main(String []argas) 4 { 5 int [] array={10,100,90,65,80,92}; 6 System.o

【从零学习经典算法系列】分治策略实例——二分查找

1.二分查找算法简介 二分查找算法是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组 为空,则代表找不到.这种搜索算法每一次比较都使搜索范围缩小一半.折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn). 二分查找的优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且

C语言实现直接插入排序,冒泡排序以及二分查找(巩固理解记忆)

C语言实现直接插入排序,冒泡排序以及二分查找(巩固理解记忆) 虽然直接插入排序,冒泡排序以及二分查找是算法中最为基础以及老掉牙的话题,但作为一名算法的深爱者,有时候无聊时候总会将这些简单的话题重新理解并敲写一番,目的只是为了得到理解娴熟的程度.而且,我觉得越是简单基础的东西,有时候更应该反复的去敲写,深化它,并最终让其中的思想内化为自己的一部分.待到他日一提起之时,会相当娴熟的"刷刷刷..."几分钟搞定,那就很有成就感了! 因为我喜欢对于一个问题进行实例的剖析,进而再转化为特有的用某种

优化的直接插入排序(二分查找插入排序,希尔排序)

直接插入排序 (一)概念及实现 直接插入排序的原理:先将原序列分为有序区和无序区,然后再经过比较和后移操作将无序区元素插入到有序区中. 具体如下(实现为升序): 设数组为a[0…n]. 1.        将原序列分成有序区和无序区.a[0…i-1]为有序区,a[i…n] 为无序区.(i从1开始) 2.        从无序区中取出第一个元素,即a[i],在有序区序列中从后向前扫描. 3.        如果有序元素大于a[i],将有序元素后移到下一位置. 4.        重复步骤3,直到找

入门算法-二分查找,二分排序,插入排序,冒泡排序

1.二分查找(nlogn) 二分查找,需要将业务模拟一个有序数组.然后查找某个值在该数组中的位置. 二分查找的关键是: 1)查找的值一定在某次的范围中间.即使值是最后一个,也要按照二分法的规则去查找. 2)有左右边界的查找范围作为一个循环不变式 function bsearch(A, x) { // A 是有序升数组:x是待查值; 结果要返回x在A中的位置 // 循环不变式 let l = 0,r = A.length-1, guess; while(i <= r) { guess = Math

从二分查找到折半插入排序

目录 从二分查找到折半插入排序 折半插入排序性能 Code 从二分查找到折半插入排序 回忆直接插入排序的过程,发现每趟排序中进行了两个动作: \1. 从左边的已排序序列中找寻插入位置. \2. 给插入位置腾出空间,将插入元素复制到表中的插入位置. 步骤一在直接插入排序中是一个"Linear Search"顺序查找过程,而我们知道二分查找比顺序查找更优秀. 折半插入排序性能 Space Complexity: S(n)=O(1) Time Complexity: T(n)=O(\(n^2

Leetcode 981. Time Based Key-Value Store(二分查找)

题目来源:https://leetcode.com/problems/time-based-key-value-store/description/ 标记难度:Medium 提交次数:1/1 代码效率:33.33%(212ms) 题意 给定一系列set和get操作,其中: 每个set操作包含一个key,一个value和一个timestamp,其中timestamp是严格递增的 每个get操作包含一个key和一个timestamp,要求找出与这个key相等且时间戳<=timestamp的set操作