【发布时间】:2011-03-03 00:15:39
【问题描述】:
我想知道为什么我们总是对列表和数组使用诸如(插入排序或合并排序,...)之类的排序算法?为什么我们不将这些算法用于堆栈或队列?
【问题讨论】:
-
您的问题真的是关于堆栈和队列,还是关于排序算法是否对“其他事物”有用?
-
我想知道排序算法有利于对堆栈和队列等其他数据结构进行排序......?
标签: java data-structures
我想知道为什么我们总是对列表和数组使用诸如(插入排序或合并排序,...)之类的排序算法?为什么我们不将这些算法用于堆栈或队列?
【问题讨论】:
标签: java data-structures
堆栈和队列是抽象的数据类型,它们有自己的顺序感,即堆栈的 LIFO(后进先出)和队列的 FIFO(先进先出)。因此,获取队列/堆栈并重新排列它们的元素是没有意义的。
您可能会注意到,在 Java 中,java.util.Stackextendsjava.util.Vector,因为对 Vector 进行排序是有意义的,所以对 Stack 进行排序可能也有意义。然而,情况并非如此; Stack extends Vector 实际上是一个设计错误。堆栈不是向量。
java.util.Stack 上使用 Collections.sort
尽管在堆栈上使用快速排序没有意义,但您可以实际上在 java.util.Stack 上使用 Collections.sort。为什么?因为,由于设计错误(这一点怎么强调都不为过!),java.util.Stack 就是java.util.Vector,而implements java.util.List,你肯定可以排序List。这是一个例子:
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(3);
stack.push(5);
stack.push(2);
stack.push(4);
Collections.sort(stack); // by virtue of design error!!!
System.out.println(stack); // prints "[1, 2, 3, 4, 5]"
while (!stack.isEmpty()) {
System.out.println(stack.pop());
} // prints "5", "4", "3", "2", "1"
请注意,元素是按降序打印的:这是因为java.util.Stack 的实现方式。它从Vector 的末尾推送和弹出。你不需要知道这一点;你不应该知道这一点;但这些都是事实。
根据您要完成的任务,TreeSet 可能是合适的数据结构。它是Set,所以它不允许重复元素。
NavigableSet<Integer> nums = new TreeSet<Integer>();
nums.add(5);
nums.add(3);
nums.add(1);
nums.add(2);
nums.add(6);
System.out.println(nums.pollFirst()); // prints "1"
System.out.println(nums.pollFirst()); // prints "2"
nums.add(4);
System.out.println(nums.pollFirst()); // prints "3"
System.out.println(nums.pollFirst()); // prints "4"
【讨论】:
List,然后按照你的意愿重新排列它们。然而,对堆栈本身的元素重新排序,违反了堆栈是什么以及它应该如何表现的定义。
这是因为堆栈或队列的顺序是这些数据结构定义的一部分。如果我们对它们进行排序,它们就不会是堆栈或队列。
【讨论】:
正如其他人所指出的,通常对堆栈和队列进行排序是没有意义的。只是为了让图片完整,有一个例外:PriorityQueue,它保持其元素有序。
【讨论】:
堆栈或队列是不同于序列的概念。数组和链表代表序列,您可以将它们视为已排序或未排序。
【讨论】:
堆栈和队列有自己独特的结构。 堆栈是一种应用后进先出(LIFO)的结构。如果您订购了一个堆栈,那么它将违反 LIFO。 认为我将 7、3、5、4 添加到堆栈中。 如您所知,堆栈只能检索最后添加的元素。每当我们调用 pop() 方法时,它都会检索 4。 但是,请考虑您现在对其进行排序。它变成 3, 4, 5, 7,当我们 pop() 时,它将检索 7,这是我们添加的第一个元素。这违反了 LIFO 规则。
同样适用于队列,因为队列结构适用先进先出。如果您有任何问题,请不要犹豫。
【讨论】:
首先堆栈和队列也是列表,但有一些特殊的特性。由于它们是列表,因此您始终可以对它们进行排序,但如果这样做,您可能会更改这些数据结构的属性。
那么在整个代码中使用这些数据结构并在某些时候对它们进行排序以释放我们使用它们的属性将毫无意义。
【讨论】: