使用两个堆栈在C中按升序对堆栈进行排序

时间:2016-07-02 22:04:46

标签: c sorting

我被赋予了一个任务,即使用两个堆栈aa按升序对整数堆栈b中的数字进行排序。

使用11个操作:

  1. sa swap a - 交换堆栈顶部的前2个元素a
  2. sb swap b - 交换堆栈b顶部的前2个元素。
  3. ss sasb同时。
  4. pa push a - 获取b顶部的第一个元素,并将其放在a的顶部。
  5. pb push b - 获取a顶部的第一个元素,并将其放在b的顶部。
  6. ra rotate a - 将堆栈a的所有元素向上移动1.第一个元素变为 最后一个。
  7. rb rotate b - 将堆栈b的所有元素向上移动1.第一个元素变为 最后一个。
  8. rr rarb同时。
  9. rra :反向rotate a - 将堆栈a的所有元素向下移动1.最后一个元素 成为第一个。
  10. rrb :reverse rotate b - 将堆栈b的所有元素向下移动1.最后一个元素 成为第一个。
  11. rrr rrarrb同时进行。
  12. 我的排序功能

    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);
        }
    }
    

    我的函数对堆栈进行排序,我认为排序需要太多步骤。我需要有关如何使用较少的步骤对堆栈进行排序的建议或建议。 complete online code

3 个答案:

答案 0 :(得分:1)

给出两个堆栈A和B,其中A用元素的随机排列填充而B是空的,并且一个临时变量T能够容纳一个元素(和一个计数器,但计数器不计数)你可以按升序将A按升序排序为B:

  1. 将所有元素从A移动到B,但保留T
  2. 中的最大元素
  3. 将所有元素从B移动到A
  4. 将元素放入堆栈B中的T
  5. 循环直到A为空
    1. 将所有元素从A移动到B,但保留T
    2. 中的最大元素
    3. 将所有元素从B移动到A除了底部最大的元素(这里是计数器方便的地方,以便将已经排序的元素的数量保存在B中)
    4. 将元素放入堆栈B中的T
  6. 当然,你可以(并且应该)把所有这些都放在一个循环中。

答案 1 :(得分:0)

这实际上是一个双队列问题,因为旋转操作有效地将堆栈转换为队列。在这种情况下,可以执行自下而上的合并排序,这将相对较快。

使用链表(而不是数组)来实现堆栈/队列可以加快旋转速度。

答案 2 :(得分:0)

这是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());
        }
    }    
}