问题
I was given a task to sort numbers in stack a
of integers in ascending order using two stacks a
and b
.
Using eleven operations:
- sa :
swap a
- swap the first 2 elements at the top of stacka
- sb :
swap b
- swap the first 2 elements at the top of stackb
. - ss :
sa
andsb
at the same time. - pa :
push a
- take the first element at the top ofb
and put it at the top ofa
. - pb :
push b
- take the first element at the top ofa
and put it at the top ofb
. - ra :
rotate a
- shift up all elements of stacka
by 1. The first element becomes the last one. - rb :
rotate b
- shift up all elements of stackb
by 1. The first element becomes the last one. - rr :
ra
andrb
at the same time. - rra : reverse
rotate a
- shift down all elements of stacka
by 1. The last element becomes the first one. - rrb : reverse
rotate b
- shift down all elements of stackb
by 1. The last element becomes the first one. - rrr :
rra
andrrb
at the same time.
My sorting function
void sorts_stack(stack *a, stack *b)
{
int srt;
srt = is_not_sorted(a);
if (srt)
{
if (a->list[srt] == top(a) && a->list[srt] > a->list[0])
{
rotate_ra_rb(a->list, a->size); //ra : rotate a
putstr("ra\n");
}
else if (a->list[srt] == top(a) && a->list[srt] > a->list[srt - 1])
{
swap_sa_sb(a->list, a->size);//sa : swap a
putstr("sa\n");
}
else if (a->list[srt] > a->list[srt - 1])
{
putstr("pb\n"); //pb : push b
push_pb(a, b);
}
sorts_stack(a, b);
}
else if (b->size > 0)
{
if (top(a) < top(b))
{
push_pa(a, b); //pa : push a
putstr("pa\n");
}
else if ((top(a) > top(b)) && b->size != 0)
{
push_pa(a, b); //pa : push a
putstr("pa\n");
}
sorts_stack(a, b);
}
}
my function sort the stack, I think it takes too many steps to sort. I need suggestions or advice on how to make it sort the stack with less steps taken. complete online code
回答1:
Given two stacks A and B, where A is filled with a random permutation of elements and B is empty, and one temporary variable T able to hold one element (and a counter but the counter doesn't count) you can sort A in ascending order into B by:
- move all elements from A to B but keep the largest element in T
- move all elements from B to A
- put element in T on the stack B
- Loop until A is empty
- move all elements from A to B but keep the largest element in T
- move all elements from B to A except the biggest one(s) on the bottom (here is the place where the counter comes handy to keep the number of already sorted elements in B)
- put element in T on the stack B
You can (and should) put all of it in a single loop, of course.
回答2:
This is really a two queue problem, since the rotate operations effectively turn a stack into a queue. In this case a bottom up merge sort can be performed, which would be relatively fast.
Using a linked list (instead of an array) to implement the stack / queue would speed up the rotates.
回答3:
Here is a solution in Java.
public class SortStack {
Stack<Integer> stack1;
Stack<Integer> stack2;
public Stack<Integer> sort(Stack<Integer> stack) {
this.stack1 = stack;
stack2 = new Stack<>();
putSmallestAtBottom();
empty2BackTo1();
return stack1;
}
private void putSmallestAtBottom() {
/*Pop a number from stack1
* Compare it top item in stack2
* If stack2 item is bigger, move it stack1
* Keep doing this
* Once thats done push that smaller num to stack 2
* Keep repeating until stack 1 is empty*/
while (stack1.isEmpty() == false) {
int num = stack1.pop();
while (stack2.isEmpty() == false && stack2.peek() > num) {
stack1.push(stack2.pop());
}
stack2.push(num);
}
}
private void empty2BackTo1() {
while (stack2.isEmpty() == false) {
stack1.push(stack2.pop());
}
}
}
来源:https://stackoverflow.com/questions/38164849/sorting-a-stack-in-ascending-order-in-c-using-two-stacks