#include <iostream>
using std::cout;

int iterativeArraySum(int integers[], int size) {
   int sum = 0;
      for (int i = 0; i < size; i++) {
      sum += integers[i];
   }
   return sum;
}

int arraySumDelegate(int integers[], int size) {
   if (size == 0) return 0;
   int lastNumber = integers[size - 1];
   int allButLastSum = iterativeArraySum(integers, size - 1);
   return lastNumber + allButLastSum;
}

int arraySumRecursive(int integers[], int size) {
   if (size == 0) return 0;
   int lastNumber = integers[size - 1];
   int allButLastSum = arraySumRecursive(integers, size - 1);
   return lastNumber + allButLastSum;
}

int main() {
   // kod testujcy
   const int ARRAY_SIZE = 10;
   int testData[ARRAY_SIZE] = {15, 6, 7, 4, 3, 21, 5, 9, 70, 10};
   cout << iterativeArraySum(testData, ARRAY_SIZE) << "\n";
   cout << arraySumDelegate(testData, ARRAY_SIZE) << "\n";
   cout << arraySumRecursive(testData, ARRAY_SIZE) << "\n";

   return 0;
}

---

// UWAGA: poniszy kod nie zawiera wersji ze strony 157., odnoszcej si do niewaciwych 
// zwyczajw w programowaniu, ktre polegaj na uyciu zmiennej globalnej lub statycznej 

#include <iostream>
using std::cout;

int zeroCountIterative(int numbers[], int size) {
   int count = 0;
   for (int i = 0; i < size; i++) {
      if (numbers[i] == 0) count ++;
   }
   return count;
}

int zeroCountRecursive(int numbers[], int size) {
   if (size == 0) return 0;
   int count = zeroCountRecursive(numbers, size - 1);
   if (numbers[size - 1] == 0) count++;
   return count;
}

int main() {
   // kod testujcy
   const int ARRAY_SIZE = 10;
   int testData[ARRAY_SIZE] = {0, 6, 7, 0, 3, 0, 9, 0, 0, 10};
   cout << zeroCountIterative(testData, ARRAY_SIZE) << "\n";
   cout << zeroCountRecursive(testData, ARRAY_SIZE) << "\n";

   return 0;
}

---

// UWAGA: poniszy kod nie zawiera wersji ze strony 157., odnoszcej si do niewaciwych 
// zwyczajw w programowaniu, ktre polegaj na uyciu zmiennej globalnej lub statycznej

#include <iostream>
using std::cout;

struct listNode {
   int data;
   listNode * next;
};

typedef listNode * listPtr;

int countNegative(listPtr head) {
   if (head == NULL) return 0;
   int listCount = countNegative(head->next);
   if (head->data < 0) listCount++;
   return listCount;
}

int main() {
   // kod testujcy
   listNode * node1 = new listNode;
   node1->data = -5;
   listNode * node2 = new listNode;
   node2->data = 7;
   listNode * node3 = new listNode;
   node3->data = -14;

   node1->next = node2;
   node2->next = node3;
   node3->next = NULL;

   cout << countNegative(node1) << "\n";

   delete node3;
   delete node2;
   delete node1;

   return 0;
}

---

#include <iostream>
using std::cout;

struct treeNode {
   int data;
   treeNode * left;
   treeNode * right;
};

typedef treeNode * treePtr;

int maxValue(treePtr root) {
   if (root == NULL) return 0;
   if (root->right == 0 && root->left == 0) 
      return root->data;
   int leftMax = maxValue(root->left);
   int rightMax = maxValue(root->right);
   int maxNum = root->data;
   if (leftMax > maxNum) maxNum = leftMax;
   if (rightMax > maxNum) maxNum = rightMax;
   return maxNum;
}

int main() {
   // kod testowy, ktry tworzy drzewo z rysunku 6.7
   treeNode rootNode;
   rootNode.data = 17;
   treeNode LC; // LC = potomek lewy itd.; LCLC = lewy potomek lewego potomka
   LC.data = 4;
   treeNode RC;
   RC.data = 144;
   treeNode LCLC;
   LCLC.data = 3;
   treeNode LCRC;
   LCRC.data = 16;
   treeNode RCLC;
   RCLC.data = 99;
   treeNode RCRC;
   RCRC.data = 217;
   rootNode.left = &LC;
   rootNode.right = &RC;
   LC.left = &LCLC;
   LC.right = &LCRC;
   // wzy lici nie maj potomkw
   LCLC.left = LCLC.right = LCRC.left = LCRC.right = NULL;
   RC.left = &RCLC;
   RC.right = &RCRC;
   RCLC.left = RCLC.right = RCRC.left = RCRC.right = NULL;

   cout << maxValue(&rootNode);

   return 0;
}

---

