1. 程式人生 > >C語言直接插入排序和折半插入排序演算法的實現

C語言直接插入排序和折半插入排序演算法的實現

直接插入排序是是一種穩定的排序,其演算法簡便,適用於順序結構和鏈式結構,更適合於基本有序(正序)的情況。其空間複雜度為O(1),時間複雜度為O(n2)。下面是實現演算法:

先是預定義和型別定義:

typedef int Status;
typedef int ElemType;

typedef struct{
	ElemType *data;
	int length;
}SqList;

建立連結串列:

Status EnSqList(SqList *L, ElemType e, int n)
{
	L->data[n + 1] = e;
	L->length++;
	return OK;
}

直接插入排序:

void InsertSort(SqList *L)
{
	int i, j;
	for (i = 2; i <= L->length; i++)
	{
		if (L->data[i] < L->data[i - 1])
		{
			L->data[0] = L->data[i];
			L->data[i] = L->data[i - 1];
			for (j = i - 2; L->data[j]>L->data[0]; j--)
				L->data[j + 1] = L->data[j];
			L->data[j + 1] = L->data[0];
		}
	}
}

先讓i等於2(只有一個元素的話沒有必要排序),判斷i下標的值是否比它前一個值要小,若是,則將i下標的值儲存在下標為0的元素中,並讓前一位元素後移一位(移動到i的位置)。之後利用迴圈判斷之前的值是否比0號元素大,若是,則後移,直到遇到元素比0號元素小的,則將0號元素儲存在比它小元素的下一個節點。

加入main():


int main(void)
{
	SqList L;
	ElemType e;
	int i, n;
	L.data = (int *)malloc(sizeof(int)*MVNum);
	L.length = 0;
	printf("輸入元素個數:");
	scanf("%d", &n);
	printf("輸入各個元素:");
	for (i = 1; i <= n; i++)
	{
		scanf("%d", &e);
		EnSqList(&L, e, L.length);
	}
	InsertSort(&L);
	for (i = 1; i <= L.length; i++)
		printf("%d ", L.data[i]);
	printf("\n");
	return 0;
}

折半插入排序也是一種穩定的排序,不可作用於鏈式儲存結構,適合用於初始值無序,且n值比較大的情況。其空間複雜度為O(1),時間複雜度為O(n2)。下面是實現程式碼:

首先預定義和型別定義:

#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;

typedef struct{
	ElemType *data;
	int length;
}SqList;

建立連結串列:

Status EnSqList(SqList *L,ElemType e,int n)
{
	if (L->length >= n)
		return ERROR;
	L->data[L->length + 1] = e;
	L->length++;
	return OK;
}

折半插入排序演算法:

void BInsertSort(SqList *L)
{
	int i, j, mid, high, low;
	for (i = 2; i <= L->length; i++)
	{
		low = 1;
		high = i - 1;
		L->data[0] = L->data[i];
		while (low <= high)
		{
			mid = (low + high) / 2;
			if (L->data[0] < L->data[mid])
				high = mid - 1;
			else
				low = mid + 1;
		}
		for (j = i - 1; j >= high + 1; j--)
			L->data[j + 1] = L->data[j];
		L->data[high + 1] = L->data[0];
	}
}

從下標為2的元素開始(只有一個元素的話根本就沒必要排序),讓下標為0的元素儲存下標為i元素的值,並初始化low為1,high為i-1。當low小於或等於high的時候,未確定插入位置,由於i之前的元素肯定有序,則利用折半的方法確定插入位置。讓後將下標等於high之前的元素值都後移一位。讓後將下標為0的元素(原來要排序的元素)插入到下標為high+1的位置。

加入main():

int main(void)
{
	SqList L;
	int n, i;
	ElemType e;
	L.length = 0;
	printf("輸入元素個數:");
	scanf("%d", &n);
	L.data = (int *)malloc(sizeof(int)*n);
	printf("輸入各個元素的值:");
	for (i = 0; i < n; i++)
	{
		scanf("%d", &e);
		EnSqList(&L, e, n);
	}
	BInsertSort(&L);
	for (i = 1; i <= n; i++)
		printf("%d ", L.data[i]);
	printf("\n");
	return 0;
}