Single Linked List Question

Hey everyone,

I'm writing a program that uses a single-linked list and I'm running into two hiccups that I can't figure out. The first is that my pop() method pops from the bottom of the stack and not the top. The second is that when I copy stack, they are copied backwards. Anyone have any idea why this is occuring?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <stdexcept>

using namespace std;
using std::ostream;

template <class T>
struct SNode
       {
            T value;
            SNode<T> *next;
            
//Constructor, copies argument into stack node and sets node's pointer to NULL
            SNode(T newData)
            {
                        value = newData;
                        next = NULL;
            }
       };
       
// Forward declaration of the Stack template class
template <class T> 
class Stack;

// Forward declaration of the operator<< template function
template <class T>
std::ostream& operator<<(std::ostream &os,const Stack<T>&st);

template <class T>
class Stack
{
      private:
             SNode<T>* head;
             void copyList(const Stack<T>&);
      public:
     	     friend std::ostream& operator<< <>(std::ostream&, const Stack<T>&);
             Stack();
             ~Stack();
             Stack(const Stack<T> & q);
             Stack<T>& operator=(const Stack<T>&); 
             int size() const;
             int top() const;
             bool empty() const;
             void push(T newValue);
             void pop();
             void clear();
             
};

// Method definitions for the Stack class


/****************************************************************
   FUNCTION:   Stack()
   ARGUMENTS:  none
   RETURNS:    nothing
   NOTES:      Default contructor that takes no arguments. The constructor
               sets head to NULL.
****************************************************************/
template <class T>
Stack<T>::Stack()
{
         head = NULL;
}

/****************************************************************
   FUNCTION:   ~Stack()
   ARGUMENTS:  none
   RETURNS:    nothing
   NOTES:      Destructor. Simply calls the clear() method..
****************************************************************/
template <class T>
Stack<T>::~Stack()
{
       clear();
}

/****************************************************************
   FUNCTION:   copyList()
   ARGUMENTS:  template parameter
   RETURNS:    nothing
   NOTES:      Copy method used in = operator and copy constructor.
               Copies one object to another.
****************************************************************/
template <class T>
void Stack<T>::copyList(const Stack<T>& listToCopy)
   {
   SNode<T>* p;
   
   for (p = listToCopy.head; p != NULL; p = p->next)
      push(p->value);
   }
/****************************************************************
   FUNCTION:   Stack(const Stack<T>& g)
   ARGUMENTS:  Template parameter
   RETURNS:    nothing
   NOTES:      Copy constructor.
****************************************************************/
template <class T>
Stack<T>::Stack(const Stack<T> & q)
{                     

                    head = NULL;
                    copyList(q);
}

/****************************************************************
   FUNCTION:   Stack<T>& operator=(const Stack<T>& s)
   ARGUMENTS:  ?
   RETURNS:    ?
   NOTES:      The assignment operator should be properly overloaded
****************************************************************/
template <class T>
Stack<T>& Stack<T>::operator=(const Stack<T>& rightOp)
{
   if (this != &rightOp)
      {
      clear();
      copyList(rightOp);
      }
         
   return *this; 
}


/****************************************************************
   FUNCTION:   overloaded << operator
   ARGUMENTS:  ?
   RETURNS:    ?
   NOTES:      The output operator should be properly overloaded.
****************************************************************/
template <class T>
ostream& operator<<(ostream& leftOp, const Stack<T>& rightOp)
{
SNode<T>* ptr = rightOp.head;
while (ptr)
{
    leftOp << ptr->value << " ";
    ptr = ptr -> next;
}
return leftOp;
}

/****************************************************************
   FUNCTION:   size()
   ARGUMENTS:  none
   RETURNS:    an integer
   NOTES:      Returns the current size of the stack (the number of data
               items currently stored in the stack. Traverses the linked
               list and counts the nodes.
****************************************************************/
template <class T>
int Stack<T>::size() const
{
    int count = 0;
    for (SNode<T>* ptr = head; ptr != NULL; ptr = ptr->next)
    count++;
    
    return count;
}

