In: Computer Science
(C++) All programs will be included!
This lab gives you a little practice with linked lists
·Debug insertSorted() and implement sorted() in numberlist.cpp
·Hint: insertSorted() is just missing a few parts. What is in the function can work fine once you add the right code, though you are free to rewrite it
·You need to have main.cpp, numberlist.h and numberlist.cpp in this project, and if you are using Code::Blocks, remember to set the Build Options to indicate you want to use C++11 or later. The expected output for the final program is:
Test driver to check insertSorted() and sorted() methods of NumberList class
Is empty list in ascending order? true
Displaying list first time:
3.9
5.2
Displaying list second time:
3.9
4.6
5.2
8.4
Is list in ascending order? true
3.9
4.6
5.2
8.4
7.1
Is list in ascending order? False
MAIN.CPP
#include <iostream>
#include "numberlist.h"
using namespace std;
int main()
{
NumberList list;
cout << "Test driver to check insertSorted() and sorted() methods of NumberList class"
<< endl << endl;
cout << "Is empty list in ascending order? "
<< boolalpha << list.sorted() << endl;
list.insertSorted(5.2);
list.insertSorted(3.9);
cout << "Displaying list first time: " << endl;
list.displayList();
list.insertSorted(8.4);
list.insertSorted(4.6);
cout << "Displaying list second time: " << endl;
list.displayList();
cout << "Is list in ascending order? "
<< list.sorted() << endl;
list.appendNode(7.1);
list.displayList();
cout << "Is list in ascending order? "
<< list.sorted() << endl;
return 0;
}
NUMBERLIST.CPP
#include "numberlist.h"
#include <iostream>
using namespace std;
const double NumberList::EPSILON = 0.000001;
// insert so values are in ascending order
void NumberList::insertSorted(double num) {
ListNode * newNode = new ListNode;
newNode->value = num;
newNode->next = nullptr;
if (num < head->value) {
newNode->next = head;
head = newNode;
}
// declare outside for loop so we can use iter after the loop
ListNode * iter = head;
for (; nullptr != iter->next; iter = iter->next) {
if (num < iter->next->value) {
// insert between iter and iter->next
iter->next = newNode;
return;
}
}
}
/** destructor to free memory for all elements in list */
NumberList::~NumberList()
{
ListNode * nodePtr, * nextNode;
nodePtr = head;
while (nodePtr != NULL) {
nextNode = nodePtr->next;
delete nodePtr;
nodePtr = nextNode;
}
}
/** display list to console
rewritten to show similarity to working with arrays */
void NumberList::displayList() const {
for (ListNode *nodePtr = head;
nodePtr != NULL;
nodePtr = nodePtr->next)
cout << nodePtr->value << endl;
}
void NumberList::insertNode(double num) {
ListNode * node = new ListNode;
node->next = head;
node->value = num;
head = node;
}
/** add to end of list */
void NumberList::appendNode(double num) {
// cannot put num into list directly
// must construct a node
ListNode *newNode;
// use this to go through list
// serves same purpose as loop counter
// for array processing
ListNode *nodePtr;
newNode = new ListNode;
newNode->value = num;
// always have to initialize the pointer
newNode->next = NULL;
// usually best to handle special cases
// first
if (!head) // like (NULL == head)
head = newNode;
else {
nodePtr = head;
/** should make sure you understand why the condition
checks nodePtr->next instead of nodePtr */
while (nodePtr->next) // same as (nodePtr->head != NULL)
nodePtr = nodePtr->next;
// the actual appending
nodePtr->next = newNode;
}
}
// delete a value from the list
void NumberList::deleteNode(double num) {
ListNode * nodePtr;
ListNode * previousNode;
// handle special case first
if (head->value == num) {
// save pointer to 2nd element
nodePtr = head->next;
// free first element's memory
delete head;
head = nodePtr;
}
else {
nodePtr = head;
while (nodePtr != NULL && nodePtr->value != num) {
previousNode = nodePtr;
nodePtr = nodePtr->next;
}
/** if nodePtr is not at the end of the list,
(What would that mean?)
link the previous node to the node after nodePtr,
then delete nodePtr
*/
if (nodePtr) {
previousNode->next = nodePtr->next;
delete nodePtr;
}
}
}
numberlist.h
// a basic linked list class from Gaddis, ch. 17.2
#ifndef NUMBERLIST_H
#define NUMBERLIST_H
// replacing NULL by nullptr -- if you are using Code::Blocks,
// remember to set the build option that you are using C++11 or later
class NumberList
{
private:
// adding this for double comparison
static const double EPSILON;
struct ListNode {
double value;
ListNode *next;
};
ListNode * head; //!< points to start of list
public:
/** Default constructor */
NumberList() {
head = nullptr;
}
/** Default destructor */
~NumberList();
// standard list operations
// add to end of list
void appendNode(double);
// inserts in order
void insertNode(double);
void deleteNode(double);
// insert so values are in ascending order
// NOTE: if we really wanted this, we should remove
// insertNode() and appendNode()
// deleteNode() could stay
void insertSorted(double);
// returns true if sorted, false if not
bool sorted() const;
void displayList() const;
};
#endif // NUMBERLIST_H
The modified code for insert sorted is shown below:
// insert so values are in ascending order
void NumberList::insertSorted(double num) {
ListNode * newNode = new ListNode;
newNode->value = num;
newNode->next = nullptr;
if (num < head->value) {
newNode->next = head;
head = newNode;
}
// declare outside for loop so we can use iter after the loop
ListNode * iter = head;
for (; nullptr != iter->next; iter = iter->next) {
if (num < iter->next->value) {
// insert between iter and iter->next
ListNode *temp=iter->next;//temporary node to store next node of iter.
iter->next = newNode;
newNode->next=temp;
return;
}
}
// if the num is largest of all then it will not be inserted in for loop.
//So,we need to connect it at last and since iter will be at last node currently therefore
iter->next = newNode
return;
}
The code given in the question have some bugs which is get fixed above with the proper comments written.
Bugs Description :-
Inside the for loop i.e. if we need to insert the node in the middle then we need to connect newNode to the next of iter and also previously the node which is iter's next must be point to newNode 's next now.
So,thats the first bug above that we are not connecting the previous next of iter to newNode's next.
And ,also suppose the newNode we need to insert at last.So,it can't get inserted at last inside the for loop.
So,we inserted at the the end of for loop.
Now ,implementation of sorted function.
bool NumberList::Sorted()
{
ListNode *temp=head;
while(temp->next!=NULL)
{
if(temp->value>temp->next->value)
return false;
temp=temp->next;
}
return true;
}
In this function we are simply comparing current value with its next value.
If current value is greater than next value then return false.
If we could not find any such case in the list we'll return true