दो ढेर का उपयोग करके एक कतार कैसे लागू करें?


394

मान लीजिए कि हमारे पास दो ढेर हैं और कोई अन्य अस्थायी चर नहीं है।

क्या केवल दो स्टैक का उपयोग करके एक कतार डेटा संरचना का "निर्माण" करना संभव है?

जवाबों:


701

2 ढेर रखो, चलो उन्हें बुलाओ inboxऔर outbox

एन्क्यू :

  • नए तत्व को चालू करें inbox

घटाव :

  • यदि outboxखाली है, तो प्रत्येक तत्व को पॉपिंग करके inboxऔर उस पर पुश करके इसे फिर से भरेंoutbox

  • पॉप और शीर्ष तत्व से लौटें outbox

इस पद्धति का उपयोग करते हुए, प्रत्येक तत्व प्रत्येक स्टैक में एक बार ठीक होगा - मतलब प्रत्येक तत्व को दो बार धकेल दिया जाएगा और दो बार पॉपअप किया जाएगा, जिससे लगातार स्थिर संचालन होता है।

यहाँ जावा में एक कार्यान्वयन है:

public class Queue<E>
{

    private Stack<E> inbox = new Stack<E>();
    private Stack<E> outbox = new Stack<E>();

    public void queue(E item) {
        inbox.push(item);
    }

    public E dequeue() {
        if (outbox.isEmpty()) {
            while (!inbox.isEmpty()) {
               outbox.push(inbox.pop());
            }
        }
        return outbox.pop();
    }

}

13
सबसे खराब स्थिति समय जटिलता अभी भी ओ (एन) है। मैं यह कहने के लिए कायम हूं क्योंकि मुझे आशा है कि कोई भी छात्र वहां से बाहर नहीं आएगा (यह होमवर्क / शैक्षिक प्रश्न जैसा लगता है) लगता है कि यह एक कतार को लागू करने का एक स्वीकार्य तरीका है।
टायलर

26
यह सच है कि एकल पॉप ऑपरेशन के लिए सबसे खराब समय ओ (एन) (जहां एन कतार का वर्तमान आकार है) है। हालांकि, n कतार संचालन के अनुक्रम के लिए सबसे खराब समय भी O (n) है, जिससे हमें लगातार समय दिया जाता है। मैं इस तरह से एक कतार लागू नहीं करेगा, लेकिन यह उतना बुरा नहीं है।
डेव एल।

1
@ टायलर यदि आपका स्टैक सरणी आधारित है, जैसा कि अधिकांश हैं, तो आपको हमेशा एकल ऑपरेशन के लिए ओ (एन) सबसे खराब स्थिति मिलेगी।
थॉमस अहले

2
@Tyler: चेक sgi.com/tech/stl/Deque.html । "तत्वों के लिए यादृच्छिक अभिगम" का समर्थन करता है। इसलिए दोनों deque और स्टैक सरणी आधारित हैं। ऐसा इसलिए है क्योंकि यह आपको संदर्भ का बेहतर स्थान देता है और इसलिए अभ्यास में तेज है।
थॉमस अहले

13
@ न्यूटैंग ए) कतार 1,2,3 => इनबॉक्स [3,2,1] / आउटबॉक्स [] । b) छलावा। आउटबॉक्स खाली है, इसलिए Refill => इनबॉक्स [] / आउटबॉक्स [1,2,3] । आउटबॉक्स से पॉप, 1 => लौटें इनबॉक्स [] / आउटबॉक्स [2,3] वापस करें । c) कतार 4,5 => इनबॉक्स [5,4] / आउटबॉक्स [2,3] । घ) धोखा। आउटबॉक्स खाली नहीं है, इसलिए आउटबॉक्स से पॉप, 2 => इनबॉक्स [5,4] / आउटबॉक्स [3] वापस करें । क्या यह ज़्यादा सही लगता है?
डेव एल।

226

ए - कैसे एक रिवर्स रिवर्स करने के लिए

दो ढेर का उपयोग करके एक कतार का निर्माण कैसे करें, यह समझने के लिए, आपको यह समझना चाहिए कि स्टैक क्रिस्टल को कैसे उल्टा करना है। याद रखें कि स्टैक कैसे काम करता है, यह आपके रसोई घर के डिश स्टैक के समान है। अंतिम धुला हुआ पकवान साफ ​​ढेर के शीर्ष पर होगा, जिसे कंप्यूटर विज्ञान में L ast I n F irst O ut (LIFO) कहा जाता है।

नीचे दिए गए बोतल की तरह हमारे ढेर की कल्पना करें;

यहां छवि विवरण दर्ज करें

यदि हम क्रमशः पूर्णांक 1,2,3 को धक्का देते हैं, तो 3 स्टैक के शीर्ष पर होगा। क्योंकि 1 को पहले धकेला जाएगा, फिर 2 को 1 के शीर्ष पर रखा जाएगा। अंत में, 3 को स्टैक के शीर्ष पर रखा जाएगा और एक बोतल के रूप में दर्शाए गए हमारे स्टैक की नवीनतम स्थिति नीचे दी जाएगी;

यहां छवि विवरण दर्ज करें

अब हमारे पास एक स्टैक के रूप में प्रतिनिधित्व किया गया है, जिसकी कीमत 3,2,1 है। और हम स्टैक को उल्टा करना चाहते हैं ताकि स्टैक का शीर्ष तत्व 1 होगा और स्टैक का निचला तत्व 3 होगा। हम क्या कर सकते हैं? हम बोतल ले सकते हैं और इसे उल्टा पकड़ सकते हैं ताकि सभी मूल्य क्रम में उलट जाएं?

यहां छवि विवरण दर्ज करें

हाँ हम ऐसा कर सकते हैं, लेकिन यह एक बोतल है। उसी प्रक्रिया को करने के लिए, हमें एक दूसरा स्टैक रखना होगा जो कि पहले स्टैक तत्वों को रिवर्स ऑर्डर में स्टोर करने वाला है। चलो हमारे आबादी वाले स्टैक को बाईं ओर और हमारे नए खाली स्टैक को दाईं ओर रखें। तत्वों के क्रम को उल्टा करने के लिए, हम प्रत्येक तत्व को बाएं स्टैक से पॉप करने जा रहे हैं, और उन्हें सही स्टैक पर धकेलेंगे। आप देख सकते हैं कि जैसा हम नीचे की छवि पर करते हैं वैसा ही होता है;

