1: /** @file linked_node_functions.cpp 2: Implementation file corresponding to the specification file 3: linked_node_functions.h. The functions in this module are 4: used with the demonstration program in linked_node_main.cpp. 5: */ 7: #include <iostream> 8: #include <iomanip> 9: using namespace std; 11: typedef int DataType; 12: struct Node 13: { 14: DataType data; 15: Node* link; 16: }; 17: typedef Node* NodePointer; 20: void DescribeProgram() 21: { 22: cout << "\nThis is a demonstration program used to illustrate some " 23: "operations on a\nsequence of linked nodes containing integer " 24: "data values. It is best to\nrun it with pencil and paper in hand " 25: "and to draw a pictorial representation\nof what the sequence of " 26: "linked nodes will look like after you take any\nparticular action " 27: "offered by the menu." 29: "\n\nYou may display the data values in the nodes at any time for " 30: "purposes of\ncomparison. Each value is printed in six spaces, " 31: "with ten values per line."; 33: cout << "\n\nYou begin with an empty list, and a menu of options " 34: "from which to choose.\n\n\n\n\n\n\n\n\n\n\n\n"; 35: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 36: } 39: void InitializeSequence 40: ( 41: NodePointer& head //inout 42: ) 43: { 44: head = nullptr; 45: } 48: void ReclaimStorage 49: ( 50: NodePointer& head //in 51: ) 52: { 53: while (head != nullptr) 54: { 55: NodePointer current = head; 56: head = head->link; 57: delete current; 58: } 59: } 63: void BuildSequenceFixedSize 64: ( 65: NodePointer& head //inout 66: ) 67: { 68: if (head != nullptr) 69: { 70: ReclaimStorage(head); 71: InitializeSequence(head); 72: } 73: cout << "Enter number of nodes you would like in the sequence: "; 74: int numNodes; 75: cin >> numNodes; cin.ignore(80, '\n'); 76: if (numNodes <= 0) 77: { 78: cout << "\nNumber of nodes must be > 0."; 79: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 80: return; 81: } 82: cout << "\nNow enter the node values for the sequence " 83: "on the following line:\n"; 85: head = new Node; 86: cin >> head->data; 87: NodePointer current = head; 88: for (int nodeCounter=2; nodeCounter<=numNodes; nodeCounter++) 89: { 90: NodePointer next = new Node; 91: cin >> next->data; 92: current->link = next; 93: current = next; 94: } 95: cin.ignore(80, '\n'); 96: current->link = nullptr; 97: cout << "\nAll values have been read in and the linked sequence " 98: "has been constructed."; 99: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 100: } 103: void PrintNodeValues 104: ( 105: NodePointer head //inout 106: ) 107: { 108: if (head == nullptr) 109: cout << "Current sequence is empty. No values to print.\n"; 110: else 111: { 112: cout << "Here are the data values in the current sequence:\n"; 113: NodePointer current = head; 114: int nodeCounter = 0; 115: while (current != nullptr) 116: { 117: cout << setw(6) << current->data; 118: nodeCounter++; 119: if (nodeCounter % 10 == 0) cout << endl; 120: current = current->link; 121: } 122: if (nodeCounter % 10 != 0) cout << endl; 123: } 124: } 127: void FindNodeDataValue 128: ( 129: NodePointer head, //inout 130: DataType targetValue, //in 131: bool& found, //out 132: NodePointer& targetPointer, //out 133: int& targetPosition //out 134: ) 135: { 136: found = false; 137: NodePointer current = head; 138: int nodeCounter = 1; 139: while (!found && current != nullptr) 140: { 141: if (current->data == targetValue) 142: found = true; 143: else 144: { 145: current = current->link; 146: nodeCounter++; 147: } 148: } 149: if (found) 150: { 151: targetPointer = current; 152: targetPosition = nodeCounter; 153: } 154: } 157: void FindDataValueAndPrevious 158: ( 159: NodePointer& head, //inout 160: DataType targetValue, //in 161: bool& found, //out 162: NodePointer& targetPointer, //out 163: NodePointer& previousPointer //out 164: ) 165: { 166: found = false; 167: NodePointer current = head; 168: NodePointer previous = nullptr; 169: while (!found && current != nullptr) 170: { 171: if (current->data == targetValue) 172: found = true; 173: else 174: { 175: previous = current; 176: current = current->link; 177: } 178: } 179: if (found) 180: { 181: targetPointer = current; 182: previousPointer = previous; 183: } 184: } 187: void FindDataValues 188: ( 189: NodePointer head //inout 190: ) 191: { 192: if (head == nullptr) 193: { 194: cout << "\nCurrent sequence is empty. No values can be found."; 195: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 196: return; 197: } 198: cout << "Enter the data value to look for, " 199: << "or end-of-file to quit: "; 200: DataType targetValue; 201: cin >> targetValue; cin.ignore(80, '\n'); 203: while (cin) 204: { 205: cout << endl; 206: bool found; 207: NodePointer targetPointer; 208: int targetPosition; 209: FindNodeDataValue(head, targetValue, found, 210: targetPointer, targetPosition); 212: cout << targetValue << " was "; 213: if (found) 214: cout << "found in node " << targetPosition << "."; 215: else 216: cout << "not found in the current sequence."; 217: cout << "\nEnter another data value to look for, " 218: << "or end-of-file to quit: "; 219: cin >> targetValue; cin.ignore(80, '\n'); 220: } 221: cin.clear(); 222: } 225: void InsertAfterNodeWithDataValue 226: ( 227: NodePointer& head //inout 228: ) 229: { 230: if (head == nullptr) 231: { 232: cout << "\nCurrent sequence is empty. Cannot find a value after " 233: "which to insert."; 234: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 235: return; 236: } 237: cout << "\nEnter data value after which to insert, " 238: << "or end-of-file to quit: "; 239: DataType targetValue; 240: cin >> targetValue; cin.ignore(80, '\n'); 241: while (cin) 242: { 243: cout << endl; 244: bool found; 245: NodePointer targetPointer; 246: int targetPosition; 247: FindNodeDataValue(head, targetValue, found, 248: targetPointer, targetPosition); 249: if (found) 250: { 251: NodePointer newNode = new Node; 252: cout << "Enter the data value for the new node: "; 253: cin >> newNode->data; cin.ignore(80, '\n'); 254: cout << endl; 255: newNode->link = targetPointer->link; 256: targetPointer->link = newNode; 257: cout << "The value " << newNode->data << " has been " 258: "inserted after the first occurrence of the value " 259: << targetValue << "."; 260: } 261: else 262: cout << "There is no node containing the value " 263: << targetValue << ".\n"; 264: cout << "\nEnter another data value after which to insert, " 265: << "or end-of-file to quit: "; 266: cin >> targetValue; cin.ignore(80, '\n'); 267: } 268: cin.clear(); 269: } 272: void InsertBeforeNodeWithDataValue 273: ( 274: NodePointer& head //inout 275: ) 276: { 277: if (head == nullptr) 278: { 279: cout << "\nCurrent sequence is empty. Cannot find a value before " 280: "which to insert."; 281: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 282: return; 283: } 284: cout << "\nEnter the data value before which to insert, " 285: << "or end-of-file to quit: "; 286: DataType targetValue; 287: cin >> targetValue; cin.ignore(80, '\n'); 289: while (cin) 290: { 291: cout << endl; 292: bool found; 293: NodePointer targetPointer; 294: NodePointer previousPointer; 295: FindDataValueAndPrevious(head, targetValue, found, 296: targetPointer, previousPointer); 297: if (found) 298: { 299: NodePointer newNode = new Node; 300: cout << "Enter the data value for the new node: "; 301: cin >> newNode->data; cin.ignore(80, '\n'); 302: cout << endl; 303: newNode->link = targetPointer; 304: if (targetPointer == head) 305: head = newNode; 306: else 307: previousPointer->link = newNode; 308: cout << "The value " << newNode->data << " has been " 309: "inserted before the first occurrence of the value " 310: << targetValue << "."; 311: } 312: else 313: cout << "There is no node containing the value " 314: << targetValue << "."; 315: cout << "\nEnter another data value, before which to insert, " 316: << "or end-of-file to quit: "; 317: cin >> targetValue; cin.ignore(80, '\n'); 318: } 319: cin.clear(); 320: } 324: void DeleteNodeWithDataValue 325: ( 326: NodePointer& head //inout 327: ) 328: { 329: if (head == nullptr) 330: { 331: cout << "\nCurrent sequence is empty. No values to delete."; 332: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 333: return; 334: } 335: cout << "\nEnter data value to delete, or " 336: "end-of-file for no deletions: "; 337: DataType targetValue; 338: cin >> targetValue; cin.ignore(80, '\n'); 340: while (cin) 341: { 342: cout << endl; 343: bool found; 344: NodePointer targetPointer; 345: NodePointer previousPointer; 346: FindDataValueAndPrevious(head, targetValue, found, 347: targetPointer, previousPointer); 348: if (found) 349: { 350: if (targetPointer == head) 351: head = targetPointer->link; 352: else 353: previousPointer->link = targetPointer->link; 354: delete targetPointer; 355: cout << "The first occurrence of the value " << targetValue 356: << " has been deleted."; 357: } 358: else 359: cout << "There is no node containing the value " 360: << targetValue << "."; 361: cout << "\nEnter another data value to delete, " 362: << "or end-of-file to end deletions: "; 363: cin >> targetValue; cin.ignore(80, '\n'); 364: } 365: cin.clear(); 366: } 369: void ReverseAllDigits 370: ( 371: NodePointer& p //inout 372: ) 373: { 374: int n, nr; 375: if (p->data > 9) 376: { 377: n = p->data; 378: nr = 0; 379: while (n != 0) 380: { 381: nr = 10*nr + (n%10); 382: n = n/10; 383: } 384: p->data = nr; 385: } 386: } 389: void ProcessAllNodes 390: ( 391: NodePointer& head, //inout 392: void (*Process)(NodePointer& p) //function 393: ) 394: { 395: if (head == nullptr) 396: { 397: cout << "\nCurrent sequence is empty. No nodes to process."; 398: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 399: return; 400: } 401: NodePointer current = head; 402: while (current != nullptr) 403: { 404: (*Process)(current); 405: current = current->link; 406: } 407: cout << "\nAll nodes have been processed."; 408: cout << "\nPress Enter to continue ... "; cin.ignore(80, '\n'); 409: }