堆以及堆排序

(二叉  )堆:一个类似完全二叉树的数据结构

左孩子:2i

右孩子:2i+1

父节点:i/2

(以上结论如果记不住,用到时可以自己画个图推一下)



物理存储:用数组存储A(1,2,3....,n)


1.调整每个节点的算法:

如果要建立大顶堆,则需遵循每个父亲结点的值都要大于左右孩子的值

递归版本:

    /**
     * 
     * @param numbers
     *            待调整数组
     * @param i
     *            待调整节点
     * @param len堆的大小
     */
    public static void maxHeapify(int[] numbers, int i, int len) {
        int l = 2 * i + 1;
        int r = 2 * i + 2;
        int largest = i;
        if (l < len && numbers[i] < numbers[l]) {
            largest = l;
        }
        if (r < len && numbers[largest] < numbers[r]) {
            largest = r;
        }
        if (largest != i) {
            int temp = numbers[i];
            numbers[i] = numbers[largest];
            numbers[largest] = temp;
            maxHeapify(numbers, largest, len);
        }

    }

非递归版本:
public static void maxHeapify1(int[] numbers, int i, int len) {
		int l = 2 * i + 1;//下标从0开始时左孩子的下标
		int r = 2 * i + 2;//下标从0开始时右孩子的下标
		int largest = i;
		if (l < len && numbers[i] < numbers[l]) {
			largest = l;
		}
		if (r < len && numbers[largest] < numbers[r]) {
			largest = r;
		}
		//修改递归调用
		while (largest != i) {
			int temp = numbers[i];
			numbers[i] = numbers[largest];
			numbers[largest] = temp;
			i=largest;
			l=2*i+1;
			r=2*i+2;
			if (l < len && numbers[i] < numbers[l]) {
				largest = l;
			}
			if (r < len && numbers[largest] < numbers[r]) {
				largest = r;
			}
		}

	}


2.建立堆的算法:

自底向上建立,调整每个非叶子节点,叶子节点无需再调整

利用结论,完全二叉树中(n/2+1,...,n)为叶子节点

public static void buildMaxHeap(int[] numbers) {
		int heapsize = numbers.length;
		for (int i = heapsize / 2 - 1; i >= 0; --i) {
			maxHeapify(numbers, i,heapsize);
		}
	}



3.堆排序的算法:

建立一个大顶堆,第一个元素与最后一个元素交换

缩小堆的规模,此时只有第一个节点可能不符合堆的性质,对第一个节点调用调整节点的算法

重复1,2步骤直到堆的规模缩小为1

// 堆排序算法,按从小到大排的
	// 初始建立一个大顶堆,因为数组中的最大元素总在根节点A[0]中,通过把它与A[n]进行互换,可以把它放在正确的位置
	// 这时从数组中去除第n个节点,这时只有根节点可能是违背最大堆的性质,这时调用一次堆调整方法就可以了,此时堆的规模减少了1
	public static void heapSort(int[] numbers) {
		int len = numbers.length;
		buildMaxHeap(numbers);
		for (int i = len; i >= 1; --i) {

			int temp = numbers[i - 1];
			numbers[i - 1] = numbers[0];
			numbers[0] = temp;
			maxHeapify(numbers, 0, i - 1);// 调用堆调整算法
		}
	}


4.优先队列:(最大优先队列、最小优先队列)

优先队列是一种用来维护由一组元素构成的集合S的数据结构,其中每个元素都有一个相关的值,称为关键字。一个最大优先队列支持一下操作:

insert(S,x):插入一个元素

maxNum(S):返回集合中最大的元素

extract-max(s):返回并从集合中删除最大的元素

increase-key(s,x,k):将元素x的关键字增加到k

应用:计算机系统的作业调度(上os时有个优先级调度算法)


完整代码:

https://github.com/tianqingwa/HeapSort



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值