132 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			132 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | 
 | ||
|  | #include "list.h"
 | ||
|  | #include "stdlib.h"
 | ||
|  | #include "string.h"
 | ||
|  | #include "stdio.h"
 | ||
|  | #include "board.h"
 | ||
|  | #include "mystdlib.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // 计算对应节点序号
 | ||
|  | #define GET_FATHER_INDEX(index)   (((index)-1)/2) 
 | ||
|  | #define GET_LEFT_INDEX(index)	    ((((index)+1)*2)-1)
 | ||
|  | #define GET_RIGHT_INDEX(index)	  (((index)+1)*2)
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte)
 | ||
|  | //{
 | ||
|  | //  for(int i=0;i<num_4byte;i++)
 | ||
|  | //  {
 | ||
|  | //    dst[i]=src[i];
 | ||
|  | //  }
 | ||
|  | //}
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // 数据下沉
 | ||
|  | // 输入:待排序列,要下沉的父节点序号,待排序列长度
 | ||
|  | static void heap_sink(list_def *l, sub_fun_def sub,int start,int size) | ||
|  | { | ||
|  | 	int left, right, index; | ||
|  |   int temp_size=list_block_size4(l); | ||
|  |   void *temp=malloc(temp_size); | ||
|  |   void *l_left,*l_right,*l_i,*l_index; | ||
|  |   param_check(temp); | ||
|  | 	for (int i = start; i < size;) | ||
|  | 	{ | ||
|  | 		left = GET_LEFT_INDEX(i); | ||
|  | 		right = GET_RIGHT_INDEX(i); | ||
|  |     l_left=list_get(l,left); | ||
|  |     l_right=list_get(l,right); | ||
|  | 		if (right < size) | ||
|  | 		{ | ||
|  |       if(sub(l_left,l_right)>0) | ||
|  | 			{ | ||
|  |         cpy4byte(temp,l_left,temp_size/4); | ||
|  | 				index = left; | ||
|  | 			} | ||
|  | 			else | ||
|  | 			{ | ||
|  |         cpy4byte(temp,l_right,temp_size/4); | ||
|  | 				index = right; | ||
|  | 			} | ||
|  | 		} | ||
|  | 		else if (left < size) | ||
|  | 		{ | ||
|  |       cpy4byte(temp,l_left,temp_size/4); | ||
|  | 			index = left; | ||
|  | 		} | ||
|  | 		else | ||
|  | 		{ | ||
|  | 			// 序号超出堆范围
 | ||
|  | 			break; | ||
|  | 		} | ||
|  | 		// 子节点比父节点小
 | ||
|  |     l_i=list_get(l,i); | ||
|  |     if(sub(temp,l_i)<=0) | ||
|  | 			break; | ||
|  |     l_index=list_get(l,index); | ||
|  | 		//array[index] = array[i];
 | ||
|  |     cpy4byte(l_index,l_i,temp_size/4); | ||
|  | 		//array[i] = temp;
 | ||
|  |     cpy4byte(l_i,temp,temp_size/4); | ||
|  | 		i = index; | ||
|  | 	} | ||
|  |   free(temp); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // 把序列初始化为大顶堆
 | ||
|  | static void heap_init(list_def *l, sub_fun_def sub,int size) | ||
|  | { | ||
|  | 	// 最后一层没有子节点,所以从倒数第二层开始
 | ||
|  | 	// 当然,从最后一层开始也不影响结果
 | ||
|  | 	for (int i = size/2; i > 0; i--) | ||
|  | 	{ | ||
|  | 		heap_sink(l, sub,i - 1, size); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void _list_sort(list_def *l,sub_fun_def sub) | ||
|  | { | ||
|  |   param_check(l); | ||
|  |   param_check(sub); | ||
|  |   int temp_size=list_block_size4(l); | ||
|  |   void *temp=malloc(temp_size); | ||
|  |   void *l_i,*l_0; | ||
|  |   int size=list_length(l); | ||
|  | 	heap_init(l, sub,size); | ||
|  | 	//heap_print(array, size);
 | ||
|  | 	for (int i = size; i > 0; i--) | ||
|  | 	{ | ||
|  |     l_0=list_get(l,0); | ||
|  |     l_i=list_get(l,i-1); | ||
|  | 		//temp = array[0];
 | ||
|  |     cpy4byte(temp,l_0,temp_size/4); | ||
|  | 		//array[0] = array[i-1];
 | ||
|  |     cpy4byte(l_0,l_i,temp_size/4); | ||
|  | 		//array[i - 1] = temp;
 | ||
|  |     cpy4byte(l_i,temp,temp_size/4); | ||
|  | 		heap_sink(l,sub,0, i - 1); | ||
|  | 	} | ||
|  |   free(temp); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 |