#include <iostream>
using std::cout;
#include <stack>
using std::stack;

class binaryTree {
private:
   struct binaryTreeNode {
      int data;
      binaryTreeNode * left;
      binaryTreeNode * right;
   };
   binaryTreeNode * root;
   int privateCountLeaves(binaryTreeNode * rootPtr);
public:
   void buildTree(); // dodano w celu przeprowadzenia testw
   int countLeaves();
   int stackBasedCountLeaves();
};

int binaryTree::privateCountLeaves(binaryTreeNode * rootPtr) {
   if (rootPtr == NULL) return 0;
   if (rootPtr->right == NULL && rootPtr->left == NULL) 
      return 1;
   int leftCount = privateCountLeaves(rootPtr->left);
   int rightCount = privateCountLeaves(rootPtr->right);
   return leftCount + rightCount;
}

int binaryTree::countLeaves() {
   return privateCountLeaves(root);
}

int binaryTree::stackBasedCountLeaves() {
   if (root == NULL) return 0;
   int leafCount = 0;
   std::stack<binaryTreeNode *> nodes;
   nodes.push(root);
   while (!nodes.empty()) {
      binaryTreeNode * currentNode = nodes.top();
      nodes.pop();
      if (currentNode->left == NULL && currentNode->right == NULL) 
         leafCount++;
      else {
         if (currentNode->right != NULL) nodes.push(currentNode->right);
         if (currentNode->left != NULL) nodes.push(currentNode->left);
      }
   }	
   return leafCount;
}

// metoda dodana w celu przeprowadzenia testw
void binaryTree::buildTree() {
   // ten kod tworzy drzewo z rysunku 6.7
   root = new binaryTreeNode;
   root->data = 17;
   binaryTreeNode * LC = new binaryTreeNode; // LC = potomek lewy itd.; LCLC = lewy potomek lewego potomka
   LC->data = 4;
   binaryTreeNode * RC = new binaryTreeNode;
   RC->data = 144;
   binaryTreeNode * LCLC = new binaryTreeNode;
   LCLC->data = 3;
   binaryTreeNode * LCRC = new binaryTreeNode;
   LCRC->data = 16;
   binaryTreeNode * RCLC = new binaryTreeNode;
   RCLC->data = 99;
   binaryTreeNode * RCRC = new binaryTreeNode;
   RCRC->data = 217;
   root->left = LC;
   root->right = RC;
   LC->left = LCLC;
   LC->right = LCRC;
   // wzy lici nie maj potomkw
   LCLC->left = LCLC->right = LCRC->left = LCRC->right = NULL;
   RC->left = RCLC;
   RC->right = RCRC;
   RCLC->left = RCLC->right = RCRC->left = RCRC->right = NULL;
}

int main() {
   binaryTree testTree;
   testTree.buildTree();
   cout << testTree.countLeaves() << "\n";
   cout << testTree.stackBasedCountLeaves() << "\n";

   return 0;
}

---

#include <iostream>
using std::cout;
#include <stack>
using std::stack;

struct node {
   int data;
   node * next;
};

typedef node * nodePtr;

void displayListForwardsIterative(nodePtr head) {
   for (nodePtr current = head; current != NULL; current = current->next) 
      std::cout << current->data << std::endl;
}

void displayListBackwardsIterative(nodePtr head) {
   std::stack<nodePtr> nodes;
   for (nodePtr current = head; current != NULL; current = current->next) 
      nodes.push(current);
   while (!nodes.empty()) {
      nodePtr current = nodes.top();
      nodes.pop();
      std::cout << current->data << std::endl;	
	}
}

void displayListForwardsRecursion(nodePtr head) {
   if (head != NULL) {
      std::cout << head->data << std::endl;
      displayListForwardsRecursion(head->next);
   }
}

void displayListBackwardsRecursion(nodePtr head) {
   if (head != NULL) {
      displayListBackwardsRecursion(head->next);
      std::cout << head->data << std::endl;
   }
}

int main() {
   // kod testowy
   node * node1 = new node;
   node1->data = 1;
   node * node2 = new node;
   node2->data = 2;
   node * node3 = new node;
   node3->data = 3;
   node1->next = node2;
   node2->next = node3;
   node3->next = NULL;

	cout << "Wywoanie funkcji displayListForwardsIterative(node1); \n";
   displayListForwardsIterative(node1);
   cout << "Wywoanie funkcji displayListBackwardsIterative(node1); \n";
   displayListBackwardsIterative(node1);
   cout << "Wywoanie funkcji displayListForwardsRecursion(node1); \n";
   displayListForwardsRecursion(node1);
   cout << "Wywoanie funkcji displayListBackwardsRecursion(node1); \n";
   displayListBackwardsRecursion(node1);

   return 0;
}