表ADT的两种实现
表的简单数组实现
对表的所有操作都可以通过数组来实现,它可以使得printList以线性时间被执行,而findKth操作则花费常数时间,不过,插入和删除的花费却潜藏着昂贵的开销,这取决于插入和删除发生在什么地方。
最坏的情况下,插入和删除发生在数组的最前端,那么整个数组的元素都将后移或者是前移一个位置。
最好的情况下,即插入和删除发生在数组的末端,那么就没有元素需要移动。
所以,在很少对表进行插入和删除,只发生对表的查询的情形下,数组是表的一种恰当的实现,而对于需要频繁对表的数据进行操作,特别是对表的前端进行的情形下,那么数组就不是一个好的选择。
表的简单链表实现
为了避免插入和删除的线性开销,我们需要保证表可以不连续存储,否则表可能需要整体移动,下图是链表的一般结构。
链表是由一系列节点组成,这些节点不必再内存中相连,每个节点都含有表元素和该元素后继节点的链。我们称之为next链。最后一个单元的next链引用为null。
与数组相比,链表的插入和删除操作的效率要高的多,但是findKth操作却不如数组效率高。
链表删除最后一项时,比较复杂,因为必须找出指向最后节点的项,把它的next链改为null,然后在更新持有最后节点的链。在经典的链表中,节点只存储到其下一个节点的链,不会存储最后节点的前驱节点的信息。故而,我们让每个节点持有一个指向其在表中前驱节点的链,我们称之为双链表,如下图所示。