书本销售堆排序演示 ( 这个 堆排函数将适合所有的堆排, 只需要改一下比较函数)

基于 堆排序演示 ( 这个 堆排函数将适合所有的堆排, 只需要改一下比较函数) 怎么排序的关键字

 

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]

  

 

posted @ 2021-08-29 22:25  皮特99  阅读(52)  评论(0)    收藏  举报