यहां छवि विवरण दर्ज करें

तो हम जानते हैं कि स्टैक को कैसे उल्टा करना है।

बी - एक कतार के रूप में दो ढेर का उपयोग करना

पिछले भाग पर, मैंने समझाया है कि हम स्टैक तत्वों के क्रम को कैसे उलट सकते हैं। यह महत्वपूर्ण था, क्योंकि अगर हम स्टैक में पॉप तत्वों को धक्का देते हैं, तो आउटपुट बिल्कुल एक कतार के रिवर्स ऑर्डर में होगा। एक उदाहरण पर विचार करते हुए, पूर्णांक के सरणी {1, 2, 3, 4, 5}को एक स्टैक पर ले जाते हैं। यदि हम तत्वों को पॉप करते हैं और उन्हें तब तक प्रिंट करते हैं जब तक कि स्टैक खाली नहीं हो जाता है, तो हमें ऑर्डर को पुश करने के रिवर्स ऑर्डर में सरणी मिलेगी, जो कि होगी{5, 4, 3, 2, 1} कि एक ही इनपुट के लिए याद , यदि हम कतार को खाली करने तक कतार में खाली करते हैं, तो आउटपुट हो जाएगा {1, 2, 3, 4, 5}। तो यह स्पष्ट है कि तत्वों के समान इनपुट ऑर्डर के लिए, कतार का आउटपुट स्टैक के आउटपुट के बिल्कुल विपरीत है। जैसा कि हम जानते हैं कि अतिरिक्त स्टैक का उपयोग करके एक स्टैक को कैसे रिवर्स किया जाता है, हम दो स्टैक का उपयोग करके एक कतार का निर्माण कर सकते हैं।

