二分法插入排序算法的尝试

  这是一个《算法导论》上的练习,可将插入排序的总体运行时间降至Θ(nlgn),我们先看看插入排序的算法代码:

#include <stdio.h>

int main(void)
{
    int arr[] = {6,3,1,5,4,2};
    int i, j;
    int temp;

    for(i = 1; i < sizeof(arr)/sizeof(int); i++)    //运行时间Θ(n)
    {
        temp = arr[i];
        j = i - 1;
        while(j >= 0 && arr[j] > temp)        //这里线性时间进行查找移动,运行时间Θ(n),所以整体运行时间Θ(n^2)
        {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = temp;
    }

    for(i = 0; i < sizeof(arr)/sizeof(int); i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

  从代码可以看出,arr[j] > temp的判断查找是在前面所有小于 j 的部分中进行移动和查找的,而小于的 j 部分都是已经排好序的,因此我们可设计使用二分查找带进行更快速的处理。但我的尝试出现了问题:

/**
 *  二分法+插入排序 - Θ(nlgn)
 *
 */
#include <stdio.h>

int main(void)
{
    int arr[] = {6,3,1,5,4,2};
    int i, j;
    int mid, left;
    int temp;

    left = 0;
    for(i = 1; i < sizeof(arr)/sizeof(int); i++)
    {
        temp = arr[i];
        j = i - 1;
        mid = (left + j) / 2;
        while(temp > arr[mid + 1] || temp < arr[mid - 1])             //情况是这样的,比如:进行到 123645,当把4进行比较后,从1236中查找位置时     //只有当同时不满足循环条件,即 3 < 4 < 6 时,不满足条件 ,就可以退出了,当前的 mid 就是4可以插入的位置。
        {
            if(arr[mid] > temp)
                mid = (mid + j) / 2;
            else if(arr[mid] < temp)
                mid = (left + mid) / 2;
        }
        for(j = i - 1; j >= mid; j--){    //移动要插入的位置以后且小于当前比较数以前的位置
            arr[j + 1] = arr[j];
        }
        arr[j] = temp;    //把比较数插入其中
    }

    for(i = 0; i < sizeof(arr)/sizeof(int); i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

  然而,我的尝试失败了,代码看上去好像没什么问题,但while还是陷入了死循环,不知道什么原因...这个循环条件的判断难道有什么问题吗?我暂时先记录下来吧,改天再继续思考这个问题...

时间: 2024-08-11 01:36:20

二分法插入排序算法的尝试的相关文章

二分法插入排序

二分法插入排序 算法思想简单描写叙述:在插入第i个元素时,对前面的0-i-1元素进行折半,先跟他们中间的那个元素比,假设小,则对前半再进行折半,否则对后半进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间的全部元素后移,再把第i个元素放在目标位置上.二分法没有排序,仅仅有查找.所以当找到要插入的位置时.移动必须从最后一个记录開始,向后移动一位,再移动倒数第2位,直到要插入的位置的记录移后一位.二分插入排序是稳定的,平均时间O(n2)     void binsort(re

矿Java开发学习之旅------&amp;gt;Java排序算法经典的二分法插入排序

一.折半插入排序(二分插入排序) 将直接插入排序中寻找A[i]的插入位置的方法改为採用折半比較,就可以得到折半插入排序算法.在处理A[i]时,A[0]--A[i-1]已经按关键码值排好序.所谓折半比較,就是在插入A[i]时,取A[i-1/2]的关键码值与A[i]的关键码值进行比較,假设A[i]的关键码值小于A[i-1/2]的关键码值.则说明A[i]仅仅能插入A[0]到A[i-1/2]之间.故能够在A[0]到A[i-1/2-1]之间继续使用折半比較:否则仅仅能插入A[i-1/2]到A[i-1]之间

插入排序算法回顾(python实现)

插入排序的基本方法是:每步将一个待排序的记录按其关键字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止. 折半插入排序是对插入排序算法的一种改进,由于排序算法过程中,就是不断的依次将元素插入前面已排好序的序列中.由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度.具体操作为:在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high],则轮比较时将待插入元素与

插入排序算法的学习

插入排序算法: 例如序列:5,6,3,7,8,2 采用插入排序算法对序列进行排序, 具体步骤如下: 第一步: 将6单独提取出来,放在一个变量中去寄存: 然后让5与寄存项进行比较,不满足前项大于寄存项,保持原有序列不变 序列为:5,6,3,7,8,2 第二步: 将3单独提取出来,放在一个变量中去寄存: 然后让6与寄存项进行比较,满足前项大于寄存项,将3位置用6覆盖掉: 序列为:5,6,6,7,8,2 然后将5与寄存项进行比较,满足前项大于寄存项,将第一个6位置用5覆盖掉: 序列为:5,5,6,7,

“深入理解”—插入排序算法

总结下自己对插入排序的理解. 插入排序算法思想:每趟将一个元素,按照其关键字的大小插入到它前面已经排序的子序列中,依此重复,直到插入全部元素. 插入排序包括:直接插入排序.二分插入排序以及希尔排序. 1.直接插入排序: public void insert(int[] a) { for(int i=1;i<a.length;i++) //n-1此扫描,依次向前插入n-1个元素 { int temp=a[i]; //每趟将a[i]插入到前面的排序子序列中 int j; for(j=i-1;j>=

插入排序算法

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序算法.插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序. 插入排序的Java实现: 1 package com.mianshi.easy; 2 public class Insert { 3 4 public static void main(String[] args) { 5

数据结构——排序——直接插入排序和折半插入排序算法

直接插入排序(Insertion Sort)的基本思想是: 每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止. 设数组为a[0…n-1]: 1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1].令i=1 2. 将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间. 3. i++并重复第二步直到i==n-1.排序完成. #include<stdio.h> #include<stdbool.h> vo

插入排序算法---插入排序与希尔排序

本文主要说明插入排序.shell排序两种排序方法.  一.插入排序  算法思想:  假定这个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止.这具算法在排完前k个数之后,可以保证a[1…k]是局部有序的,保证了插入过程的正确性. 一般来说,插入排序都采用in-place在数组上实现.具体算法描述如下: ⒈ 从第一个元素开始,该元素可以认为已经被排序 ⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描 ⒊ 如果

插入排序算法之直接插入排序和希尔排序

插入排序算法 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法--插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据. 直接插入排序 直接插入排序的排序思路是:每次将一个待排序的元素与已排序的元素进行逐一比较,直到找到合适的位置按大小插入. 例子: 有序列: 开始时,有序序列只有一个元素就是第一个元素(红色),后面的无序序列(绿色).接下来,取无序序列中