#include
#include
#include
#include
#define MAX 9999
void init_int_array(int data[], int n)
{
for (int i = 0; i < n; ++i)
data[i] = rand()%10;
}
void print_int_array(int data[], int size)
{
for (int i = 0; i < size; i++)
{
printf("%d ", data[i]);
}
printf("\n");
}
int check(int data[], int data_backup[], int size)
{
int sum = 0, sum2 = 0;
int i;
for (i = 0; i < size-1; ++i)
{
sum += data[i];
sum2 += data_backup[i];
if (data[i+1] < data[i])
return 0;
}
sum += data[i];
sum2 += data_backup[i];
if (sum != sum2)
return 0;
return 1;
}
void adjust(int leaves[], int index_tree[], int k, int i)
{
int left, right; // 左右子结点
if(2 * i <= k)
left = index_tree[2 * i];
else
left = 2 * i - k - 1;
if(2*i+1 <= k)
right = index_tree[2*i+1];
else
right = 2 * i - k ;
index_tree[i] = leaves[left] > leaves[right] ? right : left; // 胜负判定
}
void winner_tree_sort(int data[], int n)
{
int* leaves = (int *)malloc((n)*sizeof(int)); // leaves 从 [0] 到 [n-1] 一个 n 个
int* index_tree = (int *)malloc((n)*sizeof(int)); // index_tree 从 [1] 到 [n-1] 一共 n-1 个
for(int i = 0;i < n; ++i) // 初始化叶子节点
leaves[i] = data[i];
for(int father = n-1; father > 0; --father)
adjust(leaves, index_tree, n-1, father);
for(int i = 1; i < n; ++i) // 选择n-1次,每次用最大值替换掉冠军节点,并调整胜者树
{
data[i-1] = leaves[index_tree[1]];
leaves[index_tree[1]] = MAX; // 比所有数据都大的数
// 自下而上,对胜者树进行调整
for(int father = (index_tree[1]+n)/2; father > 0; father /= 2)
adjust(leaves, index_tree, n-1, father);
}
data[n-1] = leaves[index_tree[1]]; // 最后一个数据
free(index_tree);
free(leaves);
}
int main(void)
{
// 目测一次排序结果
int arr[12];
srand(time(NULL));
init_int_array(arr, sizeof(arr)/sizeof(arr[0]));
print_int_array(arr, sizeof(arr)/sizeof(arr[0]));
winner_tree_sort(arr, sizeof(arr)/sizeof(arr[0]) );
print_int_array(arr, sizeof(arr)/sizeof(arr[0]));
// 多次验证排序结果是否正确
for(int i = 0; i < 300; ++i)
{
int data[15], data_backup[15];
init_int_array(data, sizeof(data)/sizeof(data[0]));
memcpy(data_backup, data, sizeof(data_backup));
winner_tree_sort(data, sizeof(data)/sizeof(data[0]) );
if (!check(data, data_backup, sizeof(data)/sizeof(data[0])))
{
printf("error:\nOriginal data:\n");
print_int_array(data_backup, sizeof(data)/sizeof(data[0]));
printf("Sorted data:\n");
print_int_array(data, sizeof(data)/sizeof(data[0]));
return EXIT_FAILURE;
}
}
printf("check\n");
return EXIT_SUCCESS;
}
一键复制
编辑
Web IDE
原始数据
按行查看
历史