堆是否被视为抽象数据类型?

时间:2016-06-30 13:31:06

标签: data-structures heap priority-queue abstract-data-type

我正在学习数据结构课程,对于被认为是ADT(抽象数据类型)和什么不是(如果它不是ADT,那么它必须是实现? )。

具体来说,我说的是Heap。

我在维基百科中读过“堆是一种专门的基于树的数据结构”,这是否意味着它是一个ADT?如果是这样,那么我无法理解以下这一行,也来自维基百科“堆是一种称为优先级队列的抽象数据类型的最高效实现”。

我的意思是,Heap可以是ADT还是其他ADT的实现(在这种情况下是优先级队列的实现?我理解ADT的概念,在Binary Heap的上下文中我理解它可以实现使用arr[i]arr[2i]arr[2i + 1]的父级的数组 我只是想知道Heap一方面是使用数组实现的ADT还是实现其他ADT的数据结构。

希望得到一些澄清。

5 个答案:

答案 0 :(得分:6)

堆不是ADT。这是一个数据结构。

强制性的维基百科报价:

  

在计算机科学中,抽象数据类型(ADT)是一种数学   数据类型的模型,其中数据类型由其行为定义   (具体而言)从数据的用户的角度来看(语义)   就可能的值而言,可能对此类数据进行操作,   以及这些操作的行为。这与数据形成对比   结构,是数据的具体表示,是   实施者的观点,而不是用户。

奖励内容受到Steve McConnell的Code Complete -2启发。

数据结构是低级实现域项,与在问题域中工作的ADT形成对比。 ADT允许您操纵实际实体而不是低级实现实体。您可以将单元格添加到电子表格,将新类型的窗口添加到窗口类型,或将其他乘客添加到火车模拟中,而不是将节点插入链接列表或将项目添加到堆中。

  • 您可以清楚地看到堆已经定义了语义,如insert(),heapify(),peek(),getTop()等 - 详细列出了here。因此它是一种数据结构。

  • 但是,如果你模拟一个俄罗斯方块游戏,那么添加一个新区块只会放置在任何位置的顶部,这个俄罗斯方块游戏的UI实际上将是一个ADT。 < / p>

答案 1 :(得分:2)

堆不被视为抽象数据类型。

Heap是一种专门的基于树的数据结构,它是名为Priority Queue的抽象数据类型的实现。

请参阅https://en.wikipedia.org/wiki/Heap_(data_structure)

答案 2 :(得分:1)

1)Java软件结构,国际版[John Lewis,Joseph Chase]

  

抽象数据类型(ADT)是一种数据类型,其值和操作   不是在编程语言中固有地定义的。它是   仅在实现的细节必须是抽象的   已定义,应向用户隐藏。因此,一个集合   是一种抽象数据类型。

2)算法,Robert Sedgewick和Kevin Wayne第四版

  

使用抽象数据类型您不必知道如何实现数据类型即可使用它。

因此,如果您仅设计如下行为:

3)Wikipead堆操作:

Basic

    find-max (or find-min): find a maximum item of a max-heap, or a minimum item of a min-heap, respectively (a.k.a. peek)
    insert: adding a new key to the heap (a.k.a., push[4])
    extract-max (or extract-min): returns the node of maximum value from a max heap [or minimum value from a min heap] after removing it from the heap (a.k.a., pop[5])
    delete-max (or delete-min): removing the root node of a max heap (or min heap), respectively
    replace: pop root and push a new key. More efficient than pop followed by push, since only need to balance once, not twice, and appropriate for fixed-size heaps.[6]

Creation

    create-heap: create an empty heap
    heapify: create a heap out of given array of elements
    merge (union): joining two heaps to form a valid new heap containing all the elements of both, preserving the original heaps.
    meld: joining two heaps to form a valid new heap containing all the elements of both, destroying the original heaps.

Inspection

    size: return the number of items in the heap.
    is-empty: return true if the heap is empty, false otherwise.

Internal

    increase-key or decrease-key: updating a key within a max- or min-heap, respectively
    delete: delete an arbitrary node (followed by moving last node and sifting to maintain heap)
    sift-up: move a node up in the tree, as long as needed; used to restore heap condition after insertion. Called "sift" because node moves up the tree until it reaches the correct level, as in a sieve.
    sift-down: move a node down in the tree, similar to sift-up; used to restore heap condition after deletion or replacement.

真的,这只是一个ADT,实现是数据结构,实际上,两本书之一将堆定义为ADT

因此,用1和2表示3可以是堆的ADT,因为您可以使用数组和指针来实现堆。和优先级队列相同,但是时间复杂度可以改变

