`
leonzhx
  • 浏览: 793634 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

1.  Like merge sort, but unlike insertion sort, heapsort’s running time is O(n lg n). Like insertion sort, but unlike merge sort, heapsort sorts in place.

 

2.  The (binary) heap data structure is an array object that we can view as a nearly complete binary tree. Although A[1...A.length] may contain numbers, only the elements in A[1...A.heap-size], where ≤ A.heap-size ≤ A.length, are valid elements of the heap. The root of the tree is A[1], and given the index i of a node, the index of its parent is i/2 and the index of its left and right child is 2i and 2i+1 respectively.



 

3.  There are two kinds of binary heaps: max-heaps and min-heaps. In both kinds,

the values in the nodes satisfy a heap property, the specifics of which depend on

the kind of heap. In a max-heap, the max-heap property is that for every node i

other than the root, A[PARENT(i)] ≥ A[i]. Thus, the largest element in amax-heap is stored at the root, and the subtree rooted at a node contains values no larger than that contained at the node itself. A min-heap is organized in the opposite way.

 

4.  Viewing a heap as a tree, we define the height of a node in a heap to be the

number of edges on the longest simple downward path from the node to a leaf, and we define the height of the heap to be the height of its root. Since a heap of n elements is based on a complete binary tree, its height is θ(lg n). The basic operations on heaps run in time at most proportional to the height of the tree and thus take O(lg n) time.

 

5.  The inputs of sink are an array A and an index i into the array. When it is called, sink assumes that the binary trees rooted at LEFT[i] and RIGHT[i] are maxheaps, but that A[i] might be smaller than its children, thus violating the max-heap property. sink lets the value at A[i] “float down” in the max-heap so that the subtree rooted at index i obeys the max-heap property:

 

void sink (int i) {
    while ( true ) {
        int largest = i ;
        int left = i << 1;
        if ( left <= this.size && gt(left , largest) ) largest = left;
        int right = left + 1;
        if ( right <= this.size && gt(right , largest) ) largest = right;
        if ( largest == i ) break;
        swap(i, largest);
        i = largest;
    }
}

boolean gt(int i , int j) {
    // array index starts from 0
    return this.arr[i-1] > this.arr[j-1];
}

void swap(int i , int j) {
    // array index starts from 0
    int temp = this.arr[--i];
    this.arr[i] = this.arr[--j];
    this.arr[j] = temp;
}

We can characterize the running time of sink on a node of height h as O(h) = O(lg n)

 

6.  We can use the sink in a bottom-up manner to convert an array A[1...n], where n = A.length, into a max-heap. The elements in the subarray A[n/2+1...n] are all leaves of the tree, and so each is a 1-element heap to begin with. The method heapfy goes through the remaining nodes of the tree and runs sink on each one:

 

void heapfy() {
    for ( int i = this.size >> 1 ; i > 0; i -- ) {
        sink(i);
    }
}

We can easily prove the correctness of the above algorithm by the following invariant: At the start of each iteration of the for loop, each node i+1i+2, ... , n is the root of a max-heap. Since an n-element heap has height lgn⌋ and at most 

⌈n/2^(h+1)⌉ nodes of any height hThe time required by heapfy when called on a node of height h is O(h) and so we can express the total cost of heapfy as O(∑(h=0 to lgn) ( h * n/2^h) ) = O(n). So heapfy produces a min-heap from an unordered linear array in linear time.

 

7.  The heapsort algorithm starts by using heapfy to build a max-heap on the input array A[1...n], where n =A.length. Since the maximum element of the array is stored at the root A[1], we can put it into its correct final position by exchanging it with A[n]. The children of the root remain max-heaps with last element regarded from the heap, but the new root element might violate the max-heap property. All we need to do to restore the max-heap property is call sink(1), which leaves a max-heap in A[1...n-1]. The heapsort algorithm then repeats this process for the max-heap of size n-1 down to a heap of size 2:

 

void heapsort() {
    this.size = this.arr.length;
    heapfy();
    while (this.size > 1 ) {
        swap( 1 , this.size--);
        sink(1);
    }
}

 

The heapsort method takes time O(n lg n), since the call to heapfy takes time O(n) and each of the n-1 calls to sink takes time O(lg n).

 

8.  Heapsort is an excellent algorithm, but a good implementation of quicksort usually beats it in practice. One of the most popular applications of a heap is as an efficient priority queue. As with heaps, priority queues come in two forms: max-priority queues and min-priority queues.

 

9.  A priority queue is a data structure for maintaining a set S of elements, each with an associated value called a key. A max-priority queue supports the following operations:

    1)  INSERT(S , x) inserts the element x into the set S, which is equivalent to the operation S=S U {x}.

    2)  MAXIMUM(S) returns the element of S with the largest key.

    3)  EXTRACT-MAX(S) removes and returns the element of S with the largest key.

    4)  INCREASE-KEY(S, x, k) increases the value of element x’s key to the new value k, which is assumed to be at least as large as x’s current key value.

 

10.  We can use max-priority queues to schedule jobs on a shared computer. The max-priority queue keeps track of the jobs to be performed and their relative priorities. When a job is finished or interrupted,

the scheduler selects the highest-priority job from among those pending by calling EXTRACT-MAX. The scheduler can add a new job to the queue at any time by calling INSERT.

 

11.  A min-priority queue can be used in an event-driven simulator. The items in the queue are events to be simulated, each with an associated time of occurrence that serves as its key. The events must be

simulated in order of their time of occurrence, because the simulation of an event can cause other events to be simulated in the future. The simulation program calls EXTRACT-MIN at each step to choose the next event to simulate. As new events are produced, the simulator inserts them into the min-priority queue by calling INSERT.

 

12.  When we use a heap to implement a priority queue, therefore, we often need to store a handle to the corresponding application object in each heap element. Similarly, we need to store a handle to the corresponding heap element in each application object. Here, the handle would typically be an array index. Because heap elements change locations within the array during heap operations, an actual implementation, upon relocating a heap element, would also have to update the array index in the corresponding application object. 

 

13.  The maximum method can be implemented as :

 

 

int maximum() {
  if (this.size < 1) throw new NoSuchElementException("priority queue is empty!");
  return get(1);
}

int get(i) {
    // array index starts from 0
    return this.arr[0];
}

The extractMax method can be implemented as :

 

int extractMax() {
    if (this.size < 1) throw new NoSuchElementException("priority queue is empty!");
    swap(1, this.size--);
    if ( this.size > 0 ) sink(1);
    return get(this.size + 1);
}
The running time of extractMax is O(lg n), since it performs only a constant amount of work on top of the O(lg n) time for sink.

 

14.  The method increaseKey first updates the key of element A[i] to its new value. Because increasing the key of A[i] might violate the max-heap property,the method then traverses a simple path from this node toward the root to find a proper place for the newly increased key. As increaseKey traverses this path, it repeatedly compares an element to its parent, exchanging their keys and continuing if the element’s key is larger, and terminating if the element’s key is smaller, since the max-heap property now holds:

 

void increaseKey( int i , int newValue) {
    if ( newValue <= get(i) ) throw new IllegalArgumentException("the newValue should be bigger than the existing value.");
    set(i, newValue);
    swim(i);
}

void set(int i, int value) {
    // array index starts from 0
    this.arr[i-1] = value;
}

void swim (int i) {
  int parent = i >> 1;
  while( parent > 0 && gt(i, parent) ) {
      swap(i, parent);
      i = parent;
      parent = i >> 1;
  } 

}

 

The running time of increaseKey on an n-element heap is O(lg n), since the path

traced from the node updated to the root has length O(lg n).

 

15.  The method insert first expands the max-heap by adding to the tree a new leaf whose key is the new value. Then it calls swim to put this new node to its correct position thus maintain the max-heap property:

 

void insert(int newValue) {
    set(++ this.arr.size , newValue);
    swim(this.arr.size);
}

The running time of insert on an n-element heap is O(lg n).

 

16.  In summary, a heap can support any priority-queue operation on a set of size n in O(lg n) time.

 

 

  • 大小: 18.3 KB
分享到:
评论

相关推荐

    libbsd-0.6.0-1.el6.x86_64与libbsd-devel-0.6.0-1.el6.x86_64

    64和libbsd-devel-0.6.0-1.el6.x86_64是针对RHEL6的64位系统的软件包,它们提供了一套BSD风格的函数和工具,帮助开发和运行在Linux环境下需要BSD特性的程序,特别是当系统原生库中缺少某些功能(如`heapsort`)时。...

    sort-使用C++实现的排序算法之HeapSort.zip

    int arr[] = {12, 11, 13, 5, 6, 7}; int n = sizeof(arr) / sizeof(arr[0]); heapSort(arr, n); std::cout ; printArray(arr, n); return 0; } ``` 这段代码首先定义了一个`heapify`辅助函数,用于确保任何...

    算法导论详细答案(英文版)

    #### 6. Heapsort 堆排序是一种高效的排序算法,利用完全二叉树的数据结构实现。本章详细解释了堆排序的工作原理,包括构建最大堆和最小堆的过程,以及如何通过堆调整来实现排序。堆排序的最坏情况时间复杂度为O(n ...

    leetcode2sumc-dsa:使用golang练习DSA

    HeapSort - Library Implementation - Custom Implementation 5. QuickSort 6. MergeSort 链表 1. InsertAtEnd 2. InsertAtBeginning 3. InsertAtPos 4. DeleteAtEnd 5. DeleteAtBeginning 6. DeleteAtPos 7. ...

    Heapsort:教学法讲座Heapsort

    **6. 问卷** 问卷可能是为了检验学生对Heapsort的理解,可能包含选择题、填空题和/或简答题,涉及堆的性质、Heapsort的步骤、效率分析等方面。 通过这个Heapsort的教学资料,学生不仅能学习到排序算法的基础知识,...

    Skiena-The_Algorithm_Design_Manual.pdf

    4.3 Heapsort: Fast Sorting via Data Structures . . . . . . . . . . . . 108 4.4 War Story: Give me a Ticket on an Airplane . . . . . . . . . . . 118 4.5 Mergesort: Sorting by Divide-and-Conquer . . . ....

    Heapsort:Heapsort在Java中用于ICS4U的实现

    int[] array = {12, 11, 13, 5, 6, 7}; new Heapsort().heapSort(array); System.out.println("Sorted array is " + Arrays.toString(array)); ``` **Java中的`Arrays.sort()`方法虽然默认使用了更高效的Timsort,...

    libbsd-devel

    编译src.3e.tar.gz时错误,具体错误如下:barrier.c:(.text+0x80): undefined reference to `heapsort' collect2: error: ld returned 1 exit status,安装libbsd-devel和libbsd即可,适用于centos7 64位

    使用C语言实现堆排序.docx

    6. 调用 heapSort 函数,执行堆排序。 7. 打印排序后的数组。 堆排序是一种高效的排序算法,它可以在 O(n log n) 的时间复杂度下对数组进行排序。在 C 语言的实现中,我们可以使用 heapify 函数和 heapSort 函数来...

    堆排序C语言和java语言

    而在Java版本中,我们创建了一个名为`HeapSort`的类,并在其中定义了`heapify`和`heapSort`方法,然后在`main`函数中实例化这个类并调用相应方法。 总的来说,堆排序的时间复杂度为O(n log n),空间复杂度为O(1),...

    2022年计算机四级嵌入式系统开发工程师模拟试题四.docx

    3. Heapsort优先队列:实现create、insert、delete功能,heapsort算法具有O(n log n)的时间复杂度,适用于在线性时间内难以预估的情况,且空间效率高,适合实时系统。 4. Trie树字典:Trie树是一种多叉树结构,用于...

    堆排序(C#,C++)算法导论

    std::vector&lt;int&gt; arr = {12, 11, 13, 5, 6, 7}; heapSort(arr); for (int val : arr) std::cout ; return 0; } ``` 以上代码展示了如何在C#和C++中分别实现堆排序算法。在实际应用中,堆排序具有O(n log n)的...

    Advanced Topics in C.pdf

    Sophisticated sorting methods such as heapsort, quicksort, and mergesort How to implement all of the above using C Who this book is for Those with a working knowledge of basic programming concepts, ...

    HeapSort:Java中的堆排序实现

    public static void heapSort(int[] arr) { int n = arr.length; for (int i = n / 2 - 1; i &gt;= 0; i--) heapify(arr, n, i); for (int i = n - 1; i &gt;= 0; i--) { swap(arr, 0, i); heapify(arr, i, 0); ...

    HeapSort:执行 3 向堆排序

    **堆排序(HeapSort)详解** 堆排序是一种基于比较的排序算法,它的核心思想是利用数据结构中的“堆”来实现。在计算机科学中,堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子节点的键值或索引总是小于...

    leetcodepdfpython-hello-world:资料结构与演算法资料库-这是资料结构与演算法的程式码与演算法流程图及文字描述

    leetcode pdf python大家好,我是彦,目前就读大四, 最近在精进写程式的能力,这里是我存放资料结构与演算法课程的资料库,欢迎参阅! 此为资料结构演算法笔记 档案架构 ...HW6 Dijkstra_05170221.p

    Algoritmo-Heapsort-c-:通过文件参数上传文件实现的算法

    6. **性能分析**: - 堆排序的时间复杂度为O(n log n),其中n是待排序元素的数量。在最坏、最好和平均情况下,时间复杂度都是O(n log n)。 - 空间复杂度为O(1),因为它是在原地排序,不需要额外的存储空间。 7. *...

    [麻省理工学院-算法导论].Introduction.to. Algorithms,.Second.Edition

    Chapter 6 - Heapsort Chapter 7 - Quicksort Chapter 8 - Sorting in Linear Time Chapter 9 - Medians and Order Statistics Part III - Data Structures Chapter 10 - Elementary Data Structures ...

    算法导论 手册 作者自己写的

    #### 6. Quicksort(快速排序) 快速排序是一种非常高效的排序算法,其基本思想是通过分治法将待排序数组分为较小和较大的两个子数组,然后递归地对这两个子数组进行排序。本章将深入探讨快速排序的细节。 #### 7....

    基于 Java 的堆排序.pdf

    heapSort.sort(array); System.out.println("Sorted array is:"); printArray(array); } public void sort(int[] array) { int n = array.length; // Build heap (rearrange array) for (int i = n / 2 - ...

Global site tag (gtag.js) - Google Analytics