#include "stdafx.h"
struct Node
{
int data;
Node* next;
Node() = default;
Node(int _data, Node* _next) : data(_data), next(_next){};
};
// run sample code
void RunLL()
{
//Node *head = new Node;
//Node* lt = nullptr;
//Node* gt = nullptr;
//InitNode(head, 122);
//DisplayList(head);
//AddEndNode(head, 60);
//DisplayList(head);
//AddEndNode(head, 182);
//DisplayList(head);
//AddEndNode(head, 2);
//DisplayList(head);
//AddEndNode(head, 202);
//DisplayList(head);
//InsertFront(&head, 15);
//DisplayList(head);
//SortListAscending(head, head);
//DisplayList(head);
//AddSortedNode(head, 86);
//DisplayList(head);
//Node* midNode = FindMiddleNode(head);
//cout << midNode->data << endl << endl;
//bool circular = IsCircular(head);
//string disp = circular ? "true" : "false";
//cout << disp << endl << endl;
//Split(head, 86, &lt, &gt);
//DisplayList(lt);
//DisplayList(gt);
//int numDel = 15;
//Node *ptrDelete = FindANode(head, numDel);
//if (DeleteNode(head, ptrDelete->data))
// cout << numDel << " deleted!n";
//DisplayList(head);
//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);
}
// 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);
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);
// 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;
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";
}
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)
{
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
Split(head, 3, &ltList, &gtList);
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)
{
}
BOOST_AUTO_TEST_CASE(BeCircular)
{
}
BOOST_AUTO_TEST_CASE(FindMiddle)
{
}
BOOST_AUTO_TEST_SUITE_END()

Linked lists

  • 1.
    #include "stdafx.h" struct Node { intdata; Node* next; Node() = default; Node(int _data, Node* _next) : data(_data), next(_next){}; }; // run sample code void RunLL() { //Node *head = new Node; //Node* lt = nullptr; //Node* gt = nullptr; //InitNode(head, 122); //DisplayList(head); //AddEndNode(head, 60); //DisplayList(head); //AddEndNode(head, 182); //DisplayList(head); //AddEndNode(head, 2); //DisplayList(head); //AddEndNode(head, 202); //DisplayList(head); //InsertFront(&head, 15); //DisplayList(head); //SortListAscending(head, head); //DisplayList(head); //AddSortedNode(head, 86); //DisplayList(head); //Node* midNode = FindMiddleNode(head); //cout << midNode->data << endl << endl; //bool circular = IsCircular(head); //string disp = circular ? "true" : "false"; //cout << disp << endl << endl; //Split(head, 86, &lt, &gt); //DisplayList(lt); //DisplayList(gt); //int numDel = 15; //Node *ptrDelete = FindANode(head, numDel); //if (DeleteNode(head, ptrDelete->data)) // cout << numDel << " deleted!n"; //DisplayList(head);
  • 2.
    //cout << "Thelist 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 newnode 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 newNodehere 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, &ltList,&gtList); 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) {
  • 10.