2. //cout << "The list is reversedn";
//ReverseList(&head);
//DisplayList(head);
//numDel = 60;
//ptrDelete = FindANode(head, numDel);
//if (DeleteNode(head, ptrDelete->data))
//{
// cout << numDel << " deleted!n";
// DisplayList(head);
//}
//if (!circular)
// MakeCircular(head);
//circular = IsCircular(head);
//disp = circular ? "true" : "false";
//cout << disp << endl << endl;
}
// only for the 1st Node
void InitNode(Node* head, int n)
{
head->data = n;
head->next = NULL;
}
Node* TestList()
{
Node* head = new Node;
InitNode(head, 0);
head->next = new Node(3, nullptr);
head->next->next = new Node(7, nullptr);
return head;
}
void DelList(Node* head)
{
if (head->next)
DelList(head->next);
delete head;
}
// find a node with value 'd' (start with head to search entire list)
Node* FindANode(Node* currNode, int d)
{
// end of list, node not found
if (!currNode) return nullptr;
// node found
if (currNode->data == d)
return currNode;
// check next node
FindANode(currNode->next, d);
}
3. // add new node to end of list
void AddEndNode(Node* currNode, int d)
{
// move on to next node
if (currNode->next)
AddEndNode(currNode->next, d);
else // found end of list, add new node
{
currNode->next = new Node(d, nullptr);
return;
}
}
// add new node to front of list
void InsertFront(Node** head, int n)
{
Node *newNode = new Node;
newNode->data = n;
newNode->next = *head;
*head = newNode;
}
// delete node
bool DeleteNode(Node* currNode, int val)
{
if (!currNode || !currNode->next) return false;
// node found, 'delete' it
if (currNode->next->data == val)
{
Node* tempNode = currNode->next;
currNode->next = currNode->next->next;
delete tempNode;
return true;
}
// check next node
else if (DeleteNode(currNode->next, val))
return true;
// node not found
return false;
}
// add new node (sorted list)
void AddSortedNode(Node* currNode, int d)
{
// list is empty or 'd' becomes head
if (!currNode || currNode->data > d)
{
InsertFront(&currNode, d);
return;
}
// at end of list
if (!currNode->next)
{
AddEndNode(currNode, d);
4. return;
}
// insert newNode here
if ((currNode->data <= d && currNode->next->data > d)
|| (currNode->data > d && currNode->next->data < d))
{
Node* newNode = new Node;
newNode->data = d;
newNode->next = currNode->next;
currNode->next = newNode;
return;
}
// check next node
AddSortedNode(currNode->next, d);
}
// split a list into two lists (less than, greater than)
void Split(Node* head, int pivot, Node** lt, Node** gt)
{
if (!head) return;
if (head->data < pivot)
{
if (*lt)
AddEndNode(*lt, head->data);
else
{
*lt = new Node;
InitNode(*lt, head->data);
}
}
else if (head->data > pivot)
{
if (*gt)
AddEndNode(*gt, head->data);
else
{
*gt = new Node;
InitNode(*gt, head->data);
}
}
Split(head->next, pivot, lt, gt);
}
// reverse a list
void ReverseList(Node** currNode)
{
// list is empty || has only one node || at end of list
if (!(*currNode) || !(*currNode)->next) return;
// move newCurrNode to the end of the list
Node* newCurrNode = (*currNode)->next;
ReverseList(&newCurrNode);
// reverse the 'next' pointers (next->next is validated by earlier 'if check')
(*currNode)->next->next = (*currNode);
5. // set 'next' ptr to nullptr
(*currNode)->next = nullptr;
// fix the currNode / 'head' pointer and return it
*currNode = newCurrNode;
}
// sort the list
void SortListAscending(Node* firstNode, Node* currNode)
{
// recursive
#if 1
// swap data
if (currNode->data < firstNode->data)
{
int tmpData = firstNode->data;
firstNode->data = currNode->data;
currNode->data = tmpData;
}
// second / inner 'loop'
if (currNode->next)
SortListAscending(firstNode, currNode->next);
// first / outer 'loop'
else if (firstNode->next)
SortListAscending(firstNode->next, firstNode->next);
#endif
// while loop
#if 0
Node* iter = firstNode;
while (iter)
{
Node* iter2 = firstNode;
while (iter2->next)
{
if (iter->data < iter2->data)
{
int tmpData = iter->data;
iter->data = iter2->data;
iter2->data = tmpData;
}
iter2 = iter2->next;
}
iter = iter->next;
}
#endif
}
// is a list circular (count is used to avoid returning on first cycle)
bool IsCircular(Node* head)
{
// list is empty || hare reached end of list (not circular)
if (!head) return false;
int count = 1;
Node* tortoise = head;
6. Node* hare = head;
while (hare->next)
{
// move the 'tortoise' ptr once every other cycle
if (count++ % 2 == 0) tortoise = tortoise->next;
hare = hare->next;
// tortoise caught up to the hare (circular list)
if (tortoise == hare && count > 1) return true;
}
return false;
}
// make the list circular
void MakeCircular(Node* head)
{
if (!head) return;
Node* currNode = head;
while (currNode->next)
currNode = currNode->next;
currNode->next = head;
}
// find middle node in a list
Node* FindMiddleNode(Node* head)
{
Node* currNode = head;
Node* midNode = head;
int count = 1;
while (currNode->next)
{
if (count++ % 2 == 0)
midNode = midNode->next;
currNode = currNode->next;
}
return midNode;
}
// disply list from currNode (pass 'head' to display entire list)
void DisplayList(Node *currNode)
{
// display currNode
//cout << currNode->data << " ";
//// if available, move to next node
//if (currNode->next)
// DisplayList(currNode->next);
//// if not, insert two lines for end of list
//else
// cout << "nn";
}
7. BOOST_AUTO_TEST_SUITE(LinkedLists)
BOOST_AUTO_TEST_CASE(FindNode)
{
Node* head = TestList();
Node* tgt = FindANode(head, 3);
// should fail
//BOOST_CHECK_EQUAL(tgt->data, 11);
// should pass
BOOST_CHECK_EQUAL(tgt->data, 3);
DelList(head);
}
BOOST_AUTO_TEST_CASE(AddToEnd)
{
Node* head = TestList();
AddEndNode(head, 11);
Node* tgt = FindANode(head, 11);
// should fail
//BOOST_CHECK(tgt->next);
// should pass
BOOST_CHECK(!tgt->next);
DelList(head);
}
BOOST_AUTO_TEST_CASE(AddFront)
{
Node* head = TestList();
InsertFront(&head, 11);
Node* tgt = FindANode(head, 11);
// should fail
//BOOST_CHECK_EQUAL(tgt->data, 20);
// should pass
BOOST_CHECK_EQUAL(tgt, head);
DelList(head);
}
BOOST_AUTO_TEST_CASE(DelNode)
{
Node* head = TestList();
DeleteNode(head, 11);
// should fail
//BOOST_CHECK(FindANode(head, 3) == nullptr);
// should pass
BOOST_CHECK(FindANode(head, 11) == nullptr);
DelList(head);
}
// sorted item added to head of list
BOOST_AUTO_TEST_CASE(AddSortedHead)
{
8. Node* head = TestList();
AddSortedNode(head, 0);
// should fail
//BOOST_CHECK_EQUAL(head->data, 3);
// should pass
BOOST_CHECK(head->data == 0);
DelList(head);
}
// sorted item added to mid of list
BOOST_AUTO_TEST_CASE(AddSortedMid)
{
Node* head = TestList();
AddSortedNode(head, 6);
Node* prev = head;
Node* newNode = FindANode(head, 6);
// find newNode->previous
while (prev->next->data < newNode->data)
prev = prev->next;
// check if newNode is mid list
BOOST_CHECK(prev->data <= newNode->data);
BOOST_CHECK(newNode->next);
DelList(head);
}
// sorted item added to end of list
BOOST_AUTO_TEST_CASE(AddSortedEnd)
{
Node* head = TestList();
AddSortedNode(head, 60);
Node*prev = head;
Node* newNode = FindANode(head, 60);
// find newNode-previous
while (prev->next->data < newNode->data)
prev = prev->next;
// check newNode is end of list (correctly)
BOOST_CHECK(prev->data <= newNode->data);
BOOST_CHECK(!newNode->next);
DelList(head);
}
BOOST_AUTO_TEST_CASE(SplitList)
{
Node* head = TestList();
Node* ltList = nullptr;
Node* gtList = nullptr;
// create 2 new lists from first list
9. Split(head, 3, <List, >List);
Node* ltEnd = ltList;
while (ltEnd->next)
ltEnd = ltEnd->next;
BOOST_CHECK(ltEnd->data < gtList->data);
DelList(head);
delete ltList;
delete gtList;
}
BOOST_AUTO_TEST_CASE(RevList)
{
Node* head = TestList();
ReverseList(&head);
// should fail
//BOOST_CHECK_EQUAL(head->data, 0);
// should pass
BOOST_CHECK_EQUAL(head->data, 7);
BOOST_CHECK_EQUAL(head->next->data, 3);
BOOST_CHECK_EQUAL(head->next->next->data, 0);
DelList(head);
}
BOOST_AUTO_TEST_CASE(SortAsc)
{
Node* head = TestList();
int tmp = head->data;
// change list to 3, 7, 0
head->data = head->next->data;
head->next->data = tmp;
tmp = head->next->data;
head->next->data = head->next->next->data;
head->next->next->data = tmp;
// change back to 0, 3, 7
SortListAscending(head, head);
// should fail
//BOOST_CHECK_EQUAL(head->data, 3);
// should pass
BOOST_CHECK_EQUAL(head->data, 0);
BOOST_CHECK_EQUAL(head->next->data, 3);
BOOST_CHECK_EQUAL(head->next->next->data, 7);
DelList(head);
}
BOOST_AUTO_TEST_CASE(CheckCircular)
{