PPP2 Chapter 17 - Link class member functions

The Link class member functions add, erase, find and advance. I need help with them. I wrote the helper function version of the functions, but I'm having modifying them for the member function version. Here's what I have right now:
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
Link *Link::add(Link *n)
{
	if (n == nullptr)
	{
		return this;
	}
	if (this == nullptr)
	{
		return n;
	}
	n->prev = this;
	if (succ)
	{
		succ->prev = n;
	}
	n->succ = succ;
	succ = n;
	return n;
}

Link *Link::erase()
{
	if (this == nullptr)
	{
		return nullptr;
	}
	if (succ)
	{
		succ->prev = prev;
	}
	if (prev)
	{
		prev->succ = succ;
	}
	return succ;
}

Link *Link::find(const std::string &s)
{
	while (this != nullptr)
	{
		if (value == s)
		{
			return this;
		}
		this->succ;
	}
	return nullptr;
}

const Link *Link::find(const std::string &s) const
{
	while (this != nullptr)
	{
		if (value == s)
		{
			return this;
		}
		this->succ;
	}
	return nullptr;
}

Link *Link::advance(int n) const
{
	if (this == nullptr)
	{
		return nullptr;
	}
	if (n > 0)
	{
		while (n--)
		{
			if (succ == nullptr)
			{
				return nullptr;
			}
		}
	}
	else if (n < 0)
	{
		while (n++)
		{
			if (prev == nullptr)
			{
				return nullptr;
			}
		}
	}
	return const_cast<Link *>(this);
}


These are the ones in the book:
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
Link* add(Link* p, Link* n) // insert n after p; return n
{
    // much like insert (see exercise 11)
}

Link* erase(Link* p) // remove *p from list; return p’s successor
{
    if (p==nullptr) return nullptr;
    if (p–>succ) p–>succ–>prev = p–>prev;
    if (p–>prev) p–>prev–>succ = p–>succ;
    return p–>succ;
}

Link* find(Link* p, const string& s) // find s in list;
                                     // return nullptr for “not found”
{
    while (p) {
    if (p–>value == s) return p;
    p = p–>succ;
    }
    return nullptr;
}

Link* advance(Link* p, int n) // move n positions in list
                              // return nullptr for “not found”
                              // positive n moves forward, negative backward
{
    if (p==nullptr) return nullptr;
    if (0<n){
        while (n––){
            if (p–>succ == nullptr) return nullptr;
            p = p–>succ;
        }
    }
    else if (n<0){
        while (n++){
            if (p–>prev == nullptr) return nullptr;
            p = p–>prev;
        }
    }
    return p;
}


How should I modify these to the member functions where we have access to the this pointer? And wat would be the this pointer equivalent of the line p = p->prev;?

I hope someone can help me. Thanks in advance.
Last edited on
you need to differentiate a node from the list.
for example, ¿why does a node have a search function?, ¿what does advance mean? ¿are insert[i] and [i]erase responsibilities of a node or of a list?

> this == nullptr
that makes no sense, you are in a member function, ¿how may be this null then?

> this->succ;
statement has no effect (you probably have a warning with a similar message)
you are doing nothing there, no operation is performed.
Like I said, I need to know a good equivalent for the line p = p->prev; for that version of the function. And yeah, you're right about the text for null. I'll take that out.

This is part of a Link class. The rest of it, including the insert() function, were given in the book (I tried to modify that to write the add() function, but I'm not sure if I did it right). The book said at the end of the chapter that this is only the "link" part of a linked list. The "list" part will come later. It's like a re-implementation of the standard library "list" for teaching purposes.

Edit: Here's the whole program 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
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
// Osman Zakir
// 9 / 7 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 17 Section 17.9.4
// Doubly Linked Lists

#include <iostream>
#include "../../cust_std_lib_facilities.h"

class Link
{
public:
	std::string value;

	Link(const std::string &v, Link *p = nullptr, Link *s = nullptr);

	Link *insert(Link *n);    // insert n before this object
	Link *add(Link *n);	  // insert n after this object
	Link *erase();		 // remove this object from list
	Link *find(const std::string &s);    // find s in list
	const Link *find(const std::string &s) const;    // find s in const list

	Link *advance(int n) const;    // advance n positions in list
	
	Link *next() const { return succ; }
	Link *previous() const { return prev; }

private:
	Link *prev;
	Link *succ;
};

void print_all(Link *p);

int main()
{
	Link *norse_gods = new Link{ "Thor" };
	norse_gods = norse_gods->insert(new Link{ "Odin" });
	norse_gods = norse_gods->insert(new Link{ "Zeus" });
	norse_gods = norse_gods->insert(new Link{ "Freia" });

	Link *greek_gods = new Link{ "Hera" };
	greek_gods = greek_gods->insert(new Link{ "Athena" });
	greek_gods = greek_gods->insert(new Link{ "Mars" });
	greek_gods = greek_gods->insert(new Link{ "Poseidon" });

	Link *p = greek_gods->find("Mars");
	if (p)
	{
		p->value = "Ares";
	}

	Link *p2 = norse_gods->find("Zeus");
	if (p2)
	{
		if (norse_gods)
		{
			norse_gods = p2->next();
			p2->erase();
			greek_gods = greek_gods->insert(p2);
		}
	}

	print_all(norse_gods);
	print_all(greek_gods);

	keep_window_open();
}

Link::Link(const std::string &v, Link *p, Link *s)
	: value{ v }, prev{ p }, succ{ s }
{

}

Link *Link::insert(Link *n)
{
	if (n == nullptr)
	{
		return this;
	}
	n->succ = this;
	if (prev)
	{
		prev->succ = n;
	}
	n->prev = prev;
	prev = n;
	return n;
}

Link *Link::add(Link *n)
{
	if (n == nullptr)
	{
		return this;
	}
	n->prev = this;
	if (succ)
	{
		succ->prev = n;
	}
	n->succ = succ;
	succ = n;
	return n;
}

Link *Link::erase()
{
	if (succ)
	{
		succ->prev = prev;
	}
	if (prev)
	{
		prev->succ = succ;
	}
	return succ;
}

Link *Link::find(const std::string &s)
{
	std::size_t i = 0;
	while (succ != nullptr)
	{
		if (value == s)
		{
			return this;
		}
		succ++;
		++i;
	}
	return nullptr;
}

const Link *Link::find(const std::string &s) const
{
	std::size_t i = 0;
	while (succ != nullptr)
	{
		if (value == s)
		{
			return this;
		}
		++i;
	}
	return nullptr;
}

Link *Link::advance(int n) const
{
	if (n > 0)
	{
		while (n--)
		{
			if (succ == nullptr)
			{
				return nullptr;
			}
		}
	}
	else if (n < 0)
	{
		while (n++)
		{
			if (prev == nullptr)
			{
				return nullptr;
			}
		}
	}
	return const_cast<Link *>(this);
}

void print_all(Link *p)
{
	std::cout << "{ ";
	while (p)
	{
		std::cout << p->value;
		if (p == p->next())
		{
			std::cout << ", ";
		}
		std::cout << " }";
	}
}


I hope people can help me better now. The add(), advance(), erase() and find() functions are the ones I need help on. Mainly.
Last edited on
Topic archived. No new replies allowed.