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);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |