Реалізуйте стек за допомогою двох черг


143

Аналогічне питання було поставлене раніше там , але питання тут протилежний його, використовуючи дві черги в стеці. Питання...

З огляду на дві черги з їх стандартними операціями ( enqueue, dequeue, isempty, size), реалізувати стек з його стандартними операціями ( pop, push, isempty, size).

Повинно бути дві версії рішення.

  • Версія A : Стек повинен бути ефективним при натисканні на предмет; і
  • Версія B : Стек повинен бути ефективним при появі елемента.

Мене алгоритм цікавить більше, ніж будь-які конкретні мовні реалізації. Однак я вітаю рішення, висловлені на мовах, які я знайомий (,,,,,).


6
Звичайно, це! CLRS - 10,1-6 ( tinyurl.com/clrs-ex-10-1-6 )
чемпіон

1
Один стек, дві черги дає елегантне рішення, коли Popпрацює в $ O (1) $ і Pushпрацює в $ O (\ sqrt {n}) $ амортизований час.
hengxin

1
@rampion Тепер його CLRS - 10.1-7. :)
nsane

Пов’язана публікація. Це одна інша цікава задача для реалізації стека , використовуючи тільки один черзі тут .
RBT

Відповіді:


194

Версія A (ефективний поштовх):

  • поштовх:
    • анкетування в черзі1
  • поп:
    • в той час як розмір черги1 більший за 1, елементи, які виводяться з труби, виводяться з черги1 у чергу2
    • видаліть і поверніть останній елемент черги1, а потім перемкніть імена черги1 та черги2

Версія B (ефективна попса):

  • поштовх:
    • анкету в черзі2
    • залиште всі елементи queue1 у queue2, а потім перемкніть імена queue1 та queue2
  • поп:
    • deqeue з черги1

4
Здається, що у версії B є проблеми: ти маєш на увазі підписати всі елементи queue2 до queue1, окрім останнього елемента (потім переключити імена q1 та q2)?
Icerman

Коментар Icerman для мене має сенс. Версія B відповіді потребує редагування. У мене немає дозволів на редагування. Може хтось, будь ласка, відредагував цю відповідь?
eeerahul

2
@eeerahul: Я ще раз перевірив це, і відповідь правильна. У той час, коли Icerman, схоже, хоче передати всі елементи queue2 у queue1, queue2 складається лише з нового елемента, тому коментар не має сенсу.
Svante

Чи правда версія? натиснути 1, натиснути 2, натиснути 3, натиснути 4. поп 4. натиснути 5, натиснути 6, натиснути 7, натиснути 8. поп 8. поп 7. Схоже, що алгоритм буде вискакувати 3 замість 7. Ваш алгоритм здається правильним Перший погляд, тому що ми, можливо, можемо пояснити так: в основному ви завжди будете вискакувати останній елемент, що додається в черзі 1. Але це останній елемент, який виштовхується, лише якщо ви вийшли з черги раніше. Якщо ви вискакували кілька разів поспіль, це не повинно бути правдою.
user127.0.0.1

1
@ user127.0.0.1: Схоже, ви забули переключити черги в кінці кожного спливаючого вікна. Існує інваріант, що після кожного натискання та кожного виклику всі елементи знаходяться у черзі1, а черга2 порожня.
Svante

68

Найпростіший (і, можливо, єдиний) спосіб зробити це - натиснувши нові елементи в порожню чергу, а потім відпустити інший і ввімкнути в попередньо порожню чергу. Таким чином останній час завжди знаходиться на передній частині черги. Це була б версія B, для версії A ви просто поверніть процес, відклавши елементи у другу чергу, за винятком останньої.

Крок 0:

"Stack"
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
|   |   |   |   |   |  |   |   |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

Крок 1:

"Stack"
+---+---+---+---+---+
| 1 |   |   |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
| 1 |   |   |   |   |  |   |   |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

Крок 2:

"Stack"
+---+---+---+---+---+
| 2 | 1 |   |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
|   |   |   |   |   |  | 2 | 1 |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

Крок 3:

