📜  如何创建可合并堆栈?

📅  最后修改于: 2022-05-13 01:57:09.219000             🧑  作者: Mango

如何创建可合并堆栈?

设计具有以下操作的堆栈。

a) push(Stack s, x):将项目 x 添加到堆栈 s
b) pop(Stack s):从栈 s 中移除顶部项目
c) merge(Stack s1, Stack s2):将 s2 的内容合并到 s1 中。

以上所有操作的时间复杂度应为 O(1)。
如果我们使用堆栈的数组实现,则无法在 O(1) 时间内进行合并,因为我们必须执行以下步骤。
a) 删除旧数组。
b) 为 s1 创建一个新数组,其大小等于 s1 的旧数组的大小加上 s2 的大小。
c) 将 s1 和 s2 的旧内容复制到 s1 的新数组中
上述操作需要 O(n) 时间。

我们可以使用带有两个指针的链表,一个指向第一个节点的指针(当从头开始添加和删除元素时也用作顶部)。最后一个节点需要另一个指针,这样我们就可以在 s1 的末尾快速链接 s2 的链表。以下是所有操作。
a) push():使用第一个指针将新项添加到链表的开头。
b) pop():使用第一个指针从开头删除一个项目。
c) merge():将第一个指针第二个堆栈链接为第一个列表的最后一个指针的下一个。
如果我们不允许使用额外的指针,我们可以这样做吗?
我们可以用循环链表来做到这一点。这个想法是跟踪链表中的最后一个节点。最后一个节点的下一个表示堆栈的顶部。
a) push():将新项目添加为最后一个节点的下一个。

上述代码如下:

C++
#include 
using namespace std;
 
class node {
public:
    int data;
    node* next;
};
 
class mystack {
public:
    node* head;
    node* tail;
 
    mystack()
    {
        head = NULL;
        tail = NULL;
    }
};
 
mystack* create()
{
    mystack* ms = new mystack(); // creating a new stack
    return ms;
}
 
void push(int data, mystack* ms)
{
    node* temp = new node();
    temp->data = data;
    temp->next = ms->head;
 
    // when pushing first element in the stack the tail
    // must be pointed by that first element
    if (ms->head == NULL)
        ms->tail = temp;
     
    ms->head = temp;
}
 
int pop(mystack* ms)
{
    if (ms->head == NULL) {
        cout << "stack underflow" << endl;
        return 0;
    }
    else {
        node* temp = ms->head;
        ms->head = ms->head->next;
        int popped = temp->data;
        delete temp;
        return popped;
    }
}
 
// making the next pointer of tail of
// one stack point to other stack
void merge(mystack* ms1, mystack* ms2)
{
if (ms1->head == NULL)
{
    ms1->head = ms2->head;
    ms1->tail = ms2->tail;
    return;
}
     
ms1->tail->next = ms2->head;
ms1->tail = ms2->tail;
}
 
void display(mystack* ms)
{
    node* temp = ms->head;
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
}
 
int main()
{
    mystack* ms1 = create();
    mystack* ms2 = create();
 
    push(6, ms1);
    push(5, ms1);
    push(4, ms1);
    push(9, ms2);
    push(8, ms2);
    push(7, ms2);
    merge(ms1, ms2);
    display(ms1);
}
 
// This code is contributed by jayshmi


Java
import java.io.*;
 
// The class Node contains the
// structure of our Node of
// the linked list
class Node
{
    Node next;
    Node prev;
    int data;
     
    // Create a node with the
    // given value
    Node(int value)
    {
        data = value;
        next = null;
        prev = null;
    }
}
 
class Stack{
     
private Node head;
private Node tail;
 
// Initialize stack class
// with its head and tail as null
Stack()
{
    head = null;
    tail = null;
}
 
public void push(int value)
{
    Node newNode = new Node(value);
    if(head == null)
    {
        head = newNode;
        head.next=null;
        head.prev = null;
        tail = newNode;
    }
    else
    {
        newNode.prev = tail;
        tail.next = newNode;
        tail = newNode;
    }
}
 
public void pop()
{
    if(head == null)
        System.out.println("stack underflow");
     
    if(head == tail)
    {
        head = null;
        tail = null;
    }
    else
    {
        Node n = tail;
        tail = tail.prev;
        n.prev = null;
        tail.next = null;
    }
}
 
public void merge(Stack s)
{
    head.prev = s.tail;
    s.tail.next = head;
    head = s.head;
    s.tail = null;
    s.head = null;
}
 
public void display()
{
    if(tail != null)
    {
        Node n = tail;
        while(n != null)
        {
            System.out.print(n.data + " ");
            n = n.prev;
        }
        System.out.println();
    }
    else
    {
        System.out.println("Stack Underflow");
    }
}
}
 
