Reputation: 49
For a project in my Data Structures class, we have been instructed to make a program that creates a linked list.
Here is the assignment instruction: Your assignment is to define and implement a List ADT as an in-memory, ordered, double linked list. Your data will come from an input text file called ThingsToDo.txt. The List class will define, along with a constructor and destructor, the core functionality for a list:
I have created the following header file:
using namespace std;
//create a node with data and link fields
struct Node
{
string info;
Node * next;
Node * prev;
};
//the List ADT definition
class List
{
public:
// construct a List object
List();
// Destroy a list object
~List();
// Insert a string into its correct alpha location in the list and return true if the function worked and false otherwise
bool Insert(string);
// Delete a string from its location in the list and return true if the function worked and false otherwise (no string found)
bool Delete(string);
// Edit a string from its location in the list and return true if the edit worked and false otherwise.
bool Edit(string, string);
// Print all of the nodes info from the beginning to end.
void Print() const;
private:
Node * Head;
};
My problem is that I do not know how to make a good delete function in my c++ file.
I have made the following Insert and Edit functions, but if anyone could help me create a good Delete function it would be greatly appreciated.
bool List::Edit(string target, string replace)
{
bool Success = false;
// first delete the target node calling the Delete function
if (Delete(target))
{
// if deleted, then insert the replace node
if (Insert(replace))
{
Success = true;
}
}
// will only return true if Delete and add both worked , otherwise false
return Success;
}
/*Function description: insert data into the doubly linked list by placing
* it into its correct ascending alpha location
*/
bool List::Insert(string data)
{
bool wasSuccessful = false;
// Allocate memory for a node and store the address in p. If new returns
// false, then memory could not be allocated and the function will exit
// with failure.
Node* p = new Node;
if (p != NULL)
{
//store the KEY data in the node
p->info = data;
// Logic that handles the insert empty case (CASE 1)
if (Head == NULL)
{
p->next = NULL;
p->prev = NULL;
Head = p;
wasSuccessful = true;
}
else
{
//Logic if the List is not empty, cur is the traversal pointer, p points
//to the node to be inserted (CASES 2, 3 AND 4), set traversal
//pointer cur
Node* cur = Head;
//Loop until the node was successfully inserted, the loop
//looks for the correct insertion point which could be front
//middle, or last
while (!wasSuccessful)
{
//insert node (p) still greater than current node (cur)
if (p->info > cur->info)
{
//are we at the last node? condition for last insertion (CASE 2)
if (cur->next == NULL)
{
//insert node at end of list
p->next = NULL;
p->prev = cur;
cur->next = p;
wasSuccessful = true;
}
else
{
//move the current pointer to the next node
cur = cur->next;
}
}
else
{
//we have found an insertion point, the node to be inserted
//is lesser than the current node in the list
//Is it an insert front condition? (CASE 3)
if (Head == cur)
{
p->next = Head;
p->prev = NULL;
Head->prev = p;
Head = p;
}
else
{
//Logically, this has to be an insert middle case (CASE 4)
p->next = cur;
p->prev = cur->prev;
cur->prev->next = p;
cur->prev = p;
}
wasSuccessful = true;
}
}
}
}
return wasSuccessful;
}
The only thing I have written for the Delete function is this:
bool List::Delete(string data)
{
}
Is there any way someone could write the code for me for the delete function?
Upvotes: 1
Views: 400
Reputation: 84652
Presuming you have constructed a valid doubly-linked list (where Head->prev
is nullptr
as is Tail->next
[or the last node]), then removing any one node is straight forward. (I would encourage adding a Tail
pointer, e.g. Node *Head, *Tail;
where Tail
always points to the last node in the list - though doing an in-order insertion eliminates the benefit of the O(1) insertion it would provide at the end)
To add or remove nodes efficiently, you must understand the concept of iterating over your list using both the address of the pointer, and pointer itself. This eliminates any special cases.
In a bit more detail, in your linked-list, each Node
is a pointer to an allocated struct Node
, each of the pointers also has its very own address. By using both the address of the pointer and pointer to node, you can replace what is at the current pointer address with another pointer (the next
in your list) and then delete
the allocated struct that was originally stored at that address (the original pointer there). This makes things much easier and is more fully discussed at Linus on Understanding Pointers
With a doubly-linked list, you have only to update the prev
pointer for the node you will store at the current pointer address to point to what was the value of the prev
pointer for the current node.
By using both the address of the current pointer and the pointer itself, when you change what is stored at the address of the current pointer -- you still have a pointer to the original struct Node
that was there -- which you can use with delete
.
Putting it altogether, you could do:
bool List::Delete (std::string data)
{
Node **ppn = &Head; /* pointer to pointer to node */
Node *pn = Head; /* pointer to node */
/* iterate over each node using the address of poiner and pointer to node */
for (; pn; ppn = &pn->next, pn = pn->next) {
if (pn->data == data) { /* if node data matches data */
if (pn->next) /* if next not nullptr */
pn->next->prev = pn->prev; /* update next->prev to current->prev */
*ppn = pn->next; /* set node at current address to next */
delete pn; /* delete original node at address */
return true; /* return success */
}
}
return false; /* return failure (node not found) */
}
(note: suggest passing a reference rather than the string itself as a parameter, e.g. std::string& data
-- slightly more efficient)
Untested, but should work fine. Look things over, try it, and let me know if you have any questions.
Upvotes: 1