堆排序

HeapSort 堆排序

[亡魂溺海] 提交于 2019-12-26 02:07:15
堆的相关知识: 堆? 1.堆是一种完全二叉树 2.每个节点的值总是大于等于(大根堆)或者小于等于(小根堆)子节点的值. 完全二叉树? 除了最后一层外, 每一层都被完全填充, 且所有节点都向左对齐. 大根堆: 每个节点都大于等于子节点 小根堆: 每个节点都小于等于子节点 堆排序需要使用两个函数. 实现以下功能 1. 构建堆,以及实现堆内部对比以及调换. 2. 堆排序的调用, 以及堆大小的控制 # 堆排序_Python实现 # 堆最大化 def heapify(li, i, n): # 父节点位置n largest = i # 子节点位置,左,右 left = i * 2 + 1 right = i * 2 + 2 if left < n and li[left] > li[largest]: largest = left if right < n and li[right] > li[largest]: largest = right if largest != i: li[largest], li[i] = li[i], li[largest] # 显示变动 # print(li) # 当位置发生变动的时候, 递归调用, 重新排位 heapify(li, largest, n) # 因为是直接针对list列表内进行排序, 则不需要返回列表 # 堆排序 def heap_sort

堆排序

微笑、不失礼 提交于 2019-12-25 20:46:11
#include <stdio.h> //首先对于堆的性质必须有了解,堆是用数组模拟的完全二叉树 //完全二叉树就是除了最底层以外所有的节点都是充满的,而且是从左向右充满 //没有以上两个条件堆排序就是不成立的 //通过以上二个条件可以得到以下性质 //如果数组的起点为0,那么对于任意的下标i,有i的左节点的下标为2i + 1,右节点下标为2i + 2 // // //提供交换用 void swap(int* x,int* y){ int tem = *x; *x = *y; *y = tem; } //调整最大堆 //将以下标start作为根节点的子树调整为满足最大堆条件的子树,end是数组的最后一个下标 void max_heapify(int arr[],int start,int end){ //左节点下标 int left = 2 * start + 1; //右节点下标 int right = 2 * start + 2; int largest = start; if(left <= end && arr[left] > arr[start]) largest = left; if(right <= end && arr[right] > arr[largest]) largest = right; //说明存在交换 if(largest != start){

堆排序的实现

只愿长相守 提交于 2019-12-24 12:57:12
import java . util . Arrays ; public class HeapSort { public static void main ( String [ ] args ) { //要求将数组转变程升序排列 int [ ] array = new int [ 6 ] ; int len = array . length ; for ( int i = 0 ; i < len ; i ++ ) { array [ i ] = ( int ) ( Math . random ( ) * 100 ) ; } heapSort ( array ) ; System . out . println ( Arrays . toString ( array ) ) ; } public static void heapSort ( int [ ] array ) { for ( int i = array . length / 2 - 1 ; i >= 0 ; i -- ) { adjustHeap ( array , i , array . length ) ; } for ( int i = array . length - 1 ; i > 0 ; i -- ) { array [ 0 ] = array [ 0 ] + array [ i ] - ( array [

堆排序(C语言实现)

纵然是瞬间 提交于 2019-12-24 02:02:15
堆排序(C语言实现) 算法思想 步骤 程序 算法思想 见: 4. 选择排序—堆排序(Heap Sort) 算法导论------堆排序heapsort 步骤 1. 将n个元素建立初始堆,第一个节点放在数组下标1中,因此n个节点对应数组 a[1] ~ a[n],第 i 个节点的左孩子节点下标为 2i,右孩子节点为 2i + 1。 找到最后一个非叶子节点: 若节点 i 为最后一个非叶子节点,则 (a) 节点i只有左孩子节点(n 为偶数) 2*i = n; i = n/2; (b) 节点i有左右孩子节点 (n 为奇数) 2*i + 1 = n; i = (n-1)/2; n为整数,则 i = n/2 如果将跟节点放在a[0]处,则左孩子节点为 2i + 1,右孩子节点为 2i + 2,同上分析: (a)节点i只有左孩子节点(n 为偶数) 2i + 1 = n-1; i = n/2 - 1; (b)节点i有左右孩子节点 (n 为奇数) 2*i + 2 = n-1; i = (n-1)/2 - 1; n为整数,则 i = n/2 - 1 2. 输出堆顶元素后,将剩下 n-1 个元素重新建堆 程序 //构建最小堆,这样最后排序完数据从大到小排列 # define LeftChild(i) (2 * (i) + 1) //做孩子节点 //将以节点 a[i] 为根节点的构成最小堆 void

python算法

南楼画角 提交于 2019-12-20 23:46:22
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括 关于时间复杂度: 平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。 线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序。 O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序。 线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。 关于稳定性: 稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。 不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。 名词解释: n:数据规模 k:“桶”的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内存 稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同 冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

堆排序

Deadly 提交于 2019-12-20 09:58:47
堆排序,代码简化至32行 原理如下gif图,该图为搜索图,非原创: 源代码: import java.util.Arrays; public class HeapSort { public static void main(String args[]) { int arr[]= {8,6,2,0,7,9,3,4,1,5,11}; System.out.println("source data: "+Arrays.toString(arr)); sort(arr,arr.length-1); System.out.println("heap sort data: "+Arrays.toString(arr)); } private static void sort(int arr[],int len) { for(int i=(len-1)/2;i>=0;i--) adjustHeap(arr,i,len); for(int i=len;i>0;i--) { swap(arr,0,i); adjustHeap(arr,0,i-1); } } private static void adjustHeap(int arr[],int i,int len) { int max=i*2+1; if(max>len) return ; if(max+1<=len&&arr[max]<arr

03-堆排序(包含选择排序)

女生的网名这么多〃 提交于 2019-12-20 07:03:22
选择排序 :顾名思义,就是每次循环从数组[i,n)选择一个最小的元素放入位置i,一共n个元素,需要n-1轮循环。伪代码如下: void selectionSort(ElementType A[], int N){ for(i=0; i<N; i++){ //从A[]到A[]中找最小元,并将其位置赋给MinPosition MinPosition=scanForMin(A,i,N-1); //将未排序部分的最小元换到有序部分的最后位置 swap(A[i],A[MinPositon]); } } #include<bits/stdc++.h> using namespace std; int scanForMin(vector<int>& arr,int start,int end) { int minPos = start; for (int i = start; i <= end;i++) { minPos = arr[i] < arr[minPos] ? i : minPos; } return minPos; } void selectionSort(vector<int>& arr) { int n = arr.size(); int minPos = 0; for (int i = 0; i < n; i++) { minPos = scanForMin(arr, i, n

堆排序(Python)

孤者浪人 提交于 2019-12-19 03:55:53
1、堆 堆是一个完全二叉树。 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。 2、堆的操作 2.1、往堆中插入一个元素 2.2、删除堆顶元素 3、堆排序 借助于堆这种数据结构实现的排序算法,就叫作堆排序。时间复杂度非常稳定,是 O(nlogn) ,并且还是 原地排序 算法。 堆排序的过程大致分解成两个大的步骤: 建堆 和 排序 。 3.1、建堆 3.2、排序 4、小结 堆是一种完全二叉树,它最大特性:每个节点的值都大于等于(或小于等于)其子树节点的值。因此堆被分成了两类,大顶堆和小顶堆。 堆中比较重要的两个操作是插入一个数据和删除堆顶元素。这两个操作都要用到堆化。 插入一个数据的时候,我们把新插入的数据放到数组的最后,然后从下往上堆化; 删除堆顶数据的时候,我们把数组中的最后一个元素放到堆顶,然后从上往下堆化。这两个操作时间复杂度都是 O(logn)。 堆排序 堆排序包含两个过程,建堆和排序。我们将下标从 2n​ 到 1 的节点,依次进行从上到下的堆化操作,然后就可以将数组中的数据组织成堆这种数据结构。 接下来,我们迭代地将堆顶的元素放到堆的末尾,并将堆的大小减一,然后再堆化,重复这个过程,直到堆中只剩下一个元素,整个数组中的数据就都有序排列了。 来源: CSDN 作者: NLP_victor 链接: https://blog.csdn.net/IOT

常见排序算法

泪湿孤枕 提交于 2019-12-18 01:16:56
1、冒泡排序 算法思想简单描述: 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上 而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较 小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要 求相反时,就将它们互换。 冒泡排序是稳定的。算法时间复杂度O(n2)--[n的平方] main() {int a[10],i,j,k; printf("This is a maopao sort\n"); printf("Please input 10 numbers for sort:"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<9;i++) for(j=0;j<10-i;j++)if(a[j]>a[j+1]) {k=a[j];a[j]=a[j+1];a[j+1]=k;} printf("The corret sort of those numbers is:"); for(i=0;i<10;i++) printf(" %d",a[i]); printf("\n"); } 2、选择排序 算法思想简单描述: 在要排序的一组数中,选出最小的一个数与第一个位置的数交换; 然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环 到倒数第二个数和最后一个数比较为止。 选择排序是不稳定的。算法复杂度O(n2)--[n的平方

Java数据结构和算法 - 堆

好久不见. 提交于 2019-12-17 22:53:53
堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java、C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉树: 1) 是一棵完全二叉树 2) 通常由数组实现。前面介绍了 如何用数组表示树 3) 堆中的每个节点都满足堆的条件,即每个节点的关键字都大于(或等于)这个节点的子节点关键字 下图显示了堆与实现它的数组之间的关系: A: 堆是完全二叉树的事实说明了表示堆的数组中没有“洞”,从下标0到N-1,每个元素都有数据项 A: 本篇中假设最大的关键字在根节点,基于这种堆的优先级是降序的优先级队列 A: 若数组中节点的索引为i,则 1) 它的父节点的下标为(i - 1) / 2; 2) 它的左子节点的下标为 2 * i + 1; 3) 它的右子节点的下标为 2 * i + 2 Q: 弱序? A: 堆相对于二叉搜索树比较而言是弱序的,在二叉搜索树中所有的节点的左子孙的关键字都小于右子孙的关键字。二叉搜索树可以通过简单的算法就可以按序遍历节点,但在堆中,按序遍历节点是困难的,这是因为堆的组织规则比二叉搜索树的组织规则弱。 A: 对堆来说,只要求沿着从根到叶子的每一条路径,节点都是按降序排列 A: 在堆中不能便利地查找指定的关键字,因为在查找过程中,没有足够的信息来决定选择通过节点的哪一个子节点走向下一层