堆排序(代码1)

#include <stdio.h>
#include <stdlib.h>

void build_heap(int data[], int);
void adjust_heap(int data[], int);
void heap_sort(int data[], int);
int sub_max_heap(int data[], int, int);

int main(int argc, char *argv[])
{
	int i;
	int data[12] = {6, 10, 3, 5, 12, 8, 4, 23, 1, 2, 9, 7 };

	heap_sort(data, 12);

	for (i = 0; i < 12; ++i)
	{
		printf("%d ", data[i]);
	}

	printf("\n");
	return 0;
}

void heap_sort(int data[], int num)
{
	int i = 1;
	build_heap(data, num);

	for (i = 1; i < num; ++i)
	{
		int temp;
		temp = data[0];
		data[0] = data[num - i];
		data[num - i] = temp;

		adjust_heap(data, num - i);
	}

}

void build_heap(int data[], int num)
{
	int i, k, p;

	for (i = num / 2 - 1; i >= 0; --i)
	{
		k = sub_max_heap(data, num, i);

		while (2 * k + 1 < num)
		{
			p = k;
			k = sub_max_heap(data, num, p);
		}
	}

}

void adjust_heap(int data[], int num)
{
	int temp;
	int k, p;

	k = 0;
	while(2 * k + 1 < num)
	{
		p = k;
		k = sub_max_heap(data, num, p);
	}

}

int sub_max_heap(int data[], int num, int i)
{
	int k;

	if (2 * i + 2 <= num - 1 && data[2 * i + 1] > data[2 * i + 2])
		k = 2 * i + 1;
	else if (2 * i + 2 <= num - 1)
		k = 2 * i + 2;
	else
		k = 2 * i + 1;

	if (data[k] > data[i])
	{
		int temp;
		temp = data[k];
		data[k] = data[i];
		data[i] = temp;
	}

	return k;

}
/*
int sub_max_heap(int data[], int num, int i)
{
	int largest;
	int l, r;

	l = 2 * i + 1;
	r = 2 * i + 2;

	if (l <= num - 1 && data[l] > data[i])
		largest = l;
	else
		largest = i;

	if (r <= num - 1 && data[r] > data[largest])
		largest = r;
	if (largest != i)
	{
		int temp;
		temp = data[i];
		data[i] = data[largest];
		data[largest] = temp;
	}

	return largest;
}

*/
时间: 2024-10-07 08:24:31

堆排序(代码1)的相关文章

堆排序+代码实现

堆排序 堆,heap,是二叉树的一种.小根堆有这样的性质--任意一个结点的值比它的左右孩子都要小. 排序思想 将待排元素看作是完全二叉树,物理上用一维数组存储. 实现堆排序需要解决两个问题: 1.如何将杂乱的完全二叉树初始化为一个堆? 答:从最后一个非叶结点起,将该节点当做根,自上而下进行调整,使之成为一个堆.然后依次对倒数第二个.倒数第三个.直至正数第一个结点进行此操作. 2.输出堆顶元素后,如何将余下的元素调整为一个堆? 答:将最后一个结点放在原根结点位置上,以它为根进行上述的调整. 复杂度

java 堆排序代码(最小堆)

package com.juxuny.heap; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; /** * Created by Juxuny on 2015/2/10. */ public class Heap { private int MAX = 2 << 20; private Node[] arr; private int size = 0; public Heap

【算法导论】第六章、堆排序

基本过程: 1.保持最大堆的性质:假设两个子堆都满足,只需要根节点依次换下去,复杂度O(lg n) 2.初始化堆:后半段都是叶子,在前半段从后往前,依次执行上述最大堆性质的操作,名义复杂度是O(n lg n),但是有更精确的计算, 在高度为h的节点为O(h), 因此为 n\sigma (h / 2^h),其复杂度为O(n).(思想是高层复杂度才高,指数衰减,而复杂度增长是lg级别,因此被dominate掉了) 堆排序算法:先建最大堆,每次把顶上的位置与合适的位置互换,然后执行过程1, 共执行n次

十大基础实用算法之快速排序和堆排序

快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来. 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists). 算法步骤: 1 从数列中挑出一个元素,称为 "基准"(pi

排序算法——堆排序

堆排序 ①了解二叉堆的定义 ②一般用数组表示堆 注意逻辑存储结构和实际存储结构 ③i节点的 父节点(i-1)/2 子节点 左2*i+1 右2*i+2 ④注意每种操作的思想 ⑤一般数组要堆化操作后再进行堆排序 代码实现 /*本栗子是最小堆*//*从第i个节开始调整*/ void MinHeapDown(int a[],int i,int n) { int j=0,temp=0; temp = a[i]; j=2*i+1;/*i节点的左孩子*/ while(j < n) { if(j+1<n &a

选择排序:堆排序

堆排序(Heap Sort):使用堆这种数据结构来实现排序. 先看下堆的定义: 最小堆(Min-Heap)是关键码序列{k0,k1,-,kn-1},它具有如下特性: ki<=k2i+1, ki<=k2i+2(i=0,1,-) 简单讲:孩子的关键码值大于双亲的. 同理可得,最大堆(Max-Heap)的定义: ki>=k2i+1, ki>=k2i+2(i=0,1,-) 同样的:对于最大堆,双亲的关键码值大于两个孩子的(如果有孩子). 堆的特点: 堆是一种树形结构,而且是一种特殊的完全二

数据结构之堆排序

堆排序,是数据结构中重要的排序方法,可以很快帮你找到最大值.在实际应用中,如 最大优先级队列是大顶推的应用,可以很快找到优先级最高的队列. 1.堆概念 堆的定义如下,n个元素的序列{k1,k2,...kn},当且仅当满足如下关系: ki>=k2i               或者         ki<=k2i ki>=k2i+1                          ki<=k2i+1 分别对应大顶堆和小顶堆. 堆可以看作一个完全二叉树,所有非终端点都大于或都小于左右

夯实基础——堆排序

堆结构:任意的一个父节点大于其子节点. 逻辑结构:二叉树 物理结构:数组 如果从角标0开始 父节点左孩子节点:2*i+1 父节点右孩子节点:2*i+2 最后一个非叶节点:(n-1)/2 如果从角标1开始 父节点左孩子节点:2*i 父节点右孩子节点:2*i+1 最后一个非叶节点:n/2 堆排序分析: 最优时间复杂度:O(nlog2n) 最坏时间复杂度:O(nlog2n) 平均时间复杂度:O(nlog2n) 空间复杂度:O(1) 稳定性:不稳定 堆排序主要分三个函数: 1 调整成堆结构 void H

建堆,以及对堆排序

建堆,以及堆排序 代码1: #include<stdio.h> int h[101];//用来存放堆的数组 int n;//用来存储堆中元素的个数,就是堆的大小 //交换函数,用来交换堆中的俩个元素的值 void swap(int x,int y) { int t; t=h[x]; h[x]=h[y]; h[y]=t; } //向下调整函数 void siftdown(int i) {//传入一个须要向下调整的的节点编号i,这里传入1.即从堆的顶点開始向下调整 int t,flag=0;//f

堆排序总结

堆排序 概念: 第一个非叶子节点: 小于size/2的部分; 非叶子节点的区间: [0, size/2); (注意是左闭右开) 最大堆:满足父节点head, arr[head]<=arr[2*head+1] && arr[head]<=arr[2*head+2] 非叶子节点的子树才需要调整(没有子节点的树何谈调整) ps: 全文使用的下标均是从0开始 堆排序过程 初始化堆: 从size/2到0调整堆, 使得堆满足条件; 调整堆: 如果head在非叶子节点的区间, 即head 属