堆排序

本文介绍了堆排序的基本概念及其实现方式,并提供了详细的代码示例。通过具体代码讲解了如何构建最小堆、插入元素、删除最小元素等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考点击打开链接,学习了下堆排序,资料很多就不多描述了,直接贴代码。


/*
二叉堆:完全二叉树,即除最后一层外,每层节点数均到达最大值;最后一层只缺少右侧节点(节点都在左边)。
性质:对于var tree:array[1..n]of longint;{n:integer;n>=1}
(1)若i>1,tree的双亲为tree[i div 2];
(2)若2*i<=n,那么tree的左孩子为tree[2*i];若2*i+1<=n,那么tree的右孩子为tree[2*i+1];
(3)根节点为最大节点或最小节点,子树也一样。(最大堆或者最小堆,本例为最小堆)
*/

/*heap[0] : total nodes in the heap
  for a node i, its children are i*2 and i*2+1 (if exists)
  its parent is i/2 */

void insert(int node, int *heap) {
	heap[0] = heap[0] + 1;
	heap[heap[0]] = node;
	//恢复heap性质
	percolate_up(heap);
}

/*上滤,与每层父节点比较*/
void percolate_up(int *heap) {
	int lightIdx = heap[0];
	int parentIdx = lightIdx / 2;

	while ((parentIdx != 0) && (heap[lightIdx] < heap[parentIdx])) {
		swap(&heap[lightIdx], &heap[parentIdx]);
		lightIdx = parentIdx;
		parentIdx = lightIdx / 2;
	}
}

int delete_min(int *heap) {
	int min;
	if (heap[0] <= 1) {
		printf("ERROR: delete min from a empty heap\n");
	    exit(1);
	}

	min = heap[1];
	swap(&heap[1], &heap[heap[0]]);
	heap[0] = heap[0] - 1;

	percolate_down(heap);
	return min;
}

/*下滤,与左右子节点比较*/
void percolate_down(int *heap) {
    int lChildIdx;
	int rChildIdx;
	int i = 1;
	int minIdx;
	int exit_flag;

	do {
	    exit_flag = 0;
		lChildIdx = 2*i;
		rChildIdx = 2*i+1;

		/*在左右孩子节点中找出最小值的索引*/
		if (lChildIdx > heap[0]) {
		    printf("no child nodes\n");
			return;
		} else if (rChildIdx > heap[0]) {
		    /*只有左孩子节点*/
			minIdx = lChildIdx;
		} else {
		    minIdx = heap[lChildIdx] > heap[rChildIdx] ? lChildIdx : rChildIdx;
		}

		/*比较父节点与左右孩子节点中的最小值*/
		if (heap[i] > heap[minIdx]) {
		    swap(&heap[i], &heap[minIdx]);
			i = minIdx;
			exit_flag = 1;
		}

	}while(1 == exit_flag);
}

void swap(int *a, int *b) {
    int tmp = *a;
	*a = *b;
	*b = tmp;
}


void print_array(int a[], int count) {
	int carry = 0;
	int remainder = 0;
	for(int i = 0; i < count; i++) {
	    if (i % 10 == 0)
			cout << endl;
		remainder = a[i];
		do {
			carry++;
			remainder = remainder / 10;
		}while(remainder != 0);
		switch(carry) {
		case 1:
			cout<<a[i]<<"    ";
			break;
		case 2:
			cout<<a[i]<<"   ";
			break;
		case 3:
			cout<<a[i]<<"  ";
			break;
		case 4:
			cout<<a[i]<<" ";
			break;
		}
		carry = 0;
	}
	cout << endl;
}

int main() {
    int *heap = (int *)malloc(sizeof(int) * 50);
	heap[0] = 0;
	for (int i = 1; i < 10; i++) {
	    insert(rand()%100,heap);
	}
	printf("make heap node...\n");
	print_array(heap,heap[0]);

	printf("after heap sort...\n");
	for (int i = 1; i < 9; i++) {
	    delete_min(heap);
	}
	print_array(heap,10);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值