हमारे कतार मॉडल में दो ढेर होंगे। एक स्टैक के लिए इस्तेमाल किया जाएगाenqueue ऑपरेशन के (बाईं ओर स्टैक # 1, इनपुट स्टैक के रूप में कहा जाएगा), dequeueऑपरेशन के लिए एक और स्टैक का उपयोग किया जाएगा (दाईं ओर स्टैक # 2, आउटपुट स्टैक के रूप में कहा जाएगा)। नीचे की छवि देखें;

यहां छवि विवरण दर्ज करें

हमारा छद्म कोड नीचे है;


एनकाउंटर ऑपरेशन

Push every input element to the Input Stack

Dequeue ऑपरेशन

If ( Output Stack is Empty)
    pop every element in the Input Stack
    and push them to the Output Stack until Input Stack is Empty

pop from Output Stack

आइए {1, 2, 3}क्रमशः पूर्णांकों की गणना करें । इंटेगर को इनपुट स्टैक ( स्टैक # 1 ) पर धकेल दिया जाएगा जो बाईं ओर स्थित है;

यहां छवि विवरण दर्ज करें

तब क्या होगा जब हम एक dequeue कार्रवाई को अंजाम देंगे? जब भी किसी डॉक्यू ऑपरेशन को निष्पादित किया जाता है, तो यह जांचने के लिए कतार में जा रहा है कि आउटपुट स्टैक खाली है या नहीं (ऊपर छद्म कोड देखें) यदि आउटपुट स्टैक खाली है, तो आउटपुट पर इनपुट स्टैक को निकाला जाएगा इनपुट स्टैक का उल्टा होगा। एक मूल्य वापस करने से पहले, कतार की स्थिति नीचे के रूप में होगी;

यहां छवि विवरण दर्ज करें

आउटपुट स्टैक (स्टैक # 2) में तत्वों के क्रम को देखें। यह स्पष्ट है कि हम आउटपुट स्टैक से तत्वों को पॉप कर सकते हैं ताकि आउटपुट वैसा ही हो जैसे कि हम एक कतार से हट गए। इस प्रकार, यदि हम दो dequeue संचालन निष्पादित करते हैं, तो पहले हम {1, 2}क्रमशः प्राप्त करेंगे । तब तत्व 3 आउटपुट स्टैक का एकमात्र तत्व होगा, और इनपुट स्टैक खाली होगा। यदि हम तत्वों 4 और 5 को शामिल करते हैं, तो कतार की स्थिति निम्नानुसार होगी;

यहां छवि विवरण दर्ज करें

अब आउटपुट स्टैक खाली नहीं है, और यदि हम एक dequeue कार्रवाई निष्पादित करते हैं, तो केवल 3 आउटपुट स्टैक से पॉप आउट हो जाएगा। तब राज्य नीचे के रूप में देखा जाएगा;

यहां छवि विवरण दर्ज करें

फिर, अगर हम दो और अधिक dequeue संचालन को निष्पादित करते हैं, तो पहले dequeue कार्रवाई पर, आउटपुट स्टैक खाली है, जो सत्य है, तो कतार जाँच करेगी। फिर इनपुट स्टैक के तत्वों को पॉप आउट करें और उन्हें आउटपुट स्टैक पर धकेल दें जब तक इनपुट स्टैक खाली न हो जाए, तब कतार की स्थिति नीचे होगी;

यहां छवि विवरण दर्ज करें

देखना आसान है, दो dequeue संचालन का उत्पादन होगा {4, 5}

सी - दो ढेर के साथ निर्मित कतार का कार्यान्वयन

यहाँ जावा में एक कार्यान्वयन है। मैं स्टैक के मौजूदा कार्यान्वयन का उपयोग नहीं करने जा रहा हूं, इसलिए यहां उदाहरण पहिया को सुदृढ़ करने जा रहा है;

C - 1) MyStack वर्ग: एक साधारण स्टैक कार्यान्वयन

public class MyStack<T> {

    // inner generic Node class
    private class Node<T> {
        T data;
        Node<T> next;

        public Node(T data) {
            this.data = data;
        }
    }

    private Node<T> head;
    private int size;

    public void push(T e) {
        Node<T> newElem = new Node(e);

        if(head == null) {
            head = newElem;
        } else {
            newElem.next = head;
            head = newElem;     // new elem on the top of the stack
        }

        size++;
    }

    public T pop() {
        if(head == null)
            return null;

        T elem = head.data;
        head = head.next;   // top of the stack is head.next

        size--;

        return elem;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void printStack() {
        System.out.print("Stack: ");

        if(size == 0)
            System.out.print("Empty !");
        else
            for(Node<T> temp = head; temp != null; temp = temp.next)
                System.out.printf("%s ", temp.data);

        System.out.printf("\n");
    }
}

सी - 2) MyQueue वर्ग: दो स्टैक का उपयोग करके कतार कार्यान्वयन

public class MyQueue<T> {

    private MyStack<T> inputStack;      // for enqueue
    private MyStack<T> outputStack;     // for dequeue
    private int size;

    public MyQueue() {
        inputStack = new MyStack<>();
        outputStack = new MyStack<>();
    }

    public void enqueue(T e) {
        inputStack.push(e);
        size++;
    }

    public T dequeue() {
        // fill out all the Input if output stack is empty
        if(outputStack.isEmpty())
            while(!inputStack.isEmpty())
                outputStack.push(inputStack.pop());

        T temp = null;
        if(!outputStack.isEmpty()) {
            temp = outputStack.pop();
            size--;
        }

        return temp;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

}

C - 3) डेमो कोड

public class TestMyQueue {

    public static void main(String[] args) {
        MyQueue<Integer> queue = new MyQueue<>();

        // enqueue integers 1..3
        for(int i = 1; i <= 3; i++)
            queue.enqueue(i);

        // execute 2 dequeue operations 
        for(int i = 0; i < 2; i++)
            System.out.println("Dequeued: " + queue.dequeue());

        // enqueue integers 4..5
        for(int i = 4; i <= 5; i++)
            queue.enqueue(i);

        // dequeue the rest
        while(!queue.isEmpty())
            System.out.println("Dequeued: " + queue.dequeue());
    }

}

C - 4) नमूना आउटपुट

Dequeued: 1
Dequeued: 2
Dequeued: 3
Dequeued: 4
Dequeued: 5

18
अगर मैं कर सकता तो मैं इसे पूरे दिन +1 करता। मैं यह समझ नहीं पा रहा था कि यह निरंतर समय को कैसे परिचालित करता है। आपके चित्रों ने वास्तव में चीजों को साफ कर दिया, विशेष रूप से आउटपुट स्टैक पर शेष तत्वों को छोड़ने का हिस्सा, और केवल खाली होने पर फिर से भरना।
शेन मैकक्विलन

1
इससे मुझे पॉप के दौरान होने वाली टाइमआउट त्रुटियों को रोकने में मदद मिली। मैं मूल स्टैक में तत्वों को वापस रख रहा था लेकिन ऐसा करने की कोई आवश्यकता नहीं थी। कुडोस!
प्रणीत बंकर

2
सभी टिप्पणियों को एक के बाद एक मॉडल किया जाना चाहिए।
लोलोलोल ओल

4
मुझे वास्तव में इसके लिए एक समाधान की आवश्यकता नहीं थी, बस ब्राउज़िंग ... लेकिन जब मुझे इस तरह का उत्तर दिखाई देता है तो मैं बस प्यार में पड़ जाता हूँ .. शानदार जवाब !!!
मनमौजी

80

तुम भी केवल एक ढेर का उपयोग कर एक कतार अनुकरण कर सकते हैं। दूसरी (अस्थायी) स्टैक को पुनरावृत्ति कॉल के कॉल स्टैक द्वारा सम्मिलित विधि से जोड़ा जा सकता है।

नया तत्व कतार में डालने पर सिद्धांत समान रहता है:

  • आपको अपने ऑर्डर को उलटने के लिए तत्वों को एक स्टैक से दूसरे अस्थायी स्टैक में स्थानांतरित करना होगा।
  • फिर अस्थायी स्टैक पर, नए तत्व को सम्मिलित करने के लिए धक्का दें
  • फिर तत्वों को मूल ढेर में वापस स्थानांतरित करें
  • नया तत्व स्टैक के तल पर होगा, और सबसे पुराना तत्व शीर्ष पर है (पहले पॉपअप किया जाएगा)

केवल एक स्टैक का उपयोग कर एक कतार वर्ग निम्नानुसार होगा:

public class SimulatedQueue<E> {
    private java.util.Stack<E> stack = new java.util.Stack<E>();

    public void insert(E elem) {
        if (!stack.empty()) {
            E topElem = stack.pop();
            insert(elem);
            stack.push(topElem);
        }
        else
            stack.push(elem);
    }

    public E remove() {
        return stack.pop();
    }
}

51
हो सकता है कि कोड सुरुचिपूर्ण लग रहा हो, लेकिन यह बहुत अक्षम (O (n ** 2) सम्मिलित है) और इसमें अभी भी दो ढेर हैं, एक ढेर में और एक कॉल स्टैक में, जैसा कि @pythonquick बताते हैं। गैर-पुनरावर्ती एल्गोरिथ्म के लिए, आप हमेशा पुनरावृत्ति का समर्थन करने वाली भाषाओं में कॉल स्टैक से एक "अतिरिक्त" स्टैक को पकड़ सकते हैं।
एंटि हुइमा

1
@ antti.huima और क्या आप बताएंगे कि यह द्विघात आवेषण कैसे हो सकता है ?! मैं जो समझता हूं, उससे n पॉप और एन पुश ऑपरेशन करता है, इसलिए यह पूरी तरह से रैखिक O (n) एल्गोरिथ्म है।
एलपी_

1
@LP_ यह n itemsउपरोक्त डेटा संरचना का उपयोग करके कतार में डालने के लिए द्विघात समय O (n ^ 2) लेता है । में योग का (1 + 2 + 4 + 8 + .... + 2(n-1))परिणाम है ~O(n^2)। मुझे उम्मीद है कि आपको बात मिल जाएगी।
अंकित कुमार

1
@ antti.huima आप इंसर्ट फंक्शन की जटिलता के बारे में बात कर रहे थे (आपने कहा था "O (n 2) इन्सर्ट" - आपका मतलब "O (n 2) fill") था। सम्मेलन द्वारा , "जटिलता सम्मिलित करें" एक सम्मिलन का समय है, जो यहां पहले से मौजूद तत्वों की संख्या में रैखिक है। अगर हम n आइटम सम्मिलित करने के लिए आवश्यक समय में बात करते हैं , तो हम कहेंगे कि हैशटेबल में रेखीय आवेषण है। जो मामला न हो।
LP_

2
आप मूल रूप से स्टैक का उपयोग कर रहे हैं, स्टैक के रूप में। इसका मतलब है कि यदि बड़ी संख्या में आइटम स्टैक में हैं, तो आप स्टैक ओवरफ्लो के साथ समाप्त हो सकते हैं - यह लगभग उसी तरह है जैसे इस साइट के लिए समाधान तैयार किया गया था!
UKMonkey

11

हालांकि समय की जटिलताएं बदतर होंगी। एक अच्छी कतार कार्यान्वयन निरंतर समय में सब कुछ करता है।

संपादित करें

यकीन नहीं होता कि मेरा जवाब यहां क्यों दिया गया। यदि हम कार्यक्रम करते हैं, तो हम समय की जटिलता के बारे में परवाह करते हैं, और कतार बनाने के लिए दो मानक स्टैक का उपयोग करना अक्षम है। यह एक बहुत ही मान्य और प्रासंगिक बिंदु है। अगर किसी और को इसे और कम करने की आवश्यकता महसूस होती है, तो मुझे यह जानने में दिलचस्पी होगी कि क्यों।

थोड़ा और विस्तार : दो स्टैक्स का उपयोग करने पर यह केवल एक कतार से भी बदतर है: यदि आप दो स्टैक का उपयोग करते हैं, और कोई व्यक्ति डॉक्यू को कॉल करता है जबकि आउटबॉक्स खाली है, तो आपको इनबॉक्स के निचले भाग में जाने के लिए रैखिक समय की आवश्यकता होती है (जैसा कि आप देख सकते हैं) डेव के कोड में)।

