The most intuitive solution is popping all elements into an array, sorting the array and pushing all elements back to the stack.
from stack import *
def sort_stack(s):
elements = []
while not s.isEmpty():
elements.append(s.pop())
quick_sort(elements, 0, len(elements) - 1)
for i in range(0, len(elements)):
s.push(elements[i])
def quick_sort(arr, start, end):
if start >= end:
return
pivot = choose_pivot(arr, start, end)
pivot_value = arr[pivot]
arr[pivot], arr[start] = arr[start], arr[pivot]
pivot = start
p = start + 1
while p <= end:
if arr[p] <= pivot_value:
pivot = pivot + 1
arr[p], arr[pivot] = arr[pivot], arr[p]
p = p + 1
arr[pivot], arr[start] = arr[start], arr[pivot]
quick_sort(arr, start, pivot - 1)
quick_sort(arr, pivot + 1, end)
def choose_pivot(arr, start, end):
return start
# Test case
if __name__ == "__main__":
s = stack()
s.push(3)
s.push(1)
s.push(4)
s.push(2)
s.push(8)
s.push(7)
sort_stack(s)
for i in range(0, 7):
print s.pop()
However, it is so intuitive that I don't think it is the most reasonable solution. As expected, the solution on the answer page uses two stacks to achieve the goal.
from stack import *
def sort_stack(s):
s2 = stack()
while not s.isEmpty():
tmp = s.pop()
while (not s2.isEmpty()) and (s2.peek() <= tmp):
s.push(s2.pop())
s2.push(tmp)
while not s2.isEmpty():
s.push(s2.pop())
Although the solution above cannot beat mine on running time, it is an innovative method.
Here I want to summarize the mistakes that I prone to make when I am implementing quicksort:
1) The ending condition of recursion is "if start >= end", not "if start == end"
2) The initial position of pivot is array[start], not array[0]
3) The initial position of working pointer is (start + 1), not start
4) In quick_sort() (or partition()), never use array[0] and array[len(array)]. You should use array[start] and array[end].