"Stack"
+---+---+---+---+---+
| 3 | 2 | 1 |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
| 3 | 2 | 1 |   |   |  |   |   |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

1
Логіка для цього не має жодного сенсу. Перейдіть від кроку 2 до кроку 3. Коли я "натискаю" 3, як я можу розміщувати елементи в черзі B таким чином, щоб отримати 3 2 1 у черзі A? Якщо я припиняю B, щоб заперечувати A, я можу отримати лише елементи в порядку 2, 1. Якщо я потім додаю 3, я отримаю замовлення 3, 1, 2. Якщо я поставив спочатку натискання, а потім декеювати / затримати, я отримаю 1, 2, 3.
tsurantino

чому б не зробити операцію deque дорогою, ніж зробити дорогу операцію?
Divij Sehgal

49

Ми можемо це зробити однією чергою:

поштовх:

  1. нові елементи.
  2. Якщо nкількість елементів у черзі, то видаліть і вставіть елементи елементів n-1.

поп:

  1. декуе

.

push 1


front                     
+----+----+----+----+----+----+
| 1  |    |    |    |    |    |    insert 1
+----+----+----+----+----+----+


push2

front                     
+----+----+----+----+----+----+
| 1  | 2  |    |    |    |    |    insert 2
+----+----+----+----+----+----+

     front                     
+----+----+----+----+----+----+
|    | 2  |  1 |    |    |    |    remove and insert 1
+----+----+----+----+----+----+




 insert 3


      front                     
+----+----+----+----+----+----+
|    | 2  |  1 |  3 |    |    |    insert 3
+----+----+----+----+----+----+

           front                     
+----+----+----+----+----+----+
|    |    |  1 |  3 |  2 |    |    remove and insert 2
+----+----+----+----+----+----+

                front                     
+----+----+----+----+----+----+
|    |    |    |  3 |  2 |  1 |    remove and insert 1
+----+----+----+----+----+----+

Реалізація зразка:

int stack_pop (queue_data *q)
{
  return queue_remove (q);
}

void stack_push (queue_data *q, int val)
{
  int old_count = queue_get_element_count (q), i;

  queue_insert (q, val);
  for (i=0; i<old_count; i++)
  {
    queue_insert (q, queue_remove (q));
  }
}

9
import java.util.*;

/**
 *
 * @author Mahmood
 */
public class StackImplUsingQueues {

    Queue<Integer> q1 = new LinkedList<Integer>();
    Queue<Integer> q2 = new LinkedList<Integer>();

    public int pop() {
        if (q1.peek() == null) {
            System.out.println("The stack is empty, nothing to return");
            int i = 0;
            return i;
        } else {
            int pop = q1.remove();
            return pop;
        }
    }

    public void push(int data) {

        if (q1.peek() == null) {
            q1.add(data);
        } else {
            for (int i = q1.size(); i > 0; i--) {
                q2.add(q1.remove());
            }
            q1.add(data);
            for (int j = q2.size(); j > 0; j--) {
                q1.add(q2.remove());
            }

        }
    }

    public static void main(String[] args) {
        StackImplUsingQueues s1 = new StackImplUsingQueues();
        //       Stack s1 = new Stack();
        s1.push(1);
        s1.push(2);
        s1.push(3);
        s1.push(4);
        s1.push(5);
        s1.push(6);
        s1.push(7);
        s1.push(8);
        s1.push(9);
        s1.push(10);
        // s1.push(6);
        System.out.println("1st = " + s1.pop());
        System.out.println("2nd = " + s1.pop());
        System.out.println("3rd = " + s1.pop());
        System.out.println("4th = " + s1.pop());
        System.out.println("5th = " + s1.pop());
        System.out.println("6th = " + s1.pop());
        System.out.println("7th = " + s1.pop());
        System.out.println("8th = " + s1.pop());
        System.out.println("9th = " + s1.pop());
        System.out.println("10th= " + s1.pop());
    }
}

Чи може хтось пояснити вхід за методом push у наведеному вище коді? Наскільки я зрозумів, перший для циклу - це видалення всіх елементів у q2, поки в q1 не залишиться один елемент. Будь ласка, виправте мене, якщо я помиляюся.
Іван

4

Чи можемо ми просто використати одну чергу для реалізації стека? Я можу використовувати дві черги, але врахування однієї черги було б більш ефективним. Ось код:

    public void Push(T val)
    {
        queLower.Enqueue(val);
    }

    public  T Pop()
    {

        if (queLower.Count == 0 )
        {
            Console.Write("Stack is empty!");
            return default(T);

         }
        if (queLower.Count > 0)
        {
            for (int i = 0; i < queLower.Count - 1;i++ )
            {
                queLower.Enqueue(queLower.Dequeue ());
           }
                    }

        return queLower.Dequeue();

    }

Я думаю, що у pop-методі умова циклу має бути i <queLower.Count - 2, коли ви ініціалізуєте змінну i з 0.
vignesh

3
queue<int> q1, q2;
int i = 0;

void push(int v) {
  if( q1.empty() && q2.empty() ) {
     q1.push(v);
     i = 0;
  }
  else {
     if( i == 0 ) {
        while( !q1.empty() ) q2.push(q1.pop());
        q1.push(v);
        i = 1-i;
     }
     else {
        while( !q2.empty() ) q1.push(q2.pop());
        q2.push(v);
        i = 1-i;
     }
  }
}

int pop() {
   if( q1.empty() && q2.empty() ) return -1;
   if( i == 1 ) {
      if( !q1.empty() )
           return q1.pop();
      else if( !q2.empty() )
           return q2.pop();
   }
   else {
      if( !q2.empty() )
           return q2.pop();
      else if( !q1.empty() )
           return q1.pop();
   }
}

2

Ось моя відповідь - де 'поп' неефективний. Здається, що всі алгоритми, які відразу приходять на розум, мають складність N, де N - це розмір списку: чи ви вирішили виконувати роботу над 'pop' або працювати над 'push'

Алгоритм, у якому списки торгуються назад і по-четверте, може бути кращим, оскільки розрахунок розміру не потрібен, хоча вам все одно потрібно циклічно і порівняти з порожнім.

ви можете довести, що цей алгоритм не може бути записаний швидше N, зазначивши, що інформація про останній елемент у черзі доступна лише завдяки знанню розміру черги, і що ви повинні знищити дані, щоб дістатися до цього елемента, отже, 2-а черга .

Єдиний спосіб зробити це швидше - не використовувати черги в першу чергу.

from data_structures import queue

class stack(object):
    def __init__(self):
        q1= queue 
        q2= queue #only contains one item at most. a temp var. (bad?)

    def push(self, item):
        q1.enque(item) #just stick it in the first queue.

    #Pop is inefficient
    def pop(self):
        #'spin' the queues until q1 is ready to pop the right value. 
        for N 0 to self.size-1
            q2.enqueue(q1.dequeue)
            q1.enqueue(q2.dequeue)
        return q1.dequeue()

    @property
    def size(self):
        return q1.size + q2.size

    @property
    def isempty(self):
        if self.size > 0:
           return True
        else
           return False

2

Ось моє рішення, яке працює в середньому випадку для O (1). Є дві черги: inі out. Дивіться псевдокод нижче:

PUSH(X) = in.enqueue(X)

POP: X =
  if (out.isEmpty and !in.isEmpty)
    DUMP(in, out)
  return out.dequeue

DUMP(A, B) =
  if (!A.isEmpty)
    x = A.dequeue()
    DUMP(A, B)
    B.enqueue(x)

2
Там ви використовуєте 2 черги та 1 стек для імітації 1 стека!
BeniBela

Ви маєте на увазі імплікаційний стек рекурсії?
Володимир Костюков

1

Як уже зазначалося, чи не зробить жодної черги трюк? Це, мабуть, менш практично, але трохи стрункіше.

push(x):
enqueue(x)
for(queueSize - 1)
   enqueue(dequeue())

pop(x):
dequeue()

1

Ось простий псевдокод, push - O (n), pop / peek - O (1):

Qpush = Qinstance()
Qpop = Qinstance()

def stack.push(item):
    Qpush.add(item)
    while Qpop.peek() != null: //transfer Qpop into Qpush
        Qpush.add(Qpop.remove()) 
    swap = Qpush
    Qpush = Qpop
    Qpop = swap

def stack.pop():
    return Qpop.remove()

def stack.peek():
    return Qpop.peek()

1

Нехай S1 і S2 є двома стеками, які будуть використовуватися при реалізації черг.

struct Stack 
{ struct Queue *Q1;
  struct Queue *Q2;
}

Ми впевнені, що одна черга завжди порожня.

Натискання: Незалежно від того, яка черга не порожня, вставте в неї елемент.

  • Перевірте, чи порожня черга Q1 чи ні. Якщо Q1 порожній, тоді замовте елемент у ньому.
  • Інакше EnQueue елемент у Q1.

Push (struct Stack *S, int data) { if(isEmptyQueue(S->Q1) EnQueue(S->Q2, data); else EnQueue(S->Q1, data); }

Час складності: O (1)

Поп-операція: Перенесіть n-1 елементи на іншу чергу та видаліть останні з черги для виконання поп-операції.

  • Якщо черга Q1 не порожня, тоді перенесіть n-1 елементів з Q1 в Q2, а потім, DeQueue останнього елемента Q1 і поверніть його.
  • Якщо черга Q2 не порожня, тоді перенесіть n-1 елементів з Q2 в Q1, а потім, DeQueue останній елемент Q2 і поверніть його.

`

int Pop(struct Stack *S){
int i, size;
if(IsEmptyQueue(S->Q2)) 
{
size=size(S->Q1);
i=0;
while(i<size-1)
{ EnQueue(S->Q2, Dequeue(S->Q1)) ;
  i++;
}
return DeQueue(S->Q1);  
}
else{
size=size(S->Q2);
while(i<size-1)
EnQueue(S->Q1, Dequeue(S->Q2)) ;
i++;
}
return DeQueue(S->Q2);
} }

Складність часу: Час запуску поп-операції дорівнює O (n), оскільки кожен раз, коли викликається поп, ми переносимо всі елементи з однієї черги на іншу.


1
Q1 = [10, 15, 20, 25, 30]
Q2 = []

exp:
{   
    dequeue n-1 element from Q1 and enqueue into Q2: Q2 == [10, 15, 20, 25]

    now Q1 dequeue gives "30" that inserted last and working as stack
}

swap Q1 and Q2 then GOTO exp

1
import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    Queue<Integer> queue1 = new LinkedList<Integer>();
    Queue<Integer> queue2 = new LinkedList<Integer>();

    // Push element x onto stack.
    public void push(int x) {
        if(isEmpty()){
            queue1.offer(x);
        }else{
            if(queue1.size()>0){
                queue2.offer(x);
                int size = queue1.size();
                while(size>0){
                    queue2.offer(queue1.poll());
                    size--;
                }
            }else if(queue2.size()>0){
                queue1.offer(x);
                int size = queue2.size();
                while(size>0){
                    queue1.offer(queue2.poll());
                    size--;
                }
            }
        }
    }

    // Removes the element on top of the stack.
    public void pop() {
        if(queue1.size()>0){
            queue1.poll();
        }else if(queue2.size()>0){
            queue2.poll();
        }
    }

    // Get the top element. You can make it more perfect just example
    public int top() {
       if(queue1.size()>0){
            return queue1.peek();
        }else if(queue2.size()>0){
            return queue2.peek();
        }
        return 0;
    }

    // Return whether the stack is empty.
    public boolean isEmpty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

0

Ось ще одне рішення:

для PUSH: -Додайте перший елемент у чергу 1. -При додаванні другого елемента тощо, спочатку запитайте елемент у чергу 2, а потім скопіюйте увесь елемент із черги 1 у чергу2. -для POP просто видаліть елемент із черги, з якого ви вставили останній елемент.

Так,

public void push(int data){
if (queue1.isEmpty()){
    queue1.enqueue(data);
}  else {
queue2.enqueue(data);
while(!queue1.isEmpty())
Queue2.enqueue(queue1.dequeue());
//EXCHANGE THE NAMES OF QUEUE 1 and QUEUE2

}}

public int pop(){
int popItem=queue2.dequeue();
return popItem;
}'

Є одна проблема, я не в змозі розібратися, як перейменувати черги ???


0
#include <bits/stdc++.h>
using namespace std;
queue<int>Q;
stack<int>Stk;
void PRINT(stack<int>ss , queue<int>qq) {
    while( ss.size() ) {
        cout << ss.top() << " " ;
        ss.pop();
    }
    puts("");
    while( qq.size() ) {
        cout << qq.front() << " " ;
        qq.pop();
    }
    puts("\n----------------------------------");
}
void POP() {
    queue<int>Tmp ;
    while( Q.size() > 1 ) {
        Tmp.push( Q.front()  );
        Q.pop();
    }
    cout << Q.front() << " " << Stk.top() << endl;
    Q.pop() , Stk.pop() ;
    Q = Tmp ;
}
void PUSH(int x ) {
    Q.push(x);
    Stk.push(x);
}
int main() {
    while( true ) {
        string typ ;
        cin >> typ ;
        if( typ == "push" ) {
            int x ;
            cin >> x;
            PUSH(x);
        } else POP();
        PRINT(Stk,Q);
    }
}

1
Будь ласка, кілька слів, що пояснюють, про що йдеться у цьому коді, і як ця річ здатна допомогти ОП у вирішенні своєї проблеми, будуть дуже вдячні разом із прикладом коду :-)
nIcE cOw

0

Код Python, використовуючи лише одну чергу

 class Queue(object):
    def __init__(self):
        self.items=[]
    def enqueue(self,item):
        self.items.insert(0,item)
    def dequeue(self):
        if(not self.isEmpty()):
            return  self.items.pop()
    def isEmpty(self):
        return  self.items==[]
    def size(self):
        return len(self.items)



class stack(object):
        def __init__(self):
            self.q1= Queue()


        def push(self, item):
            self.q1.enqueue(item) 


        def pop(self):
            c=self.q1.size()
            while(c>1):
                self.q1.enqueue(self.q1.dequeue())
                c-=1
            return self.q1.dequeue()



        def size(self):
            return self.q1.size() 


        def isempty(self):
            if self.size > 0:
               return True
            else:
               return False

1
Будь ласка, намагайтеся уникати просто скидання коду як відповіді та спробуйте пояснити, що це робить і чому. Ваш код може бути не очевидним для людей, які не мають відповідного досвіду кодування.
Фріц

0

ось повний робочий код в c #:

Він реалізований за допомогою єдиної черги,

поштовх:

1. add new element.
2. Remove elements from Queue (totalsize-1) times and add back to the Queue

поп:

normal remove





 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace StackImplimentationUsingQueue
    {
        class Program
        {
            public class Node
            {
                public int data;
                public Node link;
            }
            public class Queue
            {
                public Node rear;
                public Node front;
                public int size = 0;
                public void EnQueue(int data)
                {
                    Node n = new Node();
                    n.data = data;
                    n.link = null;
                    if (rear == null)
                        front = rear = n;
                    else
                    {
                        rear.link = n;
                        rear = n;
                    }
                    size++;
                    Display();
                }
                public Node DeQueue()
                {
                    Node temp = new Node();
                    if (front == null)
                        Console.WriteLine("Empty");
                    else
                    {
                        temp = front;
                        front = front.link;
                        size--;
                    }
                    Display();
                    return temp;
                }
                public void Display()
                {
                    if (size == 0)
                        Console.WriteLine("Empty");
                    else
                    {
                        Console.Clear();
                        Node n = front;
                        while (n != null)
                        {
                            Console.WriteLine(n.data);
                            n = n.link;
                        }
                    }
                }
            }
            public class Stack
            {
                public Queue q;
                public int size = 0;
                public Node top;
                public Stack()
                {
                    q = new Queue();
                }
                public void Push(int data)
                {
                    Node n = new Node();
                    n.data = data;
                    q.EnQueue(data);
                    size++;
                    int counter = size;
                    while (counter > 1)
                    {
                        q.EnQueue(q.DeQueue().data);
                        counter--;
                    }
                }
                public void Pop()
                {
                    q.DeQueue();
                    size--;
                }
            }
            static void Main(string[] args)
            {
                Stack s= new Stack();
                for (int i = 1; i <= 3; i++)
                    s.Push(i);
                for (int i = 1; i < 3; i++)
                    s.Pop();
                Console.ReadKey();
            }
        }
    }

Не можете коментувати (очікуваний / амортизований) час, необхідний вашою реалізацією, як функцію елементів, що зберігаються в даний час / сума натискань і вискакувань?
сіра борода

0

Ось дуже просте рішення, яке використовує одну чергу і надає такі функції, як Stack.

public class CustomStack<T>
{
    Queue<T> que = new Queue<T>();

    public void push(T t) // STACK = LIFO / QUEUE = FIFO
    {

        if( que.Count == 0)
        {
            que.Enqueue(t);
        }
        else
        {
            que.Enqueue(t);
            for (int i = 0; i < que.Count-1; i++)
            {
                var data = que.Dequeue();

                que.Enqueue(data);
            }
        }

    }

    public void pop()
    {

        Console.WriteLine("\nStack Implementation:");
        foreach (var item in que)
        {
            Console.Write("\n" + item.ToString() + "\t");
        }

        var data = que.Dequeue();
        Console.Write("\n Dequeing :" + data);
    }

    public void top()
    {

        Console.Write("\n Top :" + que.Peek());
    }


}

Тож у вищевказаному класі під назвою "CustomStack" те, що я роблю, - це просто перевірка черги на порожню, якщо порожня, тоді вставити одну, а потім підопічні вставити, а потім видалити вставку. За цією логікою спочатку прийде останнє. Приклад: У чергу я вставив 1 і зараз намагаюся вставити 2. Вдруге видаліть 1 і знову вставити, щоб він став у зворотному порядку.

Дякую.


0

Нижче представлено дуже просте рішення Java, яке ефективно підтримує функцію push.

Алгоритм -

  1. Оголосіть дві черги q1 і q2.

  2. Операція натискання - елемент запиту до черги q1.

  3. Поп-операція - переконайтеся, що черга q2 не порожня. Якщо він порожній, то видаліть усі елементи з q1, окрім останнього, і додайте його до q2 один за одним. Видаліть останній елемент від q1 і збережіть його як елемент, що вискочив. Поміняйте місцями черги q1 і q2. Повернути збережений вискакуваний елемент.

  4. Операція "Peek" - переконайтеся, що черга q2 не порожня. Якщо він порожній, то видаліть усі елементи з q1, окрім останнього, і додайте його до q2 один за одним. Видаліть останній елемент від q1 і збережіть його як підглянутий елемент. Поверніть її назад до черги q2 і поміняйте черги q1 і q2. Повернути збережений підглянутий елемент.

Нижче наведений код для вищезгаданого алгоритму -

class MyStack {

    java.util.Queue<Integer> q1;
    java.util.Queue<Integer> q2;
    int SIZE = 0;

    /** Initialize your data structure here. */
    public MyStack() {
        q1 = new LinkedList<Integer>();
        q2 = new LinkedList<Integer>();

    }

    /** Push element x onto stack. */
    public void push(int x) {
        q1.add(x);
        SIZE ++;

    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        ensureQ2IsNotEmpty();
        int poppedEle = q1.remove();
        SIZE--;
        swapQueues();
        return poppedEle;
    }

    /** Get the top element. */
    public int top() {
        ensureQ2IsNotEmpty();
        int peekedEle = q1.remove();
        q2.add(peekedEle);
        swapQueues();
        return peekedEle;
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return q1.isEmpty() && q2.isEmpty();

    }

    /** move all elements from q1 to q2 except last element */
    public void ensureQ2IsNotEmpty() {
        for(int i=0; i<SIZE-1; i++) {
            q2.add(q1.remove());
        }
    }

    /** Swap queues q1 and q2 */
    public void swapQueues() {
        Queue<Integer> temp = q1;
        q1 = q2;
        q2 = temp;
    }
}

-1

Ось моє рішення ..

Concept_Behind :: push(struct Stack* S,int data):: Ця функція передбачає перший елемент у Q1 та інший у Q2 pop(struct Stack* S) :: якщо Q2 не порожній, переносить усі елеми у Q1 та повертає останній елем у Q2 інше (що означає, що Q2 порожній) передає всі елеми у Q2 та повертає останній елем у Q1

Efficiency_Behind :: push(struct Stack*S,int data):: O (1) // з часу єдиного запиту на дані pop(struct Stack* S):: O (n) // з моменту передачі найгірших даних n-1 за поп.

#include<stdio.h>
#include<stdlib.h>
struct Queue{
    int front;
    int rear;
    int *arr;
    int size;
    };
struct Stack {
    struct Queue *Q1;
    struct Queue *Q2;
    };
struct Queue* Qconstructor(int capacity)
{
    struct Queue *Q=malloc(sizeof(struct Queue));
    Q->front=Q->rear=-1;
    Q->size=capacity;
    Q->arr=malloc(Q->size*sizeof(int));
    return Q;
    }
int isEmptyQueue(struct Queue *Q)
{
    return (Q->front==-1);
    }
int isFullQueue(struct Queue *Q)
{
    return ((Q->rear+1) % Q->size ==Q->front);
    }
void enqueue(struct Queue *Q,int data)
{
    if(isFullQueue(Q))
        {
            printf("Queue overflow\n");
            return;}
    Q->rear=Q->rear+1 % Q->size;
    Q->arr[Q->rear]=data;
    if(Q->front==-1)
        Q->front=Q->rear;
        }
int dequeue(struct Queue *Q)
{
    if(isEmptyQueue(Q)){
        printf("Queue underflow\n");
        return;
        }
    int data=Q->arr[Q->front];
    if(Q->front==Q->rear)
        Q->front=-1;
    else
    Q->front=Q->front+1 % Q->size;
    return data;
    }
///////////////////////*************main algo****************////////////////////////
struct Stack* Sconstructor(int capacity)
{
    struct Stack *S=malloc(sizeof(struct Stack));
    S->Q1=Qconstructor(capacity);
    S->Q2=Qconstructor(capacity);
    return S;
}
void push(struct Stack *S,int data)
{
    if(isEmptyQueue(S->Q1))
        enqueue(S->Q1,data);
    else
        enqueue(S->Q2,data);
    }
int pop(struct Stack *S)
{
    int i,tmp;
    if(!isEmptyQueue(S->Q2)){
        for(i=S->Q2->front;i<=S->Q2->rear;i++){
            tmp=dequeue(S->Q2);
            if(isEmptyQueue(S->Q2))
                return tmp;
            else
                enqueue(S->Q1,tmp);
                }
            }
    else{
        for(i=S->Q1->front;i<=S->Q1->rear;i++){
            tmp=dequeue(S->Q1);
            if(isEmptyQueue(S->Q1))
                return tmp;
            else
                enqueue(S->Q2,tmp);
                }
            }
        }
////////////////*************end of main algo my algo************
///////////////*************push() O(1);;;;pop() O(n);;;;*******/////
main()
{
    int size;
    printf("Enter the number of elements in the Stack(made of 2 queue's)::\n");
    scanf("%d",&size);
    struct Stack *S=Sconstructor(size);
    push(S,1);
    push(S,2);
    push(S,3);
    push(S,4);
    printf("%d\n",pop(S));
    push(S,5);
    printf("%d\n",pop(S));
    printf("%d\n",pop(S));
    printf("%d\n",pop(S));
    printf("%d\n",pop(S));
    }

-1
import java.util.LinkedList;
import java.util.Queue;


public class StackQueue {

    static Queue<Integer> Q1 = new LinkedList<Integer>();
    static Queue<Integer> Q2 = new LinkedList<Integer>();
    public static void main(String args[]) {



        push(24);
        push(34);
        push(4);
        push(10);
        push(1);
        push(43);
        push(21);
        System.out.println("Popped element is  "+pop());
        System.out.println("Popped element is  "+pop());
        System.out.println("Popped element is  "+pop());


    }

    public static void push(int data) {

        Q1.add(data);

    }

    public static int pop() {

        if(Q1.isEmpty()) {
        System.out.println("Cannot pop elements ,  Stack is Empty !!"); 
        return -1;
        }
        else
        {
        while(Q1.size() > 1) {
            Q2.add(Q1.remove());
        }
        int element = Q1.remove();
        Queue<Integer> temp = new LinkedList<Integer>();
        temp = Q1;
        Q1 = Q2;
        Q2 = temp;
        return element;
        }
    }
}

Список, пов’язаний з Java, функціонує як декес просто чудово. Ця відповідь не має сенсу.
dfeuer

-1
#include "stdio.h"
#include "stdlib.h"

typedef struct {
    int *q;
    int size;
    int front;
    int rear;
} Queue;
typedef struct {
    Queue *q1;
    Queue *q2;
} Stack;

int queueIsEmpty(Queue *q) {
    if (q->front == -1 && q->rear == -1) {
        printf("\nQUEUE is EMPTY\n");
        return 1;
    }
    return 0;
}
int queueIsFull(Queue *q) {
    if (q->rear == q->size-1) {
        return 1;
    }
    return 0;
}
int queueTop(Queue *q) {
    if (queueIsEmpty(q)) {
        return -1;
    }
    return q->q[q->front];
}
int queuePop(Queue *q) {
    if (queueIsEmpty(q)) {
        return -1;
    }
    int item = q->q[q->front];
    if (q->front == q->rear) {
        q->front = q->rear = -1;
    }
    else {
        q->front++;
    }
    return item;
}
void queuePush(Queue *q, int val) {
    if (queueIsFull(q)) {
        printf("\nQUEUE is FULL\n");
        return;
    }
    if (queueIsEmpty(q)) {
        q->front++;
        q->rear++;
    } else {
        q->rear++;
    }
    q->q[q->rear] = val;
}
Queue *queueCreate(int maxSize) {
    Queue *q = (Queue*)malloc(sizeof(Queue));
    q->front = q->rear = -1;
    q->size = maxSize;
    q->q = (int*)malloc(sizeof(int)*maxSize);
    return q;
}
/* Create a stack */
void stackCreate(Stack *stack, int maxSize) {
    Stack **s = (Stack**) stack;
    *s = (Stack*)malloc(sizeof(Stack));
    (*s)->q1 = queueCreate(maxSize);
    (*s)->q2 = queueCreate(maxSize);
}

/* Push element x onto stack */
void stackPush(Stack *stack, int element) {
    Stack **s = (Stack**) stack;
    queuePush((*s)->q2, element);
    while (!queueIsEmpty((*s)->q1)) {
        int item = queuePop((*s)->q1);
        queuePush((*s)->q2, item);
    }
    Queue *tmp = (*s)->q1;
    (*s)->q1 = (*s)->q2;
    (*s)->q2 = tmp;
}

/* Removes the element on top of the stack */
void stackPop(Stack *stack) {
    Stack **s = (Stack**) stack;
    queuePop((*s)->q1);
}

/* Get the top element */
int stackTop(Stack *stack) {
    Stack **s = (Stack**) stack;
    if (!queueIsEmpty((*s)->q1)) {
      return queueTop((*s)->q1);
    }
    return -1;
}

/* Return whether the stack is empty */
bool stackEmpty(Stack *stack) {
    Stack **s = (Stack**) stack;
    if (queueIsEmpty((*s)->q1)) {
        return true;
    }
    return false;
}

/* Destroy the stack */
void stackDestroy(Stack *stack) {
    Stack **s = (Stack**) stack;
    free((*s)->q1);
    free((*s)->q2);
    free((*s));
}

int main()
{
  Stack *s = NULL;
  stackCreate((Stack*)&s, 10);
  stackPush((Stack*)&s, 44);
  //stackPop((Stack*)&s);
  printf("\n%d", stackTop((Stack*)&s));
  stackDestroy((Stack*)&s);
  return 0;
}

Стіна коду без коментарів чи пояснень - це погана відповідь.
Річард
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.