#include <stdio.h>
#include <stdlib.h>
#include "type.h"
#ifdef __SORT_DEBUG__
#define SORT_DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define SORT_DEBUG(fmt, ...)
#endif
/* tree pos(start from 1) map to array pos(start from 0) */
#define HEAP_SORT_RAM_POS(a) ((a) - 1)
#define HEAP_SORT_L_SON_POS(a) (2 * (a))
#define HEAP_SORT_R_SON_POS(a) (2 * (a) + 1)
#define HEAP_SORT_PARENT_POS(a) ((a) / 2)
#define HEAP_SORT_IS_VALID_POS(a, num) ((a) > (num) ? FALSE : TRUE)
#define SWAP_VALUE(list, pos1, pos2) \
{ \
list[(pos1)] ^= list[(pos2)]; \
list[(pos2)] ^= list[(pos1)]; \
list[(pos1)] ^= list[(pos2)]; \
}
void show_array(int8 *msg, uint8 *list, uint32 number)
{
uint32 i;
printf("\r\n%s", msg);
printf(", array = [ ");
for (i = 0; i < number; i++)
{
printf("%d ", list[i]);
}
printf("]\r\n");
}
uint32 heap_sort_adjust_pos_with_son(uint8 *list, uint32 num, uint32 cur_pos)
{
uint32 l_son_pos, r_son_pos; /* position is heap tree */
uint32 max_pos;
/***************************/
/* find out max son */
/***************************/
/* firstly, check if exist left son */
l_son_pos = HEAP_SORT_L_SON_POS(cur_pos);
if (HEAP_SORT_IS_VALID_POS(l_son_pos, num))
{
max_pos = l_son_pos;
}
else
{
/* no left, means no valid son */
return SORT_OK;
}
/* secondly, check if exist right son */
r_son_pos = HEAP_SORT_R_SON_POS(cur_pos);
if (HEAP_SORT_IS_VALID_POS(r_son_pos, num))
{
if (list[HEAP_SORT_RAM_POS(r_son_pos)] > list[HEAP_SORT_RAM_POS(l_son_pos)])
{
max_pos = r_son_pos;
}
}
/***********************************/
/* conpare max son with cur_pos */
/***********************************/
if (list[HEAP_SORT_RAM_POS(max_pos)] > list[HEAP_SORT_RAM_POS(cur_pos)])
{
SWAP_VALUE(list, HEAP_SORT_RAM_POS(max_pos), HEAP_SORT_RAM_POS(cur_pos));
heap_sort_adjust_pos_with_son(list, num, max_pos);
}
return SORT_OK;
}
uint32 heap_sort_create_max_hep(uint8 *list, uint32 num)
{
uint32 pos; /* position is heap tree */
int8 buf[20] = {0};
for (pos = num / 2; pos >= 1; pos--)
{
heap_sort_adjust_pos_with_son(list, num, pos);
sprintf(buf, "[pos=%d]", pos);
show_array(buf, list, num);
}
return SORT_OK;
}
uint32 heap_sort_flow_up(uint8 *list, uint32 cur_pos)
{
uint32 par_pos;
if (cur_pos == 1)
{
/* root, return */
return SORT_OK;
}
par_pos = cur_pos / 2;
if (list[HEAP_SORT_RAM_POS(cur_pos)] > list[HEAP_SORT_RAM_POS(par_pos)])
{
/* flow up */
SWAP_VALUE(list, HEAP_SORT_RAM_POS(cur_pos), HEAP_SORT_RAM_POS(par_pos));
heap_sort_flow_up(list, par_pos);
}
return SORT_OK;
}
uint32 heap_sort_add_item(uint8 *list, uint32 *num, uint32 value)
{
*num += 1;
list[HEAP_SORT_RAM_POS(*num)] = value;
heap_sort_flow_up(list, *num);
return SORT_OK;
}
uint32 heap_sort_execute(uint8 *list, uint32 num)
{
uint32 i = num;
while(i > 1)
{
/* swap */
SWAP_VALUE(list, HEAP_SORT_RAM_POS(1), HEAP_SORT_RAM_POS(i));
show_array("After swap", list, num);
i--;
heap_sort_adjust_pos_with_son(list, i, 1);
}
return SORT_OK;
}
uint32 quick_sort(uint8 *list, int32 low, int32 high)
{
uint32 key = list[low];
int32 i, j; /* supervitor */
if(low >= high)
{
return SORT_OK;
}
i = low;
j = high;
SORT_DEBUG("key = %d\r\n", key);
while(i < j)
{
/* from right to left, find less or euqal to key*/
while (i < j && list[j] > key)
{
j--;
}
SORT_DEBUG("right(j), find pos(%d) = %d less or equal to key\r\n", j, list[j]);
/* from left to right, find greater than key */
while (i < j && list[i] <= key)
{
i++;
}
SORT_DEBUG("left(i), find pos(%d) = %d greater than key\r\n", i, list[i]);
/* if not meet, swap i and j */
if (i != j)
{
list[i] ^= list[j];
list[j] ^= list[i];
list[i] ^= list[j];
}
}
if (i != j)
{
SORT_DEBUG("error occur: i = %d is not equal to j = %d\r\n", i, j);
}
/* swap key */
if (j != low)
{
list[low] ^= list[j];
list[j] ^= list[low];
list[low] ^= list[j];
}
show_array("after quick sort", list, 10);
SORT_DEBUG("call quick sort, (%d, %d)\r\n", low, j - 1);
quick_sort(list, low, j - 1);
SORT_DEBUG("call quick sort, (%d, %d)\r\n", j + 1, high);
quick_sort(list, j + 1, high);
}
uint32 select_sort(uint8 *list, uint32 number)
{
uint32 i, j;
for (i = 0; i < number; i++)
{
for(j = i + 1; j < number; j++)
{
if (list[i] > list[j])
{
list[i] ^= list[j];
list[j] ^= list[i];
list[i] ^= list[j];
}
}
}
return SORT_OK;
}
uint32 bubble_sort_low_2_max(uint8 *list, uint32 number)
{
uint32 i, j;
for (i = 0; i < number - 1; i++)
{
for (j = 0; j < number - 1 - i; j++)
{
if (list[j] > list[j + 1])
{
list[j] ^= list[j + 1];
list[j + 1] ^= list[j];
list[j] ^= list[j + 1];
}
}
}
return SORT_OK;
}
int8 main(int argc, char *argv[])
{
uint32 ret = 0;
uint8 array0[10] = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
uint8 array1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
uint8 array2[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
// bubble_sort_low_2_max(array, sizeof(array));
// select_sort(array, sizeof(array));
switch(argc)
{
case 0:
show_array("Before sort", array0, sizeof(array0));
quick_sort(array0, 0, sizeof(array0) - 1);
show_array("After sort", array0, sizeof(array0));
break;
case 1:
show_array("Before sort", array1, sizeof(array1));
quick_sort(array1, 0, sizeof(array1) - 1);
show_array("After sort", array1, sizeof(array1));
break;
case 2:
show_array("Before sort", array2, sizeof(array2));
quick_sort(array2, 0, sizeof(array2) - 1);
show_array("After sort", array2, sizeof(array2));
break;
case 3:
show_array("Before sort", array0, array0_num);
heap_sort_create_max_hep(array0, array0_num);
heap_sort_add_item(array0, &array0_num, 4);
heap_sort_add_item(array0, &array0_num, 18);
show_array("add 4 and 18 to heap", array0, array0_num);
heap_sort_execute(array0, array0_num);
show_array("After sort", array0, array0_num);
break;
default:
printf("argc is error, %d", argc);
break;
}
return SORT_OK;
}
type.h
#ifndef __TYPE_H__
#define __TYPE_H__
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned char uint8;
typedef signed char int8;
#define SORT_OK (0)
#define SORT_ERR (1)
#endif
makefile
CC=gcc
PROJECT_DIR=/repo/ezheson/sort_alg
TARGET=bubble_sort
OBJECTS=$(PROJECT_DIR)/objects/$(TARGET).o
CFLAG=-g
DEFINE=-D__SORT_DEBUG__
INCLUDE=-I$(PROJECT_DIR)/inc
$(PROJECT_DIR)/$(TARGET).out: $(OBJECTS)
@$(CC) $^ -o $@
@echo "build finished..."
$(OBJECTS):$(PROJECT_DIR)/objects/%.o:$(PROJECT_DIR)/%.c
@$(CC) $(CFLAG) $(DEFINE) $(INCLUDE) -c $< -o $@
.PHONY:clean
clean:
rm -rf $(PROJECT_DIR)/$(TARGET).out $(PROJECT_DIR)/objects/*
快排图示
堆排序–创建最大堆