#include <iostream>
using namespace std;
struct node_ll
{
int payload;
node_ll* next;//Pointer to the next node
};
void print_ll (node_ll** list)
{
node_ll* temp = *list;//Let temp be the address of the node that is the head of the list.
while(temp)// != NULL
{
cout << temp->payload << endl;//Print out payload of the struct whose address is temp.
temp = temp->next;//Set the address of temp equal to the address stored in next of the struct whose address is temp.
}
}
void head_insert(node_ll** list, int pload)
{
node_ll* temp = new node_ll;//Create a new node, and let temp be the address of that node.
temp->payload = pload;//Set the payload of the struct whose address is temp to pload.
temp->next = *list;//Set the next of the struct whose address is temp to the address of the old head of the list.
*list = temp;//The address of the old head of the list is changed to the address of the struct temp.
};
void tail_insert(node_ll** list, int pload)
{
if (*list == NULL)
{
head_insert(list, pload);
}
else
{
node_ll* temp = new node_ll;
for (temp = *list; temp->next; temp = temp->next);
temp->next = new node_ll;
temp->next->payload = pload;
temp->next->next = NULL;
}
}
int head_return (node_ll** list)
{
if (*list != NULL)
{
int temp = (*list)->payload;
node_ll* trash = *list;
*list = (*list)->next;
delete trash;
return temp;
}
else
{
return 0;
}
}
int tail_return (node_ll** list)
{
if (*list != NULL)
{
if ((*list)->next == NULL)
{
return head_return(list);
}
else
{
node_ll* trash;
for (trash = *list; trash->next->next; trash = trash->next);
int temp = trash->next->payload;
delete trash->next;
trash->next = NULL;
return temp;
}
}
else
{
return 0;
}
}
bool ordered_list(node_ll** list)
{
if (*list != NULL && (*list)->next != NULL)
{
node_ll* temp;
for (temp = *list; temp->next; temp = temp->next)
{
if (temp->payload > temp->next->payload)
{
return false;
}
}
}
return true;
}
void ordered_insert(node_ll** list, int pload)
{
if (ordered_list(list))
{
if (*list == NULL || (*list)->payload > pload)
{
head_insert(list, pload);
}
else
{
bool inserted = false;
node_ll* temp;
for (temp = *list; temp->next; temp = temp->next)
{
if (temp->next->payload > pload && !inserted)
{
node_ll* next = temp->next;
temp->next = new node_ll;
temp->next->payload = pload;
temp->next->next = next;
inserted = true;
}
}
if (!inserted)
{
tail_insert(list, pload);
}
}
}
}
void find_remove (node_ll** list, int pload)
{
if (*list != NULL)
{
while (*list && (*list)->payload == pload)
{
head_return(list);
}
if (*list != NULL)
{
node_ll* temp;
for (temp = *list; temp->next; temp = temp->next)
{
while (temp->next->next != NULL && temp->next->payload == pload)
{
node_ll* trash = temp->next;
temp->next = temp->next->next;
head_return(&trash);
}
}
if (temp->next == NULL && temp->payload == pload)
{
tail_return(list);
}
}
}
}
int main()
{
node_ll* alist = NULL;
cout << "Empty list a to start." << endl;
head_insert(&alist, 2);
head_insert(&alist, 4);
head_insert(&alist, 6);
cout << "List a after head insertion of 2,4,6 is: " << endl;
print_ll(&alist);
cout << endl;
node_ll* blist = NULL;
cout << "Empty list b to start." << endl;
tail_insert(&blist, 2);
tail_insert(&blist, 4);
tail_insert(&blist, 6);
cout << "List b after tail insertion of 2,4,6 is: " << endl;
print_ll(&blist);
cout << endl;
node_ll*clist = NULL;
cout << "Empty list c to start." << endl;
tail_insert(&clist, 2);
tail_insert(&clist, 4);
tail_insert(&clist, 6);
cout << "List c after tail insertion of 2,4,6 is: " << endl;
print_ll(&clist);
if (ordered_list(&clist))
{
cout << "List c is ordered." << endl;
}
else
{
cout << "List c is not ordered." << endl;
}
ordered_insert(&clist, 1);
ordered_insert(&clist, 3);
ordered_insert(&clist, 7);
cout << "List c after ordered insertion of 1,3,7 is: " << endl;
print_ll(&clist);
cout << endl;
node_ll* dlist = NULL;
cout << "Empty list d to start." << endl;
tail_insert(&dlist, 2);
tail_insert(&dlist, 2);
tail_insert(&dlist, 3);
tail_insert(&dlist, 4);
tail_insert(&dlist, 4);
tail_insert(&dlist, 9);
tail_insert(&dlist, 6);
tail_insert(&dlist, 6);
cout << "List d after tail insertion of 2,2,3,4,4,5,6,6 is: " << endl;
print_ll(&dlist);
if (ordered_list(&dlist))
{
cout << "List d is ordered." << endl;
}
else
{
cout << "List d is not ordered." << endl;
}
find_remove(&dlist, 2);
find_remove(&dlist, 4);
find_remove(&dlist, 6);
cout << "List c after find and remove of 2,4,6 is: " << endl;
print_ll(&dlist);
cout << endl;
system("PAUSE");
return 0;
}
The struct and the prototypes of the functions were given in the question. I am unfortunately aware that this is more C code and less C++ code.
I am looking to compact my functions (specifically ordered_insert and find_remove) without removing functionality. For example, at the moment my find_remove function works if there exists two matching nodes at the start, two matching nodes in the middle or two matching nodes at the end.
For example, could I make more use of head_insert, tail_insert in my ordered insert function?
I look forward to reading your comments. Regards.
EDIT: Hi, I have updated my code after reading your comments. Large changes include:
- new node function was not necessary because I re-factored tail_insert to use head_insert function to insert a new node.
- tail return was refactored to make more use of the head_return function removing node deletion/manipulation.
- ordered list was refactored. Iteration removed. Recursion implemented to make for a neater solution.
- ordered insert is still iterative (I couldn't work out how to implement recursion). However, it has been slightly changed with removal of inserted boolean value and inclusion of a return statement for neater code. (I thought this may be akin to adding a goto statement so was unsure of this alteration at the start).
- find remove was re-factored to use recursion dramatically reducing nesting and creating an incredibly neat solution! very proud :)
Changes I did not make:
- although I feel assert and exceptions would be a useful addition, I feel they go beyond the scope of the task.
- although I am aware that the type of var2 would be type in the example, type* var1, var2, I feel that *var1 visually confuses the type with the identifier.
- do not import everything from namespace std; I was unsure what to import instead.
Thank you for your comments, here is the updated code. Feel free to critique further.
#include <iostream>
using namespace std;
struct node_ll
{
int payload;
node_ll* next;//Pointer to the next node
};
void print_ll (node_ll** list)
{
node_ll* temp = *list;
while(temp)
{
cout << temp->payload << endl;
temp = temp->next;
}
}
void head_insert(node_ll** list, int pload)
{
node_ll *node = new node_ll;
node->payload = pload;
node->next = *list;
*list = node;
};
void tail_insert(node_ll** list, int pload)
{
if (!*list)
{
head_insert(list, pload);
}
else
{
node_ll* temp = *list;
while(temp->next)
{
temp = temp->next;
}
head_insert(&temp->next, pload);
}
}
int head_return (node_ll** list)
{
if (!*list)
{
return -1;//Error: List is empty.
}
node_ll* trash = *list;
int i = trash->payload;
*list = trash->next;
delete trash;
return i;
}
int tail_return (node_ll** list)
{
if (!*list)
{
return -1;//Error: List is empty.
}
if (!(*list)->next)
{
return head_return(list);
}
else
{
node_ll* temp = *list;
while(temp->next->next)
{
temp = temp->next;
}
return head_return(&temp->next);
}
}
bool ordered_list(node_ll** list)
{
if (!*list || !(*list)->next)
{
return true;
}
if ((*list)->payload < (*list)->next->payload)
{
return ordered_list(&(*list)->next);
}
else
{
return false;
}
}
void ordered_insert(node_ll** list, int pload)
{
if (!ordered_list(list))
{
return;//Error: List is not ordered;
}
if (!*list || (*list)->payload > pload)//If list is null or first payload is greater than new payload.
{
head_insert(list, pload);
}
else
{
node_ll* temp = *list;
while(temp->next)
{
if (temp->next->payload > pload)
{
head_insert(&temp->next, pload);
return;
}
temp = temp->next;
}
head_insert(&temp->next, pload);//If all payloads are less than or equal to new payload.
}
}
void find_remove (node_ll** list, int pload)
{
if (!*list)
{
return;//List is empty.
}
while (*list && (*list)->payload == pload)//While loop required as node will become node->next on head_return(node).
{
head_return(list);
}
if (*list && (*list)->next)
{
find_remove(&(*list)->next, pload);
}
}
int main()
{
node_ll* alist = NULL;
cout << "Empty list a to start." << endl;
head_insert(&alist, 2);
head_insert(&alist, 4);
head_insert(&alist, 6);
cout << "List a after head insertion of 2,4,6 is: " << endl;
print_ll(&alist);
cout << "Tail return: " << tail_return(&alist) << endl;
cout << "Tail return: " << tail_return(&alist) << endl;
cout << "Tail return: " << tail_return(&alist) << endl;
cout << "Tail return: " << tail_return(&alist) << endl;
cout << endl;
node_ll* blist = NULL;
cout << "Empty list b to start." << endl;
tail_insert(&blist, 2);
tail_insert(&blist, 4);
tail_insert(&blist, 6);
cout << "List b after tail insertion of 2,4,6 is: " << endl;
print_ll(&blist);
cout << "Head return: " << head_return(&blist) << endl;
cout << "Head return: " << head_return(&blist) << endl;
cout << "Head return: " << head_return(&blist) << endl;
cout << "Head return: " << head_return(&blist) << endl;
cout << endl;
node_ll*clist = NULL;
cout << "Empty list c to start." << endl;
tail_insert(&clist, 2);
tail_insert(&clist, 4);
tail_insert(&clist, 6);
cout << "List c after tail insertion of 2,4,6 is: " << endl;
print_ll(&clist);
if (ordered_list(&clist))
{
cout << "List c is ordered." << endl;
}
else
{
cout << "List c is not ordered." << endl;
}
ordered_insert(&clist, 1);
ordered_insert(&clist, 3);
ordered_insert(&clist, 7);
cout << "List c after ordered insertion of 1,3,7 is: " << endl;
print_ll(&clist);
cout << endl;
node_ll* dlist = NULL;
cout << "Empty list d to start." << endl;
tail_insert(&dlist, 2);
tail_insert(&dlist, 2);
tail_insert(&dlist, 3);
tail_insert(&dlist, 4);
tail_insert(&dlist, 4);
tail_insert(&dlist, 9);
tail_insert(&dlist, 6);
tail_insert(&dlist, 6);
cout << "List d after tail insertion of 2,2,3,4,4,5,6,6 is: " << endl;
print_ll(&dlist);
if (ordered_list(&dlist))
{
cout << "List d is ordered." << endl;
}
else
{
cout << "List d is not ordered." << endl;
}
find_remove(&dlist, 2);
find_remove(&dlist, 4);
find_remove(&dlist, 6);
cout << "List c after find and remove of 2,4,6 is: " << endl;
print_ll(&dlist);
cout << endl;
system("PAUSE");
return 0;
}
if
statements. You also shouldn't useusing namespace std
. Read this post for more information: stackoverflow.com/questions/1452721/…. – Jamal♦ Apr 15 '13 at 14:09else
statements), then I'm sorry for the confusion. I don't know how to word it exactly. – Jamal♦ Apr 15 '13 at 16:00