高频面试题目
一、堆排序
1、基础知识
* ------基本知识:
* 1. 堆数据结构特征:
* 大顶堆:所有父节点大于等于左右子节点,arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2];
* 大顶堆:所有父节点小于等于左右子节点,arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2];
* 大顶堆只能保证顶元素时最大的,无法保证整个堆(数组)是有序的,小顶堆同理。
* 2. 索引规律:
* 最后一个非叶子节点:N/2-1;
* 父节点i,则左子节点2*i+1,右子节点2*i+2;
* 3. 堆与树的区别
* ①堆占用空间较少;
* 树结构需要存储左右节点指针,占用空间较多;堆仅使用数组;
* ②二叉搜索树与堆
* 二叉搜索树整体都是有序的,搜索很快(logN),插入或删除元素时需要保持平衡,复杂度会超过;
* 使用堆的主要目的是将最大值或最小值放在最前面,从而快速地进行插入和删除操作。
* -----------------------------------------------------------------
* 2021-02-22 17:20:20
* 堆排序的过程包括两部分(升序):构建大顶堆+交换元素调整堆;
* 其中核心操作就是adjustHeap;
* S1:构建大顶堆:从下往上遍历所有非叶子节点,调整堆;
* S2:构建大顶堆之后,保证顶元素最大,交换顶元素与末尾元素,再次调整堆(堆长度减1)。
* 关键方法:adjustHeap调整堆方法,adjustHeap(int[] arr, int rootIndex, int len).
* -----------------------------------------------------------------
* adjustHeap方法功能:
* 当前节点及之下的节点满足父节点大于等于左右子节点,但是改变了当前节点的值,
* 此时当前节点可能会小于左右子节点,因此需要将调整堆,使其再恢复大顶堆特征。
* adjustHeap方法思路:
* ①当前节点是叶子节点,即2*i+1>=len,则直接退出;
* ②找到左右子节点的较大者;
* ③若当前节点小于较大子节点,则交换;当前子节点值发生改变,则需要递归或循环执行①②。
* 若当前节点大于较大子节点,方法结束。
* -----------------------------------------------------------------
* 如何构建大顶堆或小顶堆(堆的初始化)?
* adjustHeap方法本来是在大顶堆已经建立的基础上,调整堆的,而大顶堆的初始化是通过从下而上,
* 对每一个非叶子节点都执行一次adjustHeap,因此后一次调用在前一次执行的基础之上,因此满足adjustHeap的条件,
* 最后是调整顶节点,因此最终完成大顶堆的初始化。
* 具体实现过程: 依次从最后一个非叶子节点向上遍历,进行调整;
* 假如节点个数为N,则最后一个非叶子节点序号为N/2-1,即N/2个非叶子节点,
* 也就是需要调用N/2次adjustHeap方法;从N/2-1到0.
* -