ADT List. Help with storing value in previous node.

I would like to know how to modify insert in the implementation file so that the previous and next items in the list are stored correctly.
Issue is at line 134. In the insert function.

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
Below is the implementation file.
  

#include "ListP.h" // header file
#include <stddef.h> // for NULL
#include <assert.h> // for assert()
#include <iostream>
using namespace std;



List::List(): size(0), head(NULL)
    {
    } // end default constructor

List::List(const List & L): size(L.size)
    {
    if (L.head == NULL)
        head = NULL; // original list is empty

    else
        { // copy first node
        head = new ListNode;
        assert(head != NULL); // check allocation
        head->item = L.head->item;

        // copy rest of list
        ListNode * NewPtr = head; // new list pointer
        // NewPtr points to last node in new list 
        // OrigPtr points to nodes in original list
        for (ListNode * OrigPtr = L.head->next;OrigPtr != NULL;OrigPtr = OrigPtr->next)
            { NewPtr->next = new ListNode;
            assert(NewPtr->next != NULL);
            NewPtr = NewPtr->next;
            NewPtr->item = OrigPtr->item;
            } // end for

        NewPtr->next = NULL;
        } // end if
    } // end copy constructor

List::~List()
    {
    bool Success;

    while (! isEmpty())
        remove(1, Success);
    } // end destructor

bool List::isEmpty() const
    {
    return bool(size == 0);
    } // end ListIsEmpty

int List::getLength() const
    {
    return size;
    } // end ListLength

List::ListNode * List::find(int Position) const
    // --------------------------------------------------
    // Locates a specified node in a linked list.
    // Precondition: Position is the number of the 
    // desired node.
    // Postcondition: Returns a pointer to the desired 
    // node. If Position < 1 or Position > the number of 
    // nodes in the list, returns NULL.
    // --------------------------------------------------
    {
    if ( (Position < 1) || (Position > getLength()) )
        return NULL;

    else // count from the beginning of the list
        { ListNode * Cur = head;
        for (int Skip = 1; Skip < Position; ++Skip)
            Cur = Cur->next;
        return Cur;
        } // end if
    } // end find

void List::retrieve(int Position,ListItemType & Dataitem, bool & Success) const
    {
    ListNode * Cur;
    Success = bool( (Position >= 1) && (Position <= getLength()) );

    if (Success)
        { // get pointer to node, then data in node
        Cur = find(Position);
        Dataitem = Cur->item;        

		if(Cur->previous != NULL) 
		{
			cout<<"Previous cell is "<<Cur->previous->item<<endl;
		}
		else
		{
			cout<<"Previous cell is empty!"<<endl;
		}
		if(Cur->next != NULL) 
		{
			cout<<"Next cell is "<<Cur->next->item<<endl;
		}
		else
		{
			cout<<"Next cell is empty!"<<endl;
		}
        } // end if
    } // end retrieve

void List::insert(int NewPosition,ListItemType Newitem, bool & Success)
    {
    ListNode * Prev;
    ListNode * NewPtr;
    int NewLength = getLength() + 1;

    Success = bool( (NewPosition >= 1) && (NewPosition <= NewLength) );

    if (Success)
        { // create new node and place Newitem in it
        NewPtr = new ListNode;
        Success = bool(NewPtr != NULL);
        if (Success)
            { size = NewLength;
            NewPtr->item = Newitem;

            // attach new node to list
            if (NewPosition == 1)
                { // insert new node at beginning of list
                NewPtr->next = head;
                head = NewPtr;
				if(NewPtr-> next != NULL)
					{
//This is where I am having trouble getting the program to work.
						NewPtr->next->Prev=NewPtr->next;
					}
                }

            else
                { Prev = find(NewPosition-1);
                // insert new node after node 
                // to which Prev points
                NewPtr->next = Prev->next;
                Prev->next = NewPtr;
                } // end if
            } // end if
        } // end if
    } // end insert

void List::remove(int Position, bool & Success)
    {
    ListNode * Cur;
    ListNode * Prev;

    Success = bool( (Position >= 1) && (Position <= getLength()) );

    if (Success)
        { --size;
        if (Position == 1)
            { // delete the first node from the list
            Cur = head; // save pointer to node
            head = head->next;
            }

        else
            { Prev = find(Position-1);
            // delete the node after the
            // node to which Prev points
            Cur = Prev->next; // save pointer to node
            Prev->next = Cur->next;
            } // end if

        // return node to system
        Cur->next = NULL;
        delete Cur;
        Cur = NULL;
        } // end if
    } // end remove 
Last edited on
Below are the header and source code files.


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
typedef char ListItemType;