आप एक कतार को एक एकल-लिंक्ड सूची के रूप में लागू कर सकते हैं (प्रत्येक तत्व अगले सम्मिलित तत्व के लिए), पुश के लिए अंतिम सम्मिलित तत्व के लिए एक अतिरिक्त सूचक रखते हुए (या इसे एक चक्रीय सूची बनाते हैं)। इस डेटा संरचना पर कतार और विकृति को लागू करना निरंतर समय में करना बहुत आसान है। यह सबसे बुरा मामला है, लगातार समय नहीं। और, जैसा कि टिप्पणियां इस स्पष्टीकरण के लिए पूछती हैं, सबसे खराब स्थिति निरंतर समय amortized निरंतर समय की तुलना में कड़ाई से बेहतर है।


औसत मामले में नहीं। ब्रायन के उत्तर में एक कतार का वर्णन किया गया है, जिसमें निरंतर एन्क्यू और डीक्यू ऑपरेशनों को परिचालित किया जाएगा।
डैनियल स्पिवक

यह सच है। आपके पास औसत मामला है और समय जटिलता समान है। लेकिन डिफ़ॉल्ट आमतौर पर प्रति-ऑपरेशन सबसे खराब स्थिति है, और यह O (n) है जहां n संरचना का वर्तमान आकार है।
टायलर

1
सबसे खराब स्थिति को भी परिशोधन किया जा सकता है। उदाहरण के लिए, परिवर्तनशील गतिशील सरणियों (वैक्टर) को आमतौर पर निरंतर सम्मिलन का समय माना जाता है, भले ही हर बार एक महंगी आकार बदलने और कॉपी ऑपरेशन की आवश्यकता होती है।
डैनियल स्पाइवाक

1
"सबसे खराब स्थिति" और "परिशोधन" दो अलग-अलग प्रकार की समय जटिलताएं हैं। यह कहने का कोई मतलब नहीं है कि "सबसे बुरी स्थिति को परिशोधन किया जा सकता है" - यदि आप सबसे खराब स्थिति = परिशोधन कर सकते हैं, तो यह एक महत्वपूर्ण सुधार होगा; आप बिना किसी औसत के साथ सबसे खराब स्थिति के बारे में बात करेंगे।
टायलर

मुझे यकीन नहीं है कि आप ओ (1) सबसे खराब स्थिति में ओ (1) औसत मामले और ओ (एन) सबसे खराब स्थिति के संयोजन की तुलना में "सख्ती से बेहतर" होने का क्या मतलब है। लगातार स्केलिंग कारक मायने रखते हैं। एक डेटा संरचना, जिसमें यदि यह एन आइटम शामिल है, को एन माइक्रोसेकंड के समय में एन ऑपरेशन के बाद वापस करना पड़ सकता है, और अन्यथा प्रति ऑपरेशन एक माइक्रोसेकंड लेता है, प्रत्येक ऑपरेशन के लिए एक मिलीसेकंड लेने की तुलना में कहीं अधिक उपयोगी हो सकता है, यहां तक ​​कि यदि डेटा आकार लाखों आइटम तक विस्तृत हो जाएगा (इस प्रकार कि कुछ अलग-अलग संचालन में कई सेकंड लगेंगे)।
22

8

कतार को कार्यान्वित करने दें क्यू और स्टैक को लागू करने के लिए उपयोग किया जाता है स्टैक 1 और स्टैक 2।

q को दो में लागू किया जा सकता है तरीकों से है:

विधि 1 (enQueue ऑपरेशन महंगा करके)

यह विधि यह सुनिश्चित करती है कि नव प्रवेश किया गया तत्व हमेशा स्टैक 1 के शीर्ष पर होता है, जिससे कि डीक्यूयू ऑपरेशन केवल स्टैक 1 से पॉप हो जाता है। स्टैक 1 के शीर्ष पर तत्व डालने के लिए, स्टैक 2 का उपयोग किया जाता है।

enQueue(q, x)
1) While stack1 is not empty, push everything from stack1 to stack2.
2) Push x to stack1 (assuming size of stacks is unlimited).
3) Push everything back to stack1.
deQueue(q)
1) If stack1 is empty then error
2) Pop an item from stack1 and return it.

विधि 2 (डीक्यू ऑपरेशन महंगा करके)

इस विधि में, एन-कतार ऑपरेशन में, स्टैक 1 के शीर्ष पर नया तत्व दर्ज किया गया है। डी-कतार ऑपरेशन में, यदि स्टैक 2 खाली है तो सभी तत्वों को स्टैक 2 में ले जाया जाता है और अंत में स्टैक 2 के शीर्ष को वापस लौटा दिया जाता है।

enQueue(q,  x)
 1) Push x to stack1 (assuming size of stacks is unlimited).

deQueue(q)
 1) If both stacks are empty then error.
 2) If stack2 is empty
   While stack1 is not empty, push everything from stack1 to stack2.
 3) Pop the element from stack2 and return it.

विधि 2 निश्चित रूप से विधि 1 से बेहतर है। विधि 1 enQueue ऑपरेशन में दो बार सभी तत्वों को स्थानांतरित करता है, जबकि विधि 2 (deQueue ऑपरेशन में) तत्वों को एक बार स्थानांतरित करता है और तत्वों को केवल तभी स्थानांतरित करता है जब stack2 खाली हो।