Java软件结构国际版[John Lewis,Joseph Chase] 中,有HeapADT

public interface HeapADT<T> extends BinaryTreeADT<T>
{
/**
* Adds the specified object to this heap.
*
* @param obj the element to be added to this heap
*/
public void addElement (T obj);
/**
* Removes element with the lowest value from this heap.
*
* @return the element with the lowest value from this heap
*/
public T removeMin();
/**
* Returns a reference to the element with the lowest value in
* this heap.
*
* @return a reference to the element with the lowest value in this heap
*/
public T findMin();
}

但在Robert Sedgewick和Kevin Wayne撰写的算法第4版中,PriorityQueue作为ADT:

public class MaxPQ< Key extends Comparable<Key>> 
MaxPQ() create a priority 
queueMaxPQ(int max) create a priority queue of initial capacity max 
MaxPQ(Key[] a) create a priority queue from the keys in a[]
void  insert(Key v) insert a key into the priority queueKey  
max() return the largest keyKey  
delMax() return and remove the largest key  
boolean isEmpty() is the priority queue empty?
int  size() number of keys in the priority queue

作为DS:https://algs4.cs.princeton.edu/24pq/MaxPQ.java.html

我认为他们只会这样说:

  

二进制堆是一种数据结构,可以有效地支持   基本优先级队列操作。在二进制堆中,键

因为他们正在谈论实现:

  

存储在数组中,以确保每个键都可以   大于(或等于)其他两个特定位置上的键。

可以说另一个有关List的例子,List可以是adt,静态数组和dinamic数组是实现List的数据结构,但是另一位作者将ADT定义为它,因为这是预期的行为。

您可以在另一本书中查阅以下数组: N。S. KUTTI,P。Y. PADHYE撰写的C ++数据结构(您可以选中here

好的,如果您要定义某事物的行为,我会说这是ADT,而如果要实现该行为,我会说这是DS。

编辑:

书籍之间的另一个矛盾

Java Robert Lafore中的数据结构和算法

  

优先级队列是一种更专业的数据结构

答案 3 :(得分:0)

我会尝试以其他方式澄清这种混乱。从here引用维基百科:

  

虽然优先级队列通常使用堆来实现,但它们是   在概念上与堆不同。优先级队列是抽象的   概念如&#34;列表&#34;或者&#34;地图&#34 ;;就像列表可以实现一样   使用链表或数组,可以实现优先级队列   使用堆或各种其他方法,如无序数组。

因此堆只是优先级队列抽象数据类型(ADT)的一种实现,可以在下面列出的许多其他实现中实现,但可能不限于:

  • 无序数组
  • 无序列表
  • 有序数组
  • 有序列表
  • 二进制搜索树(BST)
  • 平衡二进制搜索树(AVL-tree)
  • 二进制堆(由OP询问)

将Priority Queue ADT中主要操作的堆实现的时间效率与其他可能的实现进行比较:

----------------------------------------------------------------------------
| Implementation | Insertion   | Deletion(DeleteMax/DeleteMin)|Find Max/Min
----------------------------------------------------------------------------
| Unordered Array| 1           | n                            | n
----------------------------------------------------------------------------
| Unordered List | 1           | n                            | n
----------------------------------------------------------------------------
| Ordered Array  | n           | 1                            | 1
----------------------------------------------------------------------------
| Ordered List   | n           | 1                            | 1
----------------------------------------------------------------------------
| BST            | logn (avg.) | logn (avg.)                  | logn (avg.)
----------------------------------------------------------------------------
| Balanced BST   | log n       | log n                        | log n
----------------------------------------------------------------------------
| Binary Heaps   | log n       | log n                        | 1

答案 4 :(得分:0)

我正在向您展示Wikipedia的整行内容,而您只是引用了使您感到困惑的那部分内容。也许,如果您只是进入下一部分内容,可能会更好地理解它。

  

堆是一种称为优先级队列的抽象数据类型的最大有效实现,实际上,优先级队列通常被称为“堆”,而不管它们如何实现。堆的常见实现是二进制堆,其中树是二进制树

在这里说

  

实际上,优先级队列通常被称为“堆”,而不管它们如何实现。

由于堆数据结构(DS)的普及,在实现优先级队列ADT时。优先级队列ADT通常称为堆

在维基百科的下一行引用中

  

堆的常见实现是二进制堆,其中树是二进制树

这里第一个堆表示优先级队列,二进制堆表示短堆表示数据结构。

因此,当您看到堆(在ADT的上下文中)时,实际上意味着优先级队列ADT,并且堆是其实现。因此,堆是DS。

在此引用的地方:

  

“堆是基于树的专用数据结构”

这只是表示它是DS,而不是ADT。