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

最近想看下算法,把<<算法概论>> <<算法引论>><<算法导论>>都翻了出来,感觉<<算法导论>>的描述最清晰,最啰嗦,最适合菜鸟做编程练习,<<算法概论>>讲解很清晰,看的很舒服,比<<算法导论>>更明白算法的实质,但是伪码描述没有<<算法导论>>详细。以前算法课老师讲解很认真,几乎每个算法都用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]);

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值