class List
    {
    public:
        List();                     // default constructor
        List(const List & L);    //copy Constructor
        ~List();                //Destructor
        // list operations:
        bool isEmpty() const;
        // Determines whether a list is empty.
        // Precondition: None.
        // Postcondition: Returns true if the list is empty;
        // otherwise returns false.

        int getLength() const;
        // Determines the length of a list.
        // Precondition: None.
        // Postcondition: Returns the number of items
        // that are currently in the list.

        void insert(int index, ListItemType newItem,bool & success);
        // Inserts an item into the list at position index.
        // Precondition: index indicates the position at which
        // the item should be inserted in the list.
        // Postcondition: If insertion is successful, newItem is
        // at position index in the list, and other items are
        // renumbered accordingly, and success is true;
        // otherwise success is false.
        // Note: Insertion will not be successful if
        // index < 1 or index > getLength()+1.

        void remove(int index, bool & success);
        // Deletes an item from the list at a given position.
        // Precondition: index indicates where the deletion
        // should occur.
        // Postcondition: If 1 <= index <= getLength(),
        // the item at position index in the list is
        // deleted, other items are renumbered accordingly,
        // and success is true; otherwise success is false.

        void retrieve(int index, ListItemType & dataItem,bool & success) const;
        // Retrieves a list item by position.
        // Precondition: index is the number of the item to
        // be retrieved.
        // Postcondition: If 1 <= index <= getLength(),
        // dataItem is the value of the desired item and
        // success is true; otherwise success is false.

    private:
        struct ListNode // a node on the list
            {
            ListItemType item; // a data item on the list
            ListNode *next; // pointer to next node
       		ListNode *previous; //previous
            }; // end struct

        int size; // number of items in list
        ListNode *head; // pointer to linked list of items
        ListNode *find(int index) const;
        // Returns a pointer to the index-th node
        // in the linked list.
    }; // end List class
// End of header file.

Below is the source code



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
#include <iostream>
using namespace std;
#include "ListP.h"
int main()
    {
    ListItemType item;
    bool Success,done;
    char choice;
    int where;
    List L;
    done=false;
    while (! done)
        {
        //print menu
        cout<<"\n\n(I)nsert an item\n"
        <<"(D)elete an item\n"
        <<"(R)etrieve an item\n"
        <<"(L)ength of list\n"
        <<"(Q)uit\n";
        //get choice
        cout<<"?";
        cin>>choice;
        //execute command
        switch (choice)
            {
            case 'd':
            case 'D':
                cout<<"What position?\n";
                cin>>where;
                L.remove( where, Success);
                if(Success)
                    cout<<"Successful!\n";
                else
                    cout<<"Not successful\n";
                break;
            case 'i':
            case 'I':
                cout<<"What position?\n";
                cin>>where;
                cout<<"What item?\n";
                cin>>item;
                L.insert( where, item, Success);
                if(Success)
                    cout<<"Successful!\n";
                else
                    cout<<"Not successful\n";
                break;
            case 'r':
            case 'R':
                cout<<"What position?\n";
                cin>>where;
                L.retrieve( where, item, Success);
                if(Success)
                    {
                    cout<<"Successful!\n";
                    cout<<"Item retrieved: "<<item<<endl;
                    }
                else
                    cout<<"Not successful\n";
                break;
            case 'l':
            case 'L':

                cout<<"Length: "<<L.getLength( )<<endl;
                break;
            case 'Q':
            case 'q':
                done=true;
                break;
            }
        }

    }
Last edited on
I get a headache looking at all those variables-named-as-if-they-were-classes, so this is how I'd do it if I were writing it (with changes to style and naming conventions to assuage my headache.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void List::insert(int pos, ListItemType item, bool & success)
{
    success = false;
    if (pos < 1 || pos > size + 1) return;

    ListNode* node = new ListNode{ item, nullptr, nullptr };
    success = true;

    if (++size == 1)
        head = node;
    else {
        ListNode * prev = head;
        for (std::size_t i = 0; i < pos; ++i)
            prev = prev->next;

        node->previous = prev;
        node->next = prev->next;
        prev->next = node;

        if ( node->next ) node->next->previous = node;
    }
}


caveat: untested code

Are you wedded to the idea of taking the "success" indicator by reference? It would be more usual to return the value. Note that you've named the pointer representing the previous node as previous in the ListNode type, and not Prev as you're trying to use currently in insert.
yes, i am going to stick with this indicator for this reference. I would like to get this program running first and of course then i would try other ways to make it work, especially if it is better. thanks for the input. I am working to place it in my code now.
I tried to put a version of your node value placement code in mine, but i get a segmentation error. any clue how i can fix it?

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
void List::insert(int NewPosition,ListItemType Newitem, bool & Success)
    {
    ListNode * Prev;
    ListNode * NewPtr;
    int NewLength = getLength() + 1;

    Success = bool( (NewPosition >= 1) && (NewPosition <= NewLength) );

    if (Success)
        { // create new node and place Newitem in it
        NewPtr = new ListNode;
        Success = bool(NewPtr != NULL);
        if (Success)
            { size = NewLength;
            NewPtr->item = Newitem;

            // attach new node to list
            if (NewPosition == 1)
                { // insert new node at beginning of list
                NewPtr->next = head;
                head = NewPtr;
				if (NewPtr-> next != NULL)
					{
						NewPtr->previous= Prev;
						NewPtr->next = Prev->next;
						Prev->next = NewPtr;
						
						if ( NewPtr->next ) NewPtr -> next -> previous = NewPtr;
					}
                }

            else
                { Prev = find(NewPosition-1);
                // insert new node after node 
                // to which Prev points
                NewPtr->next = Prev->next;
                Prev->next = NewPtr;
                } // end if
            } // end if
        } // end if
    } // end insert 
.
Last edited on
sent
It is not possible for line 12 to be reached if line 11 doesn't succeed rendering the check on line 13 superfluous.

On line 24 (and the following lines,) Prev has some unspecified value, but you treat it as if it contains a valid non-null value. This will result in undefined behavior and memory corruption.

Btw, I suggest you ignore our local troll SakurasouBusters when he asks you to send him a PM. As you can see he doesn't want people to know he's requesting PMs and deletes the contents of his posts.
Topic archived. No new replies allowed.