Collection of algorithm for sorting (part one)
冒泡排序 bubble sort :
速度撸一发冒泡. 关键点在第二层循环的初始化和两层循环一致的边界控制.
#include <stdio.h>
void bubble(int *p_array, int size)
{
int i = 0;
int j = 0;
int tmp = 0;
for (i = 0; i < size; i++)
{
for (j = 0; j < size - i; j++)
{
if(p_array[j] >= p_array[j+1])
{
tmp = p_array[j];
p_array[j] = p_array[j+1];
p_array[j+1] = tmp;
}
}
}
}
int main()
{
int array[] = {2,5,1,6,3};
bubble(array, sizeof(array)/sizeof(array[0]));
int i = 0;
for(i = 0; i < sizeof(array)/sizeof(array[0]); i++)
{
printf("\t%d", array[i]);
}
printf("\n");
return 0;
}
选择排序--Selection sort
可能你会觉得奇怪,为什么用结构体传参? 那是一层封装,我在面向对象的思想来写 : )
对已一个数组,不管怎么操作,都不能越界. C语言 不会自动检查数组越界。这个时候程序员就应该负起责任来。
数组的边界成为数组必不可少的信息,此时可以把array当作一个对象来看,即此时的element.
我们排序的对象可能会变,比方说从int类型变到char类型,这时候我们仅仅去改变struct element就可以了
不必要去改动API. 面向对象是一种思想。即使C语言不具备,但是程序员也应该有这种思想.把程序变得更棒.
/***************************************************
code writer : EOF
code date : 2014.09.14
code file : selection_sort.c
e-mail : jasonleaster@gmail.com
******************************************************/
#include <stdio.h>
#define DEBUG
#define ARRAY_SIZE 6
struct element
{
int array[ARRAY_SIZE];
int size;
};
int selection_sort(struct element* element)
{
if(!element)
{
printf("element is NULL!\n");
return 0;
}
int tmp_1 = 0;
int tmp_2 = 0;
int swap = 0;
int min_index = 0;
for(tmp_1 = 0;tmp_1 < element->size;tmp_1++)
{
min_index = tmp_1;
for(tmp_2 = tmp_1;tmp_2 < element->size;tmp_2++)
{
if(element->array[min_index] > element->array[tmp_2])
{
min_index = tmp_2;
}
}
swap = element->array[min_index];
element->array[min_index] = element->array[tmp_1];
element->array[tmp_1] = swap;
}
return 0;
}
#ifdef DEBUG
void print_element(struct element* const element)
{
if(!element)
{
printf("");
return ;
}
int tmp = 0;
for(tmp = 0;tmp < element->size; tmp++)
{
printf("%d ",element->array[tmp]);
}
printf("\n");
}
int main()
{
/*
** Initialize this element.
*/
struct element test_element = {
{1,4,9,6,3,2},
ARRAY_SIZE,
};
printf("Before sorting\n");
print_element(&test_element);
selection_sort(&test_element);
printf("Before sorting\n");
print_element(&test_element);
return 0;
}
#endif
插入排序 insertion sort
这里和上面的不同仅仅是排序算法的不同.
update : 2014.09.20(算法错误fix it up)
插入排序就是把当前待排序的元素当作对“已排序部分”的最新插入元素,如果前面的元素大于它,就逐一的往后挪动一个位置.直到找到比自己小的元素,然后插入到这个比自己小的元素后面.
/***************************************************
code writer : EOF
code date : 2014.09.14
code file : insertion_sort.c
e-mail : jasonleaster@gmail.com
update: 2014.09.20
******************************************************/
#include <stdio.h>
#define DEBUG
#define ARRAY_SIZE 6
struct element
{
int array[ARRAY_SIZE];
int size;
};
int insertion_sort(struct element* element)
{
if(!element)
{
printf("element is NULL!\n");
return 0;
}
int tmp_1 = 0;
int tmp_2 = 0;
int swap = 0;
int sentinel = 0;
for(tmp_1 = 1;tmp_1 < element->size; tmp_1++)
{
sentinel = element->array[tmp_1];
for(tmp_2 = tmp_1;element->array[tmp_2-1] > sentinel && tmp_2 > 0; tmp_2--)
{
element->array[tmp_2] = element->array[tmp_2-1];
}
element->array[tmp_2] = sentinel;
}
return 0;
}
#ifdef DEBUG
void print_element(struct element* const element)
{
if(!element)
{
printf("Function:%s line:%d Somebody passed NULL into print_element\n",__FUNCTION__,__LINE__);
return ;
}
int tmp = 0;
for(tmp = 0;tmp < element->size; tmp++)
{
printf("%d ",element->array[tmp]);
}
printf("\n");
}
int main()
{
/*
** Initialize this element.
*/
struct element test_element = {
{1,4,9,6,3,2},
ARRAY_SIZE,
};
printf("Before sorting\n");
print_element(&test_element);
insertion_sort(&test_element);
printf("Before sorting\n");
print_element(&test_element);
return 0;
}
#endif
希尔排序 shell sort
如果搞定了上面的插入排序,希尔排序不是问题的...
自己写出来就会发现,希尔排序其实就是插入排序的一种改进.它把原来插入排序的一整个数组划分成多个小数组排序.
/***************************************************
code writer : EOF
code date : 2014.09.14
code file : shell_sort.c
e-mail : jasonleaster@gmail.com
******************************************************/
#include <stdio.h>
#define DEBUG
#define ARRAY_SIZE 6
struct element
{
int array[ARRAY_SIZE];
int size;
};
int shell_sort(struct element* element)
{
if(!element)
{
printf("element is NULL!\n");
return 0;
}
int increment = 0;
int tmp_1 = 0;
int tmp_2 = 0;
int swap = 0;
for(increment = element->size/2; increment > 0;increment /=2 )
{
for(tmp_1 = increment;tmp_1 < element->size;tmp_1++)
{
for(tmp_2 = tmp_1;tmp_2 >= increment;tmp_2 -= increment)
{
if(element->array[tmp_2] < element->array[tmp_2-increment])
{
swap = element->array[tmp_2-increment];
element->array[tmp_2-increment] = element->array[tmp_2];
element->array[tmp_2] = swap;
}
}
}
}
return 0;
}
#ifdef DEBUG
void print_element(struct element* const element)
{
if(!element)
{
printf("Panic! NULL was passed into %s %d :(",__FUNCTION__,__LINE__);
return ;
}
int tmp = 0;
for(tmp = 0;tmp < element->size; tmp++)
{
printf("%d ",element->array[tmp]);
}
printf("\n");
}
int main()
{
/*
** Initialize this element.
*/
struct element test_element = {
{1,4,9,6,3,2},
ARRAY_SIZE,
};
printf("Before sorting\n");
print_element(&test_element);
shell_sort(&test_element);
printf("Before sorting\n");
print_element(&test_element);
return 0;
}
#endif
西斯廷圣母 拉斐尔