堆排序的C语言实现

#include
#include
#include
#include

typedef struct heap_array
{
  int max_num;
  int total_num;
  int last_index;
  int data[0];
}heap_array;

#define HEAP_LAYERS(n)  ((int)(log(n)/log(2)))
#define HEAP_PARENT_INDEX(n) ((int)((n-1)/2))
#define HEAP_CHILD_LEFT_INDEX(n) ((int)(n*2+1))
#define HEAP_CHILD_RIGHT_INDEX(n) ((int)(n*2+2))

extern heap_array *heap_create(int n);
extern void heap_add(heap_array *heap, int data);
extern void heap_del(heap_array *heap, int data);
extern void heap_sort(heap_array *heap);


heap_array *heap_create(int n)
{
  heap_array *heap;
  int i;

  heap = (heap_array *)malloc(sizeof(heap_array) + n*sizeof(int));
  if(NULL == heap)
    return NULL;

  heap->max_num = n;
  heap->total_num = 0;
  heap->last_index = 0;

  for(i=0; i   {
    heap->data[i] = -1;
  }

  return heap;
}

void heap_add(heap_array *heap, int data)
{
  int cur_index;
  int parent_index;
  int tmp;

  if(heap->total_num >= heap->max_num)
    return;

  heap->total_num++;  

  if(heap->last_index == 0)
  {
    heap->data[heap->last_index] = data;
    heap->last_index++;
    return;
  }
 
  /*先尝试插入到最后节点*/
  cur_index = heap->last_index;
  heap->last_index++;  
  heap->data[cur_index] = data;
  parent_index = HEAP_PARENT_INDEX(cur_index);

  while(heap->data[parent_index] < heap->data[cur_index])
  {
    /*和父节点比较,如果比父节点大,则调换,如果较小,则结束循环*/
    tmp = heap->data[parent_index];
    heap->data[parent_index] = heap->data[cur_index];
    heap->data[cur_index] = tmp;
    cur_index = parent_index;    
    parent_index = HEAP_PARENT_INDEX(cur_index);    
  }

  return;
}

void heap_sort(heap_array *heap)
{
    int cur_index;
    int child_index;
    int tmp;

    cur_index = heap->last_index--;
    
    /*从堆中删除根节点数据,将最后的节点依次和父节点比较,直至符合堆的数据结构特征*/
    while(heap->total_num > 0)
    {
        cur_index = heap->last_index--;
        
        tmp = heap->data[0];
        heap->data[0] = heap->data[cur_index];
        heap->data[cur_index] = tmp;
        heap->total_num--;

        cur_index = 0;

        while(1)
        {
            /*左子树不存在,退出循环*/
            if(HEAP_CHILD_LEFT_INDEX(cur_index) >= heap->total_num)
            {
                break;
            }
            else
            {
                /*右子树不存在,只和左子树比较大小*/
                if(HEAP_CHILD_RIGHT_INDEX(cur_index) >= heap->total_num)
                {
                    child_index = HEAP_CHILD_LEFT_INDEX(cur_index);

                    if(heap->data[cur_index] < heap->data[child_index])
                    {
                        tmp = heap->data[cur_index];
                        heap->data[cur_index] = heap->data[child_index];
                        heap->data[child_index] = tmp;

                        cur_index = child_index;        
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    /*右子树也存在,和左右子节点中的较大一个交换*/
                    if(heap->data[HEAP_CHILD_LEFT_INDEX(cur_index)] > heap->data[HEAP_CHILD_RIGHT_INDEX(cur_index)])
                        child_index = HEAP_CHILD_LEFT_INDEX(cur_index);
                    else
                        child_index = HEAP_CHILD_RIGHT_INDEX(cur_index);

                    if(heap->data[cur_index] < heap->data[child_index])
                    {
                        tmp = heap->data[cur_index];
                        heap->data[cur_index] = heap->data[child_index];
                        heap->data[child_index] = tmp;

                        cur_index = child_index;        
                    }
                    else
                    {
                        break;
                    }           
                }
            }
            
        }     
    }

    return;
}

void heap_show(heap_array *heap)
{
  int i;
  int layer = 0;

  for(i=0; itotal_num; i++)
  {
    if(i == (pow(2, layer)-1))
    {
        printf("\r\n%4d:", layer);
        layer++;
    }
    
    printf("  %4d", heap->data[i]);
  }

  printf("\r\n");

  return;
}

void heap_show_data(heap_array *heap)
{
    int i;

    for(i=0; imax_num; i++)
    {
        printf(" %d", heap->data[i]);
    }

    printf("\r\n");

    return;    
}

int main(int argc, char **argv)
{
    heap_array *heap = NULL;
    int i;
    int cnt = 34;

    srand( (unsigned)time( NULL ) ); //初始化随机数
    

    heap = heap_create(cnt);

    for(i=0; i     {
        heap_add(heap, rand()%50);
    }

    heap_show(heap);

    printf("---------------------------\r\n");

    heap_sort(heap);

    heap_show_data(heap);

    return 0;
}

 

你可能感兴趣的:(算法)