/****************************************************************
   FUNCTION:   top()
   ARGUMENTS:  none
   RETURNS:    an integer
   NOTES:      Returns the data stored in the top node of the stack (the
               front node in the linked list). Assume this method will
               not be called if the stack is empty.
****************************************************************/
template <class T>
int Stack<T>::top() const
{
    T final;
    SNode<T>* nodePtr = head;
    while(nodePtr != NULL)
                  {
                  final = nodePtr->value;
                  nodePtr = nodePtr->next;
                  };
    return final;
         
}

/****************************************************************
   FUNCTION:   empty()
   ARGUMENTS:  none
   RETURNS:    nothing
   NOTES:      Returns true if there are no data items currently stored in
               the stack, otherwise returns false.
****************************************************************/
template <class T>
bool Stack<T>::empty() const
{
     if(head == NULL)
     return true;
     
     else 
     return false;
}

/****************************************************************
   FUNCTION:   push(T newValue)
   ARGUMENTS:  Reference to a constant item of the template parameter type?
   RETURNS:    nothing
   NOTES:      Inserts the item at the top[ of the stack (the front of the 
               linked list.
****************************************************************/
template <class T>
void Stack<T>::push(T newValue)
{
     SNode<T> * newNode = new SNode<T>(newValue);    
     newNode->next = head;
     head = newNode;
}

/****************************************************************
   FUNCTION:   pop()
   ARGUMENTS:  none
   RETURNS:    nothing
   NOTES:      Removes the node at the top of the stack. Assumes that 
               this method will not be called if the stack is empty.
****************************************************************/
template <class T>
void Stack<T>::pop()
{
    SNode<T>* delNode = head;
    if (!empty())
    {
       head = delNode -> next;
       delete delNode;
}
}

/****************************************************************
   FUNCTION:   clear()
   ARGUMENTS:  none
   RETURNS:    nothing
   NOTES:      Properly set the stack back to the empty state. Delete
               all of the nodes in the stack and set the top pointer 
               back to NULL.
****************************************************************/
template <class T>
void Stack<T>::clear()
{
     while (!empty())
     {
           pop();
           }
           head = NULL;
}

#endif 
Your top() method seems to indicate that the top of your stack is the last node in the list. But the pop() method deletes the first node in the list, which is the bottom of your stack.

Your copy() method goes the the internal list of the second stack (which, from before, is in reverse order compared to the stack it represents), but instead of appending to the internal list of the first stack, it pushes on the first stack (which prepends to the internal list). Does that make sense?
I understand what you mean about the pop() method, but I'm not sure exactly how to implement it. How do I go about about removing the top of my stack instead of the bottom? I just can't figure out the logic to do it.

Your explanation of the copy method just went right over my head. I'm not quite sure what you meant by it, what internal list of the second stack? Could you rephrase it in easier terms?

Thanks for your help.
Instead of setting the head of the list to head->next and then deleting the old head, iterate to the end of the list, set prev->next to NULL (making it the new end) and delete the old end.

I apologize, I made a mistake analyzing your copy() method. The algorithm there is fine; the problem likes in push().

In your implementation, the head of the list is the bottom of the stack, and the end of the list is the top of the stack.

In push(), however, you place the inserted element at the head of the list (the bottom of the stack). This is the opposite of the behavior you want, I think.
Well with a stack I can only access the top element of the stack, so the top element must be copied first (right?). When I push it into a new stack, it is automatically on the bottom (since there is nothing in the stack). How can I possibly copy it so it is not reversed? Can I used recursion in the copylist() method to copy it again and reverse it again into proper order?

I really just don't even know how to implement this at all. If you could provide code to demonstrate your explanation it would make it much easier.

Thanks for your help again, Zhuge.
Well with a stack I can only access the top element of the stack, so the top element must be copied first (right?).

This is correct, but you forget that in your copy function, you're copying from the internal list structure, which gives you access from the head (stack bottom) to end (stack top).

When I push it into a new stack, it is automatically on the bottom (since there is nothing in the stack).

This is correct as well, but you shouldn't think of it this way. When you push() you place things on the top of the stack; this first push() is just a special case where the top and the bottom are the same element.

How can I possibly copy it so it is not reversed?

When doing the copy, remember you have access to your underlying list that is being using for your stack. The process is just to copy one linked list to the other; start at the head of one, and keep appending each successive element to the list.

I don't really want to give you code here because I think it's important you understand the algorithm you need to implement and why that algorithm works.
Topic archived. No new replies allowed.