您的位置:首页 > 其它

CLRS-Ch2(插入排序、合并排序、冒泡排序)

2011-11-26 04:35 316 查看
最近想看下算法,把<<算法概论>> <<算法引论>><<算法导论>>都翻了出来,感觉<<算法导论>>的描述最清晰,最啰嗦,最适合菜鸟做编程练习,<<算法概论>>讲解很清晰,看的很舒服,比<<算法导论>>更明白算法的实质,但是伪码描述没有<<算法导论>>详细。以前算法课老师讲解很认真,几乎每个算法都用c代码现场演示过,但是当时只是听了,自己没有练习,基本都忘的差不多了,现在有空了就实际的编程练习下。

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

/**
* @brief : int版
*/
void insert_sort_int(int *arr , int n)
{
int key;
int i,j;
for(i = 1 ; i < n ; i++){
key = arr[i];
j = i - 1;

while(j >= 0 && arr[j] > key){
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}

/**
* @brief : 通用版插入排序
*/
void insert_sort(void *pv , int elemSize , int n , int (*cmp)(void *pv1 , void *pv2))
{
char *pb;
char *pkey;
int i,j;

assert(pv != NULL);
assert(elemSize != 0 && n != 0);
assert(cmp != NULL);

pb = (char *)pv;

if((pkey = (char *)malloc(elemSize)) == NULL){
fprintf(stderr , "Malloc Error\n");
return ;
}

for(i = 1 ; i < n ; i++){
memcpy(pkey , pb + (i * elemSize) , elemSize);
j = i - 1;

while(j >= 0 && cmp(pkey , (pb + (j * elemSize))) < 0){
memmove(pb + (j + 1) * elemSize , pb + j * elemSize , elemSize);
j--;
}

memcpy(pb + (j + 1) * elemSize , pkey , elemSize);
}
free(pkey);
}

static int int_cmp(void *pv1 , void *pv2)
{
int *pi1 ,*pi2;
pi1 = (int *)pv1;
pi2 = (int *)pv2;

return (*pi1 - *pi2);
}

#define ARRAYSZ     1 << 12
int arr[ARRAYSZ];

int main()
{
int i;
printf("%d\n" , ARRAYSZ);
srand(time(NULL));
for(i = 0 ; i < ARRAYSZ ; i++){
arr[i] = rand() % 1000000;
}

insert_sort(arr , sizeof(int) , sizeof(arr) / sizeof(int) , int_cmp);
//	 insert_sort_int(arr , sizeof(arr) / sizeof(int));
for(i = 0 ; i < ARRAYSZ ; i++){
printf("%d\n" , arr[i]);
}

return 0;
}


测试了一下合并排序,windows+Mingw,递归五十多万层后栈溢出,计算了下栈区大概有10M(52w * 20byte),linux试了下,栈自动扩展,递归深度不会是瓶颈。

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

static void merge(int arr[] , int left , int right);

/**
* @brief : 合并排序整形数
*/
void merge_sort_int(int arr[] , int left , int right)
{
int mid;

if(left < right){
mid = (left + right) / 2;
merge_sort_int(arr , left , mid);
merge_sort_int(arr , mid + 1 , right);
merge(arr , left , right);
}
}

static void merge(int arr[] , int left , int right)
{
int mid = (left + right) / 2;
int nl = mid + 1 - left;
int nr = right - mid;
int narr = right - left + 1;
int al[nl];
int ar[nr];
int i,j,k;

for(i = 0 ; i < nl ; i++){
al[i] = arr[left + i];
}

for(i = 0 ; i < nl ; i++){
ar[i] = arr[mid + i + 1];
}

al[nl] = INT_MAX;
ar[nr] = INT_MAX;

i = j = 0;
for(k = left ; k < narr + left ;){
if(al[i] < ar[j]){
arr[k++] = al[i++];
}else{
arr[k++] = ar[j++];
}
}
}

#define ARRAYSZ  (1 << 10)
static int array[ARRAYSZ];
int main()
{
int i;
srand(time(NULL));

for(i = 0 ; i < ARRAYSZ ; i++)
array[i] = rand() % 100000000;

merge_sort_int(array , 0 , ARRAYSZ - 1);

for(i = 0 ; i < ARRAYSZ ; i++)
printf("%d\n" , array[i]);

return 0;
}

习题里有个冒泡排序,c代码如下:

#include <stdio.h>
#include <time.h>

/**
* @brief : 冒泡排序
*/
void bubble_sort(int arr[] , int n)
{
int i,j,m,tmp;
m = n - 1;
for(i = 0 ; i < m ; i++){
for(j = m ; j >= i ; j--){
if(arr[j] < arr[j - 1]){
tmp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = tmp;
}
}
}
}

#define ARRAYSZ  (1 << 15)
static int array[ARRAYSZ];
int main()
{
int i;
srand(time(NULL));
for(i = 0 ; i < ARRAYSZ ; i++)
array[i] = rand() % 1000000;

bubble_sort(array , ARRAYSZ);

for(i = 0 ; i < ARRAYSZ ; i++)
printf("%d\n" , array[i]);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