Ivan Prodanov
Ivan Prodanov

Reputation: 35522

How to copy a stack?

So I use a dynamic stack and I want to write a copy constructor, which has to copy the stack's data from another instance of the same class. I'm trying to write the function, but it seems pretty hard. Could somebody give me a hand?

template<typename T=int>
class LStack
{
public:

    template<typename U=int>
    struct elem
    {
        U con;
        elem<U>* link;
    }

private:

    elem<T>* el;

    void Copystack(Lstack const& stack)    // HERE
    {
        elem<T>* last = el;
        el->con = stack->con;
        while(stack->link != null)
        {
            var temp = new elem<T>;
            temp->con = stack->con;
            temp->link = stack->link;
            stack = stack->link;
        }
    }

};

Upvotes: 4

Views: 31328

Answers (3)

selbie
selbie

Reputation: 104514

First, if you are going to support copying a collection class, you need to be able to property release the memory owned by the stack object your are copying into, else you have a memory leak. The kind of thing your destructor would do anyway. So let's have a clean method:

void clean() {
    while (el) {
        auto ptr = el;
        el = el->link;
        delete ptr;
    }
    el = nullptr;
}

Then cloning a stack is cloning your linked list. It doesn't matter that your linked list represents a stack or a queue when we clone it. We're just preserving order.

void clone(elem<T>* ptr) {

    clean();  // erase the current stack

    elem<T>* head = nullptr;
    elem<T>* last = nullptr;
    while (ptr) {

        // clone the item
        elem<T>* item = new elem<T>();
        item->con = ptr->con;
        item->link = nullptr;

        // appead the item at the end of our new linked list
        if (head == nullptr) {
           head = item;
        } else {
           last->link = item;
        }
        last = item;
        ptr = ptr->link;
    }
    el = head;
}

Then enables you to have a copy method:

LStack& operator=(const LStack& other) {
    clone(other.el);        
    return *this;
}

And a copy constructor, which sets the head of the linked list to null before cloning the other one.

LStack(const LStack& other) : el(nullptr) {
    clone(other.el);        
}

And your CopyStack function, if you still want it, does the same thing.

CopyStack(const LStack& other) {
    clone(other.el);
}

And let's not forget your destructor can invoke the clean method:

~LStack() {
    clean();
}

Upvotes: 0

Prakash Thakur
Prakash Thakur

Reputation: 25

/*Create two stack objects of the same data type.
Push elements into the original stack.
Copy the original stack into the new stack using the assignment operator.
Traverse the copied stack using a loop.
For each element in the copied stack, perform the following operations:
Retrieve the top element of the copied stack using the top() function.
Store the top element of the copied stack in a variable.
Pop the top element of the copied stack using the pop() function.
Push the stored element into the new stack using the push() function.
Print the elements of the new stack*/




#include <iostream>
#include <stack>

int main() {
    std::stack<int> originalStack;
    std::stack<int> copiedStack;
    std::stack<int> newStack;

    // Push elements into the original stack
    originalStack.push(10);
    originalStack.push(20);
    originalStack.push(30);

    // Copy the original stack into the copied stack
    copiedStack = originalStack;

    // Traverse the copied stack and push its elements into the new stack
    while (!copiedStack.empty()) {
        int element = copiedStack.top();
        copiedStack.pop();
        newStack.push(element);
    }

    // Print the elements of the new stack
    while (!newStack.empty()) {
        std::cout << newStack.top() << " ";
        newStack.pop();
    }

    return 0;
}

Upvotes: 0

TemplateRex
TemplateRex

Reputation: 70526

The STL container adaptor std::stack has an assignment operator= that allows you to do exactly that

#include <stack>

int main()
{
   std::stack<int> s1;
   std::stack<int> s2;
   s1 = s2;
}

If you need to do it manually, you can use @FredOverflow's recursive solution, or you could do it with two loops and a temporary Stack, which the recurisve version keeps on the stack frame (pun intended).

void copy_reverse(Stack& source, Stack& dest)
{
    while(!source.empty())
        dest.push(Element(source.top()));
        source.pop();
    }
}

Stack src, tmp, dst;
copy_reverse(src, tmp);
copy_reverse(tmp, dst);

Upvotes: 8

Related Questions