您的位置:首页 > 编程语言 > C语言/C++

直接插入排序(C语言版)

2014-10-05 01:35 197 查看
先说说直接插入排序的思想:

将一个数插入到一个已经有序的表中,得到一个新的、数量增一的有序表。

稳定性和复杂度:

直接插入排序是稳定的排序算法;时间复杂度最坏为O(n2),平均为O(n2),空间复杂度为O(1)。

下面是我用C语言实现的直接插入排序,如果有什么问题请各位指出,谢谢。

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

void insertSort(int array[], int size);
void insertSort2(int array[], int size);
void printArray(int *array, int size);

int main(int argc, char const *argv[])
{
    int size = 0;
    scanf("%d", &size);
    assert(size > 0);

    int *array = (int *)calloc(size, sizeof(int));
    int i = 0;
    for (i = 0; i < size; ++i) {
        scanf("%d", &array[i]);
    }

    insertSort2(array, size);
    printArray(array, size);

    free(array);
    return 0;
}

//按从小到大的次序进行排序
void insertSort(int array[], int size) 
{
    assert(array != NULL && size > 0);
	int insertVal = 0;
	int insertPos = 0;

	int i = 0;
	int j = 0;
	for (i = 0; i < size; ++i) {
		insertPos = i;
		insertVal = array[i];
		//在array[0..i]中寻找插入的位置
		for (j = 0; j < i; ++j) {
			if (array[i] < array[j]) {
				insertPos = j;
				break;
			}
		}
		//当插入位置不同于要插入元素的自身的位置时,
		//把array[j..i]中的所有元素向后移动一位
		if (insertPos != i) {
			int k = 0;
			for (k = i; k > j; --k) {
				array[k] = array[k - 1];
			}
			array[insertPos] = insertVal;
		}
	}
}

void printArray(int *array, int size)
{
    assert(array != NULL && size > 0);
	
    int i = 0;
    for (i = 0; i < size; ++i) {
        printf("%d ", array[i]);
    }
    printf("\n");
}

上面的这个insertSort()函数的算法还不够简练和高效,下面是我在其他地方看到的方法:

void insertSort2(int array[], int size) 
{
    assert(array != NULL && size > 0);
	int insertVal = 0;

	int i = 0;
	int j = 0;
	for (i = 1; i < size; ++i) {
		insertVal = array[i];
		//若第i-1个元素大于第i个元素,则移动后插入;
		//否则无需任何操作
		if (array[i - 1] > insertVal) {
			j = i - 1;
			//寻找插入位置,一边寻找一边后移
			while (j >= 0 && array[j] > insertVal) {
			    array[j + 1] = array[j];
			    --j;
			}
			array[j + 1] = insertVal;
		}
	}
}

这个方法的优点在于在寻找插入位置的同时移动了要插入位置之后的元素,而不用两次循环。

其他八种排序算法的博客:

常见的9种内部排序(C语言实现)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: