堆栈
来源:互联网 发布:python 多进程写文件 编辑:程序博客网 时间:2024/05/18 21:50
堆栈只能在一端(栈顶(top))对数据项进行插入和删除,堆:先进后出,栈:后进先出
操作系统:
栈:是由编译器自动分配释放,存放函数的参数值,局部变量的值等,调用完毕立即释放,使用的是一级缓存
堆:存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定
数据结构:
堆:可以被看成是一棵树,如:堆排序
栈:一种后进先出的数据结构
java自动管理栈和堆
栈的优势是存取速度比堆快,仅次于直接位于CPU中的寄存器,缺点:存在栈中的数据大小与生存期必须确定,缺乏灵活性。栈数据可以共享
堆的优势是可以动态地分配内存大小,JAVA的垃圾收集器会自动收走不再使用的数据,缺点:由于要在运行时动态分配内存,存取速度较慢。
包装类数据全部存在堆中
例:
int a = 3;
int b = 3;
编译器先处理int a= 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b= 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。
数据结构 堆:
什么是堆
堆是一种特殊的二叉完全树。堆的一个主要特点是它以一定的偏序(a partial order)来保存所有节点[译者注:此处的偏序是指不完全的排序,堆只需要满足父节点大于两个子节点,而子节点之间没有要求]。作为一颗完全树,一层中的节点是从左到右填满的。如果一个节点没有左儿子,那么它一定没有右儿子。并且在第h层中如果存在节点,那么第h-1层必须是填满的。
以下是堆的正式定义(摘自Computer Algorithms by S. Baase and A. Van Gelder):
一个二叉树V是一个堆,当且仅当它满足以下条件:
- V从根节点至h-1层是完全树
- 所有的叶子节点只存在于h与h-1层上
- 所有到达h层叶子节点的路劲都在到达h-1层叶子节点路径的左侧
堆有两种:最大堆和最小堆。最小堆中每个节点的优先级小于或者等于它的子节点;最大堆则相反,每个节点的优先级都大于或者等于它的子节点。
图示最大堆(左)和最小堆(右):
经典排序算法 - 堆排序Heap sort
堆排序有点小复杂,分成三块
第一块,什么是堆,什么是最大堆
第二块,怎么将堆调整为最大堆,这部分是重点
第三块,堆排序介绍
第一块,什么是堆,什么是最大堆
什么是堆
这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构。
堆可以视为一棵完全的二叉树,完全二叉树的一个“优秀”的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素.
数组与堆之间的关系
二叉堆一般分为两种:最大堆和最小堆。
什么是最大堆
堆中每个父节点的元素值都大于等于其孩子结点(如果存在),这样的堆就是一个最大堆
因此,最大堆中的最大元素值出现在根结点(堆顶)
节点与数组索引关系
对于给定的某个结点的下标i,可以很容易的计算出这个结点的父结点、孩子结点的下标,而且计算公式很漂亮很简约
第二块,怎么将堆调整为最大堆,这部分是重点
整个过程如下图所示
在4,14,7这个小堆里边,父节点4小于左孩子14,所以两者交换
在4,2,8这个小堆里边,父节点4小于右孩子8,所以两者交换
上图展示了一趟调整的过程,这个过程递归实现,直到调整为最大堆为止
第三块,堆排序介绍
堆排序就是把堆顶的最大数取出,
将剩余的堆继续调整为最大堆,具体过程在第二块有介绍,以递归实现
剩余部分调整为最大堆后,再次将堆顶的最大数取出,再将剩余部分调整为最大堆,这个过程持续到剩余数只有一个时结束
下边三张图详细描述了整个过程
参考文章
http://blog.kingsamchen.com/archives/547#viewSource
堆排序:取出根部最大(最小)的元素放入一个数组后,将根的最后一个元素填充到根部,然后重建最大(最小)堆,然后就递归package com.algorithm;public class HeapSort {public static void main(String[] args) { // 数组0下标元素作为暂存单元 /*int[] array = { 0, 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51 };*/ int[] array = { 0, 49, 38, 65, 97, 76, 13, 27, 49 }; heapSort(array); for (int i = 1; i < array.length; i++) { System.out.print(array[i] + " "); } } // 排序函数===================================================== public static void heapSort(int[] array) { // 对数组进行筛选,建成一个大顶堆 double len = array.length - 1; for (int i = (int) Math.floor(len / 2); i > 0; i--) { heapAdjust(array, i, array.length - 1); } for (int i = array.length - 1; i > 1; i--) { // 将堆顶元素与最后一个元素调换位置,即输出最大值 swap(array, 1, i); // 将最后一位剔出,数组最大下标变为i-1。自队顶至叶子进行调整,形成一个新堆,此过程称为筛选 heapAdjust(array, 1, i - 1); } } // 建堆函数,认为【s,m】中只有 s // 对应的关键字未满足大顶堆定义,通过调整使【s,m】成为大顶堆===================================================== public static void heapAdjust(int[] array, int s, int m) { // 用0下标元素作为暂存单元 array[0] = array[s]; // 沿孩子较大的结点向下筛选 for (int j = 2 * s; j <= m; j*=2) { // 保证j为较大孩子结点的下标,j < m 保证 j+1 <= m ,不越界 (此数组真正从1开始固左子树为leftChild=2*s) if (j < m && array[j] < array[j + 1]) { j++; } if (!(array[0] < array[j])) { break; } // 若S位较小,应将较大孩子上移 array[s] = array[j]; // 较大孩子的值变成S位的较小值,可能引起顶堆的不平衡,故对其所在的堆进行筛选 s = j; } // 若S位较大,则值不变;否则,S位向下移动至2*s、4*s、。。。 array[s] = array[0]; } // 交换函数===================================================== public static void swap(int[] array, int i, int j) { int temp; temp = array[i]; array[i] = array[j]; array[j] = temp; } }
package com.algorithm;import com.test.java.intStringToint;public class HeapSortTest2 {public static void main(String args[]) {int[] array = { 49, 38, 65, 97, 76, 13, 27, 49 };int[] array1 = { 1, 2, 7, 4, 34, 25, 67 };sortHeap(array);for (int i = 0; i < array.length; i++) {System.out.print(array[i] + " ");}sortHeap(array1);for (int i = 0; i < array1.length; i++) {System.out.print(array1[i] + " ");}}public static void sortHeap(int[] arr) {int len = arr.length;for (int i = len / 2; i >= 0; i--) {maxHeap(arr, i, len);}for (int i = len - 1; i > 0; i--) {swap(arr, i, 0);maxHeap(arr, 0, i);}}public static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}public static void maxHeap(int[] arr, int index, int heapSize) {int leftIndex = index*2+1;//此数组下标从0开始 固leftIndex=index*+1int rightIndex = index*2+2;int largest = index;if (leftIndex < heapSize && arr[index] < arr[leftIndex]) {largest = leftIndex;}if (rightIndex < heapSize && arr[largest] < arr[rightIndex]) {largest = rightIndex;}if (largest != index) {swap(arr, largest, index);maxHeap(arr, largest, heapSize);}}}
#!bin/usr/pythondef left(index): return index*2+1def right(index): return index*2+2def maxHeap(arr,index,heapSize): leftInd=left(index) rightInd=right(index) largest=index if leftInd<heapSize and arr[index]<arr[leftInd]: largest=leftInd if rightInd<heapSize and arr[largest]<arr[rightInd]: largest=rightInd if largest != index: arr[largest],arr[index]=arr[index],arr[largest] maxHeap(arr,largest,heapSize)def heapSort(arr): for i in range(len(arr)/2,-1,-1): maxHeap(arr,i,len(arr)) for i in range(len(arr)-1,0,-1): arr[0],arr[i]=arr[i],arr[0] maxHeap(arr,0,i)arr=[1,2,7,4,34,25,67] heapSort(arr) print arrarr1=[49,38,65,97,76,13,27,49]heapSort(arr1)print arr1
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- SD卡初始化
- ps滤镜下载大全-PSCC 64位滤镜收集
- java获取当前操作系统的信息
- 【机器学习算法-python实现】PCA 主成分分析、降维
- Section 1.1 Broken Necklace
- 堆栈
- PHP 获取图像信息 getimagesize 函数
- mule studio 学习笔记 (一): test006-loanbroker-simple
- LeetCode OJ算法题(十):Regular Expression Matching
- Python写的爬取知乎的最多一百篇文章
- Js:getAttribute 取html中某个元素属性的值 或者设置添加属性和值
- pom-for-sshe
- 字符串的的内存分配
- 电脑USB发现不了