class GFG{
public static void main (String[] args)
{
    Stack ms1 = new Stack();
    Stack ms2 = new Stack();
     
    ms1.push(6);
    ms1.push(5);
    ms1.push(4);
    ms2.push(9);
    ms2.push(8);
    ms2.push(7);
     
    ms1.merge(ms2);
    ms1.display();
}
}
 
// This code is contributed by Ayaan


Python3
# The Node class for Linked List
class Node():
    def __init__(self,data):
         
        self.next = None
        self.prev = None
        self.data = data
 
class Stack():
     
    # Initialize stack class with
    # its head and tail as None
    def __init__(self):
         
        self.head = None
        self.tail = None
 
    def push(self, data):
         
        new_node = Node(data)
         
        if (self.head == None):
            self.head = new_node
            self.head.next= None
            self.head.prev = None
            self.tail = new_node
 
        else:
            new_node.prev = self.tail
            self.tail.next = new_node
            self.tail = new_node
 
    def pop(self):
         
        if (self.head == None):
            print("Stack underflow")
 
        if (self.head == self.tail):
            self.head = None
            self.tail = None
 
        else:
            node = self.tail
            self.tail = self.tail.prev
            del node
            self.tail.next = None
 
    # self (stack) is linked on top (which is tail here) of stack
    # self becomes the merged stack
    def merge(self, stack):
        if stack.head == None: return  # if stack is empty self stays as it is
        if self.head == None:        # self (stack) is empty -> point to stack
            self.head = stack.head
            self.tail = stack.tail
            return
        self.head.prev = stack.tail # link self on top of stack
        stack.tail.nxt = self.head
        self.head = stack.head      # set new head for self (stack)
 
    def display(self):
         
        if (self.tail != None):
            n = self.tail
             
            while (n != None):
                print(n.data, end = " ")
                n = n.prev
 
            print()
 
        else:
            print("Stack Underflow")
 
# Driver code
ms1 = Stack()
ms2 = Stack()
 
ms1.push(6)
ms1.push(5)
ms1.push(4)
ms2.push(9)
ms2.push(8)
ms2.push(7)
 
ms1.merge(ms2)
ms1.display()
while ms1.head != ms1.tail:
  ms1.pop ()
print ("check pop all elements until head == tail (one element left)")
print ("on merged stack: ", end = "")
ms1.display()
# This code is contributed by maheswaripiyush9


C#
using System;
// The class Node contains the
// structure of our Node of
// the linked list
public
 
    class Node {
    public
 
        Node next;
    public
 
        Node prev;
    public
 
        int data;
 
    // Create a node with the
    // given value
    public
 
        Node(int value)
    {
        data = value;
        next = null;
        prev = null;
    }
}
 
public
 
    class Stack {
 
    private Node head;
    private Node tail;
 
    // Initialize stack class
    // with its head and tail as null
    public Stack()
    {
        head = null;
        tail = null;
    }
 
    public void Push(int value)
    {
        Node newNode = new Node(value);
        if (head == null) {
            head = newNode;
            head.next = null;
            head.prev = null;
            tail = newNode;
        }
        else {
            newNode.prev = tail;
            tail.next = newNode;
            tail = newNode;
        }
    }
 
    public void Pop()
    {
        if (head == null)
            Console.WriteLine("stack underflow");
 
        if (head == tail) {
            head = null;
            tail = null;
        }
        else {
            Node n = tail;
            tail = tail.prev;
            n.prev = null;
            tail.next = null;
        }
    }
 
    public void merge(Stack s)
    {
        head.prev = s.tail;
        s.tail.next = head;
        head = s.head;
        s.tail = null;
        s.head = null;
    }
 
    public void display()
    {
        if (tail != null) {
            Node n = tail;
            while (n != null) {
                Console.Write(n.data + " ");
                n = n.prev;
            }
            Console.WriteLine();
        }
        else {
            Console.WriteLine("Stack Underflow");
        }
    }
}
 
public class GFG {
    public static void Main(String[] args)
    {
        Stack ms1 = new Stack();
        Stack ms2 = new Stack();
 
        ms1.Push(6);
        ms1.Push(5);
        ms1.Push(4);
        ms2.Push(9);
        ms2.Push(8);
        ms2.Push(7);
 
        ms1.merge(ms2);
        ms1.display();
    }
}
// This code contributed by aashish1995


输出
4 5 6 7 8 9