1. 程式人生 > >C語言-資料結構-插入排序及優化-原始碼

C語言-資料結構-插入排序及優化-原始碼

1. 插入排序的定義及複雜度

插入排序的基本思想是:每步將一個待排序的紀錄,按其關鍵碼值的大小插入前面已經排序的檔案中適當位置上,直到全部插入完為止。其時間複雜度為O(n^2)。

2. 原始碼

執行結果如下圖所示。


#include<stdio.h>

void insertsort(int a[], int n)
{
    int i, j, temp, c1=0;
    for(i=1;i<n;i++)
    {
        if(a[i]<a[i-1])//如果後面出現比前面小的數字
        {
            temp=a[i];
            for(j=i-1;temp<a[j]&&j>=0;j--)//把前面的數字移動,挪出一個合適的位置給a[i]
            {
                c1++;
                a[j+1]=a[j];
            }
            a[j+1]=temp;
        }
    }
    printf("總計資料交換%d次\n\n", c1);
}

int main(void)
{
    int i;
    int a[10]={1,2,0,3,4,5,6,7,9,8};
    printf("排序前:");
    for(i=0;i<10;i++)
    {
        printf("%d",a[i]);
    }
    printf("\n\n\n");
    insertsort(a, 10);
    printf("排序後:");
    for(i=0;i<10;i++)
    {
        printf("%d",a[i]);
    }
    printf("\n\n\n");
    return 0;
}

3. 折半插入排序

折半插入排序又叫二分插入排序,其思想是,對於前部分已經排序好的陣列,進行折半查詢(查詢合適的插入位置),這樣可以減少比較的次數,但是資料交換的次數並沒有減少,所以其時間複雜度仍為O(n^2).

原始碼如下:

#include<stdio.h>
void BInsertSort(int *a, int n)
{
	int i, j, m, high, low, temp;//m為折半的中間點下標, low為查詢的下邊界, high為查詢的上邊界
	
	//從i=1開始,尋找a[i]應該插入的位置,迴圈結束後,low的值就是a[i]應該放置的位置
	for(i=1; i<n; i++)
	{	high=i-1;
		low=0;
		while(high>=low)
		{
			m=(high+low)/2;
			if(a[i]>=a[m])//如果a[i]大於等於a[m],則a[i]應該插入a[m]的右半部分
			{
				low=m+1;
			}
			else//相反則應插入a[m]的左半部分
			{
				high=m-1;
			}
		}
		temp=a[i];//備份a[i]
		
		//給a[i]騰位置
		for(j=i-1; j>=low;j--)//資料交換,將a[low]及之後的資料都向後移動一位,騰出a[low]的位置給a[i]
		{
			a[j+1]=a[j];
		}
		//a[j+1]=temp;
		a[low]=temp;
	}
}

int main(void)  
{  
    int i;  
    int a[10]={2,1,0,3,4,5,6,7,9,8};  
    printf("排序前:");  
    for(i=0;i<10;i++)  
    {  
        printf("%d",a[i]);  
    }  
    printf("\n\n\n");  
    BInsertSort(a, 10);  
    printf("排序後:");  
    for(i=0;i<10;i++)  
    {  
        printf("%d",a[i]);  
    }  
    printf("\n\n\n");  
    return 0;  
}