आपकी विधि के अलावा जो भी समाधान मुझे समझ में नहीं आये हैं उनमें से कोई भी 2. मैं जिस तरह से आपको समझाता हूं वह आपको चरणों के साथ एन्क्यू और डीक्यू पद्धति से समझाता है।
theGreenCabbage


3

सी # में एक समाधान

public class Queue<T> where T : class
{
    private Stack<T> input = new Stack<T>();
    private Stack<T> output = new Stack<T>();
    public void Enqueue(T t)
    {
        input.Push(t);
    }

    public T Dequeue()
    {
        if (output.Count == 0)
        {
            while (input.Count != 0)
            {
                output.Push(input.Pop());
            }
        }

        return output.Pop();
    }
}

2

कतार में दो ढेर को stack1 और stack2 के रूप में परिभाषित किया गया है ।

एन्क्यू: यूरोपेड तत्वों को हमेशा स्टैक 1 में धकेल दिया जाता है

विपंक्ति: के शीर्ष stack2 पॉप आउट किया जा सकता है के बाद से यह पहला तत्व जब कतार में डाला है stack2 खाली नहीं है। जब स्टैक 2 खाली होता है, हम स्टैक 1 से सभी तत्वों को पॉप करते हैं और स्टैक 2 को एक-एक करके धक्का देते हैं । कतार में पहला तत्व स्टैक 1 के निचले भाग में धकेल दिया जाता है । यह स्टैक 2 के शीर्ष पर होने के बाद सीधे पॉपिंग और पुश अप ऑपरेशन के बाद पॉप आउट किया जा सकता है ।

निम्नलिखित समान C ++ नमूना कोड है:

template <typename T> class CQueue
{
public:
    CQueue(void);
    ~CQueue(void);

    void appendTail(const T& node); 
    T deleteHead();                 

private:
    stack<T> stack1;
    stack<T> stack2;
};

template<typename T> void CQueue<T>::appendTail(const T& element) {
    stack1.push(element);
} 

template<typename T> T CQueue<T>::deleteHead() {
    if(stack2.size()<= 0) {
        while(stack1.size()>0) {
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }


    if(stack2.size() == 0)
        throw new exception("queue is empty");


    T head = stack2.top();
    stack2.pop();


    return head;
}

यह समाधान मेरे ब्लॉग से उधार लिया गया है । चरण-दर-चरण संचालन सिमुलेशन के साथ अधिक विस्तृत विश्लेषण मेरे ब्लॉग वेबपेज में उपलब्ध है।


2

आपको नीचे के तत्व को प्राप्त करने के लिए पहले स्टैक से सब कुछ पॉप करना होगा। फिर उन सभी को हर "dequeue" ऑपरेशन के लिए दूसरे स्टैक पर वापस रखें।


3
हाँ आप सही है। मुझे आश्चर्य है, आपको इतने डाउन वोट कैसे मिले। मैंने आपके उत्तर को रद्द कर दिया है
बिनीता भारती

यह देखने के लिए डरावना है कि यह उसका आखिरी उत्तर था और तब से एक दशक है।
शानू गुप्ता

2

सी # डेवलपर के लिए यहां पूरा कार्यक्रम है:

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

namespace QueueImplimentationUsingStack
{
    class Program
    {
        public class Stack<T>
        {
            public int size;
            public Node<T> head;
            public void Push(T data)
            {
                Node<T> node = new Node<T>();
                node.data = data;
                if (head == null)
                    head = node;
                else
                {
                    node.link = head;
                    head = node;
                }
                size++;
                Display();
            }
            public Node<T> Pop()
            {
                if (head == null)
                    return null;
                else
                {
                    Node<T> temp = head;
                    //temp.link = null;
                    head = head.link;
                    size--;
                    Display();
                    return temp;
                }
            }
            public void Display()
            {
                if (size == 0)
                    Console.WriteLine("Empty");
                else
                {
                    Console.Clear();
                    Node<T> temp = head;
                    while (temp!= null)
                    {
                        Console.WriteLine(temp.data);
                        temp = temp.link;
                    }
                }
            }
        }

        public class Queue<T>
        {
            public int size;
            public Stack<T> inbox;
            public Stack<T> outbox;
            public Queue()
            {
                inbox = new Stack<T>();
                outbox = new Stack<T>();
            }
            public void EnQueue(T data)
            {
                inbox.Push(data);
                size++;
            }
            public Node<T> DeQueue()
            {
                if (outbox.size == 0)
                {
                    while (inbox.size != 0)
                    {
                        outbox.Push(inbox.Pop().data);
                    }
                }
                Node<T> temp = new Node<T>();
                if (outbox.size != 0)
                {
                    temp = outbox.Pop();
                    size--;
                }
                return temp;
            }

        }
        public class Node<T>
        {
            public T data;
            public Node<T> link;
        }

        static void Main(string[] args)
        {
            Queue<int> q = new Queue<int>();
            for (int i = 1; i <= 3; i++)
                q.EnQueue(i);
           // q.Display();
            for (int i = 1; i < 3; i++)
                q.DeQueue();
            //q.Display();
            Console.ReadKey();
        }
    }
}

2

स्टैक का उपयोग करके एक कतार के निम्नलिखित कार्यों को लागू करें।

धक्का (एक्स) - कतार के पीछे तत्व एक्स को पुश करें।

pop () - तत्व को कतार के सामने से हटाता है।

झांकना () - सामने वाला तत्व प्राप्त करें।

खाली () - वापसी चाहे कतार खाली हो।

यहां छवि विवरण दर्ज करें

class MyQueue {

  Stack<Integer> input;
  Stack<Integer> output;

  /** Initialize your data structure here. */
  public MyQueue() {
    input = new Stack<Integer>();
    output = new Stack<Integer>();
  }

  /** Push element x to the back of queue. */
  public void push(int x) {
    input.push(x);
  }

  /** Removes the element from in front of queue and returns that element. */
  public int pop() {
    peek();
    return output.pop();
  }

  /** Get the front element. */
  public int peek() {
    if(output.isEmpty()) {
        while(!input.isEmpty()) {
            output.push(input.pop());
        }
    }
    return output.peek();
  }

  /** Returns whether the queue is empty. */
  public boolean empty() {
    return input.isEmpty() && output.isEmpty();
  }
}

1
// Two stacks s1 Original and s2 as Temp one
    private Stack<Integer> s1 = new Stack<Integer>();
    private Stack<Integer> s2 = new Stack<Integer>();

    /*
     * Here we insert the data into the stack and if data all ready exist on
     * stack than we copy the entire stack s1 to s2 recursively and push the new
     * element data onto s1 and than again recursively call the s2 to pop on s1.
     * 
     * Note here we can use either way ie We can keep pushing on s1 and than
     * while popping we can remove the first element from s2 by copying
     * recursively the data and removing the first index element.
     */
    public void insert( int data )
    {
        if( s1.size() == 0 )
        {
            s1.push( data );
        }
        else
        {
            while( !s1.isEmpty() )
            {
                s2.push( s1.pop() );
            }
            s1.push( data );
            while( !s2.isEmpty() )
            {
                s1.push( s2.pop() );
            }
        }
    }

    public void remove()
    {
        if( s1.isEmpty() )
        {
            System.out.println( "Empty" );
        }
        else
        {
            s1.pop();

        }
    }

1

स्विफ्ट में दो स्टैक का उपयोग करके एक कतार का कार्यान्वयन:

struct Stack<Element> {
    var items = [Element]()

    var count : Int {
        return items.count
    }

    mutating func push(_ item: Element) {
        items.append(item)
    }

    mutating func pop() -> Element? {
        return items.removeLast()
    }

    func peek() -> Element? {
        return items.last
    }
}

struct Queue<Element> {
    var inStack = Stack<Element>()
    var outStack = Stack<Element>()

    mutating func enqueue(_ item: Element) {
        inStack.push(item)
    }

    mutating func dequeue() -> Element? {
        fillOutStack() 
        return outStack.pop()
    }

    mutating func peek() -> Element? {
        fillOutStack()
        return outStack.peek()
    }

    private mutating func fillOutStack() {
        if outStack.count == 0 {
            while inStack.count != 0 {
                outStack.push(inStack.pop()!)
            }
        }
    }
}

1

जबकि दो कतार के साथ एक कतार लागू करने से संबंधित आपको बहुत सारे पद मिलेंगे: 1. या तो enQueue प्रक्रिया को और अधिक महंगा बनाकर 2. या फिर deQueue प्रक्रिया को बहुत अधिक महंगा बनाकर

https://www.geeksforgeeks.org/queue-using-stacks/

उपरोक्त पोस्ट से मुझे पता चला कि एक महत्वपूर्ण तरीका केवल स्टैक डेटा संरचना और रिकर्सियन कॉल स्टैक के साथ कतार का निर्माण करना था।

जबकि कोई यह तर्क दे सकता है कि शाब्दिक रूप से यह अभी भी दो स्टैक का उपयोग कर रहा है, लेकिन तब आदर्श रूप से यह केवल एक स्टैक डेटा संरचना का उपयोग कर रहा है।

समस्या की व्याख्या नीचे दी गई है:

  1. डेटा को एनक्यूइंग और डीक्यूइंग करने के लिए एक ही स्टैक की घोषणा करें और डेटा को स्टैक में धकेलें।

  2. जबकि deQueueing की एक आधार स्थिति होती है, जहां स्टैक का आकार 1 होने पर स्टैक का तत्व पॉप होता है। यह सुनिश्चित करेगा कि डीक्यू रिकर्सन के दौरान स्टैक ओवरफ्लो न हो।

  3. जबकि सबसे पहले डेटा को स्टैक के शीर्ष से पॉप करें। आदर्श रूप से यह तत्व वह तत्व होगा जो स्टैक के शीर्ष पर मौजूद है। अब एक बार यह हो जाने के बाद, पुन: deQueue फ़ंक्शन को कॉल करें और फिर स्टैक में वापस ऊपर पॉप किए गए तत्व को पुश करें।

कोड नीचे की तरह दिखेगा:

if (s1.isEmpty())
System.out.println("The Queue is empty");
        else if (s1.size() == 1)
            return s1.pop();
        else {
            int x = s1.pop();
            int result = deQueue();
            s1.push(x);
            return result;

इस तरह आप एकल स्टैक डेटा संरचना और रिकर्सन कॉल स्टैक का उपयोग करके एक कतार बना सकते हैं।


1

नीचे ईएस 6 सिंटैक्स का उपयोग करके जावास्क्रिप्ट भाषा में समाधान है।

Stack.js

//stack using array
class Stack {
  constructor() {
    this.data = [];
  }

  push(data) {
    this.data.push(data);
  }

  pop() {
    return this.data.pop();
  }

  peek() {
    return this.data[this.data.length - 1];
  }

  size(){
    return this.data.length;
  }
}

export { Stack };

QueueUsingTwoStacks.js

import { Stack } from "./Stack";

class QueueUsingTwoStacks {
  constructor() {
    this.stack1 = new Stack();
    this.stack2 = new Stack();
  }

  enqueue(data) {
    this.stack1.push(data);
  }

  dequeue() {
    //if both stacks are empty, return undefined
    if (this.stack1.size() === 0 && this.stack2.size() === 0)
      return undefined;

    //if stack2 is empty, pop all elements from stack1 to stack2 till stack1 is empty
    if (this.stack2.size() === 0) {
      while (this.stack1.size() !== 0) {
        this.stack2.push(this.stack1.pop());
      }
    }

    //pop and return the element from stack 2
    return this.stack2.pop();
  }
}

export { QueueUsingTwoStacks };

नीचे उपयोग है:

index.js

import { StackUsingTwoQueues } from './StackUsingTwoQueues';

let que = new QueueUsingTwoStacks();
que.enqueue("A");
que.enqueue("B");
que.enqueue("C");

console.log(que.dequeue());  //output: "A"

यह बगिया है। यदि आप छल करने के बाद अधिक तत्वों की गणना करते हैं, तो आप उन्हें अंदर डाल देंगे stack1। जब आप dequeueफिर से जाते हैं, तो आप उन्हें आइटम में स्थानांतरित करेंगे stack2, जो पहले से ही वहां था।
अलेक्जेंडर - मोनिका

0

मैं इस प्रश्न का उत्तर Go में दूंगा क्योंकि Go के पास अपने मानक पुस्तकालय में बहुत सारे संग्रह नहीं हैं।

चूंकि एक स्टैक वास्तव में लागू करने के लिए आसान है मैंने सोचा कि मैं कोशिश करूँगा और दो स्टैक का उपयोग करके एक डबल समाप्त कतार को पूरा कर सकता हूं। यह समझने के लिए कि मैं अपने उत्तर में कैसे आया, मैंने कार्यान्वयन को दो भागों में विभाजित किया है, पहला भाग उम्मीद के मुताबिक समझने में आसान है लेकिन यह अधूरा है।

type IntQueue struct {
    front       []int
    back        []int
}

func (q *IntQueue) PushFront(v int) {
    q.front = append(q.front, v)
}

func (q *IntQueue) Front() int {
    if len(q.front) > 0 {
        return q.front[len(q.front)-1]
    } else {
        return q.back[0]
    }
}

func (q *IntQueue) PopFront() {
    if len(q.front) > 0 {
        q.front = q.front[:len(q.front)-1]
    } else {
        q.back = q.back[1:]
    }
}

func (q *IntQueue) PushBack(v int) {
    q.back = append(q.back, v)
}

func (q *IntQueue) Back() int {
    if len(q.back) > 0 {
        return q.back[len(q.back)-1]
    } else {
        return q.front[0]
    }
}

func (q *IntQueue) PopBack() {
    if len(q.back) > 0 {
        q.back = q.back[:len(q.back)-1]
    } else {
        q.front = q.front[1:]
    }
}

यह मूल रूप से दो स्टैक हैं जहां हम स्टैक के निचले हिस्से को एक-दूसरे द्वारा हेरफेर करने की अनुमति देते हैं। मैंने एसटीएल के नामकरण सम्मेलनों का भी उपयोग किया है, जहां पारंपरिक धक्का, पॉप, एक स्टैक के संचालन को सामने / पीछे उपसर्ग है चाहे वे कतार के सामने या पीछे देखें।

उपरोक्त कोड के साथ मुद्दा यह है कि यह बहुत कुशलता से मेमोरी का उपयोग नहीं करता है। वास्तव में, यह अंतहीन रूप से बढ़ता है जब तक आप अंतरिक्ष से बाहर नहीं भागते। यह वास्तव में बुरा है। इसके लिए तय यह है कि जब भी संभव हो, स्टैक स्पेस के निचले हिस्से का पुन: उपयोग करें। हमें इसे ट्रैक करने के लिए एक ऑफसेट शुरू करना होगा क्योंकि गो में एक स्लाइस एक बार सिकुड़ने के बाद सामने नहीं बढ़ सकता है।

type IntQueue struct {
    front       []int
    frontOffset int
    back        []int
    backOffset  int
}

func (q *IntQueue) PushFront(v int) {
    if q.backOffset > 0 {
        i := q.backOffset - 1
        q.back[i] = v
        q.backOffset = i
    } else {
        q.front = append(q.front, v)
    }
}

func (q *IntQueue) Front() int {
    if len(q.front) > 0 {
        return q.front[len(q.front)-1]
    } else {
        return q.back[q.backOffset]
    }
}

func (q *IntQueue) PopFront() {
    if len(q.front) > 0 {
        q.front = q.front[:len(q.front)-1]
    } else {
        if len(q.back) > 0 {
            q.backOffset++
        } else {
            panic("Cannot pop front of empty queue.")
        }
    }
}

func (q *IntQueue) PushBack(v int) {
    if q.frontOffset > 0 {
        i := q.frontOffset - 1
        q.front[i] = v
        q.frontOffset = i
    } else {
        q.back = append(q.back, v)
    }
}

func (q *IntQueue) Back() int {
    if len(q.back) > 0 {
        return q.back[len(q.back)-1]
    } else {
        return q.front[q.frontOffset]
    }
}

func (q *IntQueue) PopBack() {
    if len(q.back) > 0 {
        q.back = q.back[:len(q.back)-1]
    } else {
        if len(q.front) > 0 {
            q.frontOffset++
        } else {
            panic("Cannot pop back of empty queue.")
        }
    }
}

यह बहुत छोटे कार्य हैं, लेकिन 6 कार्यों में से 3 केवल दूसरे के दर्पण हैं।


आप यहाँ सरणियों का उपयोग कर रहे हैं। मैं नहीं देखता कि आपके ढेर कहां हैं।
melpomene

@melpomene ठीक है, यदि आप एक करीब से देखते हैं, तो आप देखेंगे कि केवल वही कार्य जो मैं कर रहा हूँ / जोड़ रहा हूँ / अंतिम तत्व को हटा रहा हूँ। दूसरे शब्दों में, धक्का और पॉपिंग। सभी इरादों और उद्देश्यों के लिए ये स्टैक हैं लेकिन सरणियों का उपयोग करके कार्यान्वित किया जाता है।
बजे जॉन लेडिग्रेन

@melpomene वास्तव में, यह केवल आधा ही सही है, मैं मान रहा हूं कि दोगुने स्टैक हैं। मैं स्टैक को कुछ शर्तों के तहत नीचे से गैर मानक तरीके से संशोधित करने की अनुमति दे रहा हूं।
जॉन लीडग्रेन

0

यहाँ मेरे समाधान में java लिंक्डलिस्ट का उपयोग कर रहा है।

class queue<T>{
static class Node<T>{
    private T data;
    private Node<T> next;
    Node(T data){
        this.data = data;
        next = null;
    }
}
Node firstTop;
Node secondTop;

void push(T data){
    Node temp = new Node(data);
    temp.next = firstTop;
    firstTop = temp;
}

void pop(){
    if(firstTop == null){
        return;
    }
    Node temp = firstTop;
    while(temp != null){
        Node temp1 = new Node(temp.data);
        temp1.next = secondTop;
        secondTop = temp1;
        temp = temp.next;
    }
    secondTop = secondTop.next;
    firstTop = null;
    while(secondTop != null){
        Node temp3 = new Node(secondTop.data);
        temp3.next = firstTop;
        firstTop = temp3;
        secondTop = secondTop.next;
    }
}

}

नोट: इस मामले में, पॉप ऑपरेशन में बहुत समय लगता है। इसलिए मैं दो स्टैक का उपयोग करके एक कतार बनाने का सुझाव नहीं दूंगा।


0

के साथ O(1) dequeue(), जो अजगर के उत्तर के समान है :

// time: O(n), space: O(n)
enqueue(x):
    if stack.isEmpty():
        stack.push(x)
        return
    temp = stack.pop()
    enqueue(x)
    stack.push(temp)

// time: O(1)
x dequeue():
    return stack.pop()

इसके साथ O(1) enqueue()(इस पोस्ट में इसका उल्लेख नहीं किया गया है इसलिए यह उत्तर), जो बैटरकॉस्ट आइटम को वापस बुलबुला करने और वापस करने के लिए भी उपयोग करता है।

// O(1)
enqueue(x):
    stack.push(x)

// time: O(n), space: O(n)
x dequeue():
    temp = stack.pop()
    if stack.isEmpty():
        x = temp
    else:
        x = dequeue()
        stack.push(temp)
    return x

जाहिर है, यह एक अच्छा कोडिंग अभ्यास है क्योंकि यह अक्षम लेकिन सुरुचिपूर्ण है।


0

** आसान जेएस समाधान **

  • नोट: मैंने अन्य लोगों की टिप्पणियों से विचार लिया

/*

enQueue(q,  x)
 1) Push x to stack1 (assuming size of stacks is unlimited).

deQueue(q)
 1) If both stacks are empty then error.
 2) If stack2 is empty
   While stack1 is not empty, push everything from stack1 to stack2.
 3) Pop the element from stack2 and return it.

*/
class myQueue {
    constructor() {
        this.stack1 = [];
        this.stack2 = [];
    }

    push(item) {
        this.stack1.push(item)
    }

    remove() {
        if (this.stack1.length == 0 && this.stack2.length == 0) {
            return "Stack are empty"
        }

        if (this.stack2.length == 0) {

            while (this.stack1.length != 0) {
                this.stack2.push(this.stack1.pop())
            }
        }
        return this.stack2.pop()
    }


    peek() {
        if (this.stack2.length == 0 && this.stack1.length == 0) {
            return 'Empty list'
        }

        if (this.stack2.length == 0) {
            while (this.stack1.length != 0) {
                this.stack2.push(this.stack1.pop())
            }
        }

        return this.stack2[0]
    }

    isEmpty() {
        return this.stack2.length === 0 && this.stack1.length === 0;
    }

}

const q = new myQueue();
q.push(1);
q.push(2);
q.push(3);
q.remove()

console.log(q)


-1
public class QueueUsingStacks<T>
{
    private LinkedListStack<T> stack1;
    private LinkedListStack<T> stack2;

    public QueueUsingStacks()
    {
        stack1=new LinkedListStack<T>();
        stack2 = new LinkedListStack<T>();

    }
    public void Copy(LinkedListStack<T> source,LinkedListStack<T> dest )
    {
        while(source.Head!=null)
        {
            dest.Push(source.Head.Data);
            source.Head = source.Head.Next;
        }
    }
    public void Enqueue(T entry)
    {

       stack1.Push(entry);
    }
    public T Dequeue()
    {
        T obj;
        if (stack2 != null)
        {
            Copy(stack1, stack2);
             obj = stack2.Pop();
            Copy(stack2, stack1);
        }
        else
        {
            throw new Exception("Stack is empty");
        }
        return obj;
    }

    public void Display()
    {
        stack1.Display();
    }


}

प्रत्येक एन्क्यू ऑपरेशन के लिए, हम स्टैक 1 के शीर्ष पर जोड़ते हैं। प्रत्येक डैक्यू के लिए, हम स्टैक 1 की सामग्री को स्टैक 2 में खाली करते हैं, और स्टैक के शीर्ष पर मौजूद तत्व को हटाते हैं। डीक्यू के लिए समय की जटिलता हे (एन) है, क्योंकि हमें स्टैक 1 को स्टैक 2 में कॉपी करना होगा। एन्क्यू की समय जटिलता एक नियमित स्टैक के समान है


यह कोड अकुशल (अनावश्यक नकल) है और टूटा हुआ है: if (stack2 != null)हमेशा सही होता है क्योंकि stack2कंस्ट्रक्टर में तुरंत दिया जाता है।
melpomene

-2

दो java.util.Stack ऑब्जेक्ट का उपयोग करके कतार कार्यान्वयन:

public final class QueueUsingStacks<E> {

        private final Stack<E> iStack = new Stack<>();
        private final Stack<E> oStack = new Stack<>();

        public void enqueue(E e) {
            iStack.push(e);
        }

        public E dequeue() {
            if (oStack.isEmpty()) {
                if (iStack.isEmpty()) {
                    throw new NoSuchElementException("No elements present in Queue");
                }
                while (!iStack.isEmpty()) {
                    oStack.push(iStack.pop());
                }
            }
            return oStack.pop();
        }

        public boolean isEmpty() {
            if (oStack.isEmpty() && iStack.isEmpty()) {
                return true;
            }
            return false;
        }

        public int size() {
            return iStack.size() + oStack.size();
        }

}

3
यह कोड कार्यात्मक रूप से डेव एल द्वारा उत्तर के समान है। इसमें कोई नई बात नहीं है, स्पष्टीकरण भी नहीं।
melpomene

यह बुनियादी अपवाद हैंडलिंग के साथ-साथ खाली () और आकार () विधियों को जोड़ता है। मैं स्पष्टीकरण जोड़ने के लिए संपादित करूंगा।
realPK

1
किसी ने उन अतिरिक्त तरीकों के लिए नहीं पूछा, और वे तुच्छ हैं (प्रत्येक पंक्ति एक): return inbox.isEmpty() && outbox.isEmpty()और return inbox.size() + outbox.size(), क्रमशः। डेव एल का कोड पहले से ही एक अपवाद फेंकता है जब आप एक खाली कतार से हटते हैं। मूल प्रश्न जावा के बारे में भी नहीं था; यह सामान्य रूप से डेटा संरचनाओं / एल्गोरिदम के बारे में था। जावा कार्यान्वयन सिर्फ एक अतिरिक्त चित्रण था।
17

1
यह उन लोगों के लिए एक महान स्रोत है जो यह समझने की कोशिश कर रहे हैं कि दो स्टैक से कतार का निर्माण कैसे किया जाए, डायग्राम ने निश्चित रूप से डेव के उत्तर को पढ़ने से अधिक मेरी मदद की।
केमल टीज़र दिल्सीज़

@melpomene: इसकी विधियों के तुच्छ होने की जरूरत नहीं है। जावा में कतार इंटरफ़ेस संग्रह इंटरफ़ेस से उन विधियों का विस्तार करता है क्योंकि उनकी आवश्यकता होती है।
realPK
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.