1. 程式人生 > >插入排序--直接插入、折半插入

插入排序--直接插入、折半插入

  昨天寫了交換排序的演算法(包括氣泡排序、快速排序),今天寫一寫插入排序。插入排序有三種:直接插入排序、折半插入排序、希爾排序。時間有限,今天先寫一下直接插入排序和折半插入排序,希爾排序等明天有時間再寫!
  插入排序是將未排序序列中的元素依次拿出來與已排序序列中的元素進行比較,插入到已排序序列中的適當位置的排序方法。
  直接插入排序是一種簡單的排序的方法,基本操作為:將一個元素插入到已排序的序列中。初始預設第一個元素為有序序列,從第二個元素開始依次進行插入排序。
程式碼如下:

//簡單插入排序
void straightInsertSort(int *arr,int len)
{ int i = 0; int j = 0; for(i = 2;i < len;i++) { arr[0] = arr[i];//元素a[0]用於存放待比較元素,不用來存放資料 for(j = i - 1;j > 0;j--) { if(arr[0] < arr[j]) { arr[j + 1] = arr[j]; } else { break
; } } arr[j + 1] = arr[0]; } }

  折半插入排序原理與直接插入排序一致,只不過折半插入排序首先查詢元素要插入的位置,其查詢方法採用折半查詢,提高來執行效率。
程式碼如下:

//折半查詢
int halveSearch(int *arr,int low,int high,int elem)
{
    int mid = (low + high)/2;
    while(low < high)
    {
        if(elem > arr[mid])
        {
            low =
mid + 1; } else { high = mid - 1; } mid = (low + high) / 2; } return low; } //折半插入排序 void halveInsertSort(int *arr,int len) { int i = 0; int j = 0; int temp = 0; for(i = 2;i < len;i++) { if(arr[i] > arr[i - 1]) { continue; } temp = halveSearch(arr,1,i - 1,arr[i]); arr[0] = arr[i]; for(j = i;j > temp;j --) { arr[j] = arr[j - 1]; } arr[temp] = arr[0]; } }

  這兩個演算法看起來很簡單,但是如果邏輯搞不清楚,還是很容易出錯。有的時候看起來簡單的東西做起來並不一定簡單,而看起來複雜的事情做起來並不一定那麼難。但是關鍵是自己要動手才知道事情到底是怎樣的,會犯哪些錯誤,走哪些彎路,才能積累相應的經驗!之前一直覺得直接插入排序很簡單,但是真正去實現的時候發現自己並沒有做到一次性編寫成功,正確的執行結果是在修改了幾個位置之後才得到的;而之前一直以為快排很麻煩,但是昨天寫過後發現快排也沒有自己想象的那麼難,所以還是要多動手!
最後附上所有程式碼:

#include <stdio.h>

//簡單插入排序
void straightInsertSort(int *arr,int len)
{
    int i = 0;
    int j = 0;
    for(i = 2;i < len;i++)
    {
        arr[0] = arr[i];//元素a[0]用於存放待比較元素,不用來存放資料
        for(j = i - 1;j > 0;j--)
        {
            if(arr[0] < arr[j])
            {
                arr[j + 1] = arr[j];
            }
            else
            {
                break;
            }
        }
        arr[j + 1] = arr[0];
    }
}

//折半查詢
int halveSearch(int *arr,int low,int high,int elem)
{
    int mid = (low + high)/2;
    while(low < high)
    {
        if(elem > arr[mid])
        {
            low = mid + 1;
        }
        else
        {
            high = mid - 1;
        }
        mid = (low + high) / 2;
    }
    return low;
}

//折半插入排序
void halveInsertSort(int *arr,int len)
{
    int i = 0;
    int j = 0;
    int temp = 0;
    for(i = 2;i < len;i++)
    {
        if(arr[i] > arr[i - 1])
        {
            continue;
        }
        temp = halveSearch(arr,1,i - 1,arr[i]);
        arr[0] = arr[i];
        for(j = i;j > temp;j --)
        {
            arr[j] = arr[j - 1];
        }
        arr[temp] = arr[0];
    }
}

int main()
{
    int i = 0;
    int arr[7] = {0,6,4,9,2,5,3};
    printf("Before straight insertSort arr:\n");
    for(i = 1;i < 7;i ++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
    straightInsertSort(arr,7);
    printf("After straight insertSort arr:\n");
    for(i = 1;i < 7;i ++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
    int arr2[7] = {0,6,4,9,4,5,3};
    printf("Before halve insertSort arr2:\n");
    for(i = 1;i < 7;i ++)
    {
        printf("%d ",arr2[i]);
    }
    printf("\n");
    halveInsertSort(arr2,7);
    printf("After halve insertSort arr2:\n");
    for(i = 1;i < 7;i ++)
    {
        printf("%d ",arr2[i]);
    }
    printf("\n");
    return 0;
}