书本销售堆排序演示 ( 这个 堆排函数将适合所有的堆排, 只需要改一下比较函数)
基于 堆排序演示 ( 这个 堆排函数将适合所有的堆排, 只需要改一下比较函数) 怎么排序的关键字
1. 生成书本的结构体信息 :
/*
如果要产生1~100,则是这样:int num = rand() % 100 + 1;
总结来说,可以表示为:int num = rand() % n + a; 其中的a是起始值,n - 1 + a是终止值,n是整数的范围。
一般性:rand() % (b - a + 1) + a; 就表示 a~b 之间的一个随机整数。
*/
//每本书的 id 都不一样, 对书进行排序, 优先返回价格比较高的,如果价格一样, 则先返回id 小的
typedef struct Book
{
int memidx; // 这样 id 的值就比较随意了
int id;
int price;
int pos;
}Book;
#define maxbookcnt 20
static Book mbook[maxbookcnt];
void init_book(int num)
{
srand((int)time(0));
for (int i = 0; i < num; i++)
{
mbook[i].memidx = i;
mbook[i].id = i; //次关键字
//mbook[i].price = i + 100; //主关键字
mbook[i].price = 1 + rand() % (50 - 10 + 1) + 10;
printf("[%d %d] ", mbook[i].id, mbook[i].price);
}
printf("\n\n");
}
堆的结构 和 比较 , 交换, 打印函数 :
/**
* heap_size 此次调整堆的最大元素个数(因为堆排序过程中,后面已经调整好的就不需要调整了)
* pos 表示此次调整堆的节点
* */
typedef struct Heap
{
int heap[maxbookcnt];
int tail;
}Heap;
//比较堆中任意两个数, 价格越高, 排在前面, 如果价格一样,则ID 小的排在前面
static int Compare(int idA, int idB)
{
if (mbook[idA].price == mbook[idB].price)
{
return idB - idA;
}
return mbook[idA].price - mbook[idB].price;
}
//交换堆中任意两个数
static void Swap(Heap *pheap, int posA, int posB)
{
int idA = pheap->heap[posA];
int idB = pheap->heap[posB];
pheap->heap[posA] = idB;
pheap->heap[posB] = idA;
mbook[idA].pos = posB;
mbook[idB].pos = posA;
}
//打印堆中的数据
static void printHeap(Heap *pheap)
{
for (int i = 1; i < pheap->tail; i++)
{
int id = pheap->heap[i];
printf("[%d %d] ", mbook[id].id, mbook[id].price);
}
printf("\n\n");
}
3. 堆的通用调整函数
#define parent (pos >> 1) //获得该父节点的左孩子
#define left (pos << 1) //获得该父节点的左孩子
#define right (pos*2 + 1) //获得该父节点的右孩子
static void adjustHeap(Heap *pheap, int pos, int Compare(int idA, int idB)) // heap_size --> tail
{
if (pos <= 0)
{
return;
}
int old_pos = pos;
while (pos > 1 && Compare(pheap->heap[parent], pheap->heap[pos]) < 0)
{
Swap(pheap, pos, parent);
pos = parent;
}
pos = old_pos;
while ((left < pheap->tail && Compare(pheap->heap[left], pheap->heap[pos]) > 0)
|| (right < pheap->tail && Compare(pheap->heap[right], pheap->heap[pos]) > 0))
{
if ((left < pheap->tail && Compare(pheap->heap[left], pheap->heap[pos]) > 0)
&& (right < pheap->tail && Compare(pheap->heap[right], pheap->heap[pos]) > 0))
{
if (Compare(pheap->heap[left], pheap->heap[right]) > 0) {
Swap(pheap, pos, left);
pos = left;
}
else
{
Swap(pheap, pos, right);
pos = right;
}
}// tail == 12 的时候, pos = 6, 又跟已经交换到 12 的值为 18 的元素交换, 所以不能用 <=
else if (left < pheap->tail && Compare(pheap->heap[left], pheap->heap[pos]) > 0)
{
Swap(pheap, pos, left);
pos = left;
}
else if (right < pheap->tail && Compare(pheap->heap[right], pheap->heap[pos]) > 0)
{
Swap(pheap, pos, right);
pos = right;
}
}
}
4. 插入式堆排测试
static void maxHeapInsert(Heap *pheap, int key)
{
int old_pos = pheap->tail;
pheap->heap[old_pos] = key;
pheap->tail++;
adjustHeap(pheap, old_pos, Compare);
}
extern void test_heap_book()
{
int len = maxbookcnt;
init_book(len);
LOGE("book len = %d ", len);
Heap heap;
heap.heap[0] = 0;
heap.tail = 1; // 这里是从1 开始
LOGE("will build max heap");
//build heap (插入式创建 heap)
for (int i = 1; i < len; i++)
{
maxHeapInsert(&heap, mbook[i].id);
printHeap(&heap);
}
LOGE("will sort all the heap");
for (int heap_size = len; heap_size >= 2; heap_size--) // heap_size is size of not sort of heap , from tail-1 to 1
{
heap.tail--;
Swap(&heap, 1, heap.tail);//将堆顶元素(通过调整堆获得的最大值)和最后一个交换(剩余未排好序部分的最后一个)
adjustHeap(&heap, 1, Compare);//之后每次从堆顶开始调整,最大的值将上升到根节点
printHeap(&heap);
}
heap.tail = len;
printHeap(&heap);
}
数据的插入(首先构建一个大顶堆) :
Test start
[0 16] [1 32] [2 51] [3 44] [4 18] [5 34] [6 42] [7 19] [8 19] [9 49] [10 20] [11 51] [12 45] [13 16] [14 17] [15 26] [16 39] [17 50] [18 42] [19 22]
e:\c++\c_test\c_test\heap_sort_not_use0-book.cpp test_heap_book 142 : book len = 20
e:\c++\c_test\c_test\heap_sort_not_use0-book.cpp test_heap_book 148 : will build max heap
[1 32]
[2 51] [1 32]
[2 51] [1 32] [3 44]
[2 51] [1 32] [3 44] [4 18]
[2 51] [5 34] [3 44] [4 18] [1 32]
[2 51] [5 34] [3 44] [4 18] [1 32] [6 42]
[2 51] [5 34] [3 44] [4 18] [1 32] [6 42] [7 19]
[2 51] [5 34] [3 44] [8 19] [1 32] [6 42] [7 19] [4 18]
[2 51] [9 49] [3 44] [5 34] [1 32] [6 42] [7 19] [4 18] [8 19]
[2 51] [9 49] [3 44] [5 34] [1 32] [6 42] [7 19] [4 18] [8 19] [10 20]
[2 51] [11 51] [3 44] [5 34] [9 49] [6 42] [7 19] [4 18] [8 19] [10 20] [1 32]
[2 51] [11 51] [12 45] [5 34] [9 49] [3 44] [7 19] [4 18] [8 19] [10 20] [1 32] [6 42]
[2 51] [11 51] [12 45] [5 34] [9 49] [3 44] [7 19] [4 18] [8 19] [10 20] [1 32] [6 42] [13 16]
[2 51] [11 51] [12 45] [5 34] [9 49] [3 44] [7 19] [4 18] [8 19] [10 20] [1 32] [6 42] [13 16] [14 17]
[2 51] [11 51] [12 45] [5 34] [9 49] [3 44] [15 26] [4 18] [8 19] [10 20] [1 32] [6 42] [13 16] [14 17] [7 19]
[2 51] [11 51] [12 45] [16 39] [9 49] [3 44] [15 26] [5 34] [8 19] [10 20] [1 32] [6 42] [13 16] [14 17] [7 19] [4 18]
[2 51] [11 51] [12 45] [17 50] [9 49] [3 44] [15 26] [16 39] [8 19] [10 20] [1 32] [6 42] [13 16] [14 17] [7 19] [4 18] [5 34]
[2 51] [11 51] [12 45] [17 50] [9 49] [3 44] [15 26] [16 39] [18 42] [10 20] [1 32] [6 42] [13 16] [14 17] [7 19] [4 18] [5 34] [8 19]
[2 51] [11 51] [12 45] [17 50] [9 49] [3 44] [15 26] [16 39] [18 42] [10 20] [1 32] [6 42] [13 16] [14 17] [7 19] [4 18] [5 34] [8 19] [19 22]
每次不断跟队尾进行交换,然后排序 :
e:\c++\c_test\c_test\heap_sort_not_use0-book.cpp test_heap_book 156 : will sort all the heap [11 51] [17 50] [12 45] [18 42] [9 49] [3 44] [15 26] [16 39] [19 22] [10 20] [1 32] [6 42] [13 16] [14 17] [7 19] [4 18] [5 34] [8 19] [17 50] [9 49] [12 45] [18 42] [1 32] [3 44] [15 26] [16 39] [19 22] [10 20] [8 19] [6 42] [13 16] [14 17] [7 19] [4 18] [5 34] [9 49] [18 42] [12 45] [16 39] [1 32] [3 44] [15 26] [5 34] [19 22] [10 20] [8 19] [6 42] [13 16] [14 17] [7 19] [4 18] [12 45] [18 42] [3 44] [16 39] [1 32] [6 42] [15 26] [5 34] [19 22] [10 20] [8 19] [4 18] [13 16] [14 17] [7 19] [3 44] [18 42] [6 42] [16 39] [1 32] [7 19] [15 26] [5 34] [19 22] [10 20] [8 19] [4 18] [13 16] [14 17] [6 42] [18 42] [15 26] [16 39] [1 32] [7 19] [14 17] [5 34] [19 22] [10 20] [8 19] [4 18] [13 16] [18 42] [16 39] [15 26] [5 34] [1 32] [7 19] [14 17] [13 16] [19 22] [10 20] [8 19] [4 18] [16 39] [5 34] [15 26] [19 22] [1 32] [7 19] [14 17] [13 16] [4 18] [10 20] [8 19] [5 34] [1 32] [15 26] [19 22] [10 20] [7 19] [14 17] [13 16] [4 18] [8 19] [1 32] [19 22] [15 26] [8 19] [10 20] [7 19] [14 17] [13 16] [4 18] [15 26] [19 22] [7 19] [8 19] [10 20] [4 18] [14 17] [13 16] [19 22] [10 20] [7 19] [8 19] [13 16] [4 18] [14 17] [10 20] [8 19] [7 19] [14 17] [13 16] [4 18] [7 19] [8 19] [4 18] [14 17] [13 16] [8 19] [14 17] [4 18] [13 16] [4 18] [14 17] [13 16] [14 17] [13 16] [13 16]
最后排序的结果 (价格越大, 优先级越高, 如果价格一样, 则比较 idx , idx 越小, 优先级越高):
[13 16] [14 17] [4 18] [8 19] [7 19] [10 20] [19 22] [15 26] [1 32] [5 34] [16 39] [18 42] [6 42] [3 44] [12 45] [9 49] [17 50] [11 51] [2 51]
浙公网安备 33010602011771号