Exam information in lab Tue, 18 Apr 2017, 9:00-noon programming part

Slides:



Advertisements
Similar presentations
Binary Search Trees Azhar Maqsood School of Electrical Engineering and Computer Sciences (SEECS-NUST)
Advertisements

Binary Trees. DCS – SWC 2 Binary Trees Sets and Maps in Java are also available in tree-based implementations A Tree is – in this context – a data structure.
Binary Search Trees Briana B. Morrison Adapted from Alan Eugenio.
Trees Chapter 8. Chapter 8: Trees2 Chapter Objectives To learn how to use a tree to represent a hierarchical organization of information To learn how.
Data Structures Topic #9. Today’s Agenda Continue Discussing Trees Examine the algorithm to insert Examine the algorithm to remove Begin discussing efficiency.
CS 104 Introduction to Computer Science and Graphics Problems Data Structure & Algorithms (4) Data Structures 11/18/2008 Yang Song.
Liang, Introduction to Java Programming, Sixth Edition, (c) 2007 Pearson Education, Inc. All rights reserved L12 (Chapter 20) Lists, Stacks,
More Trees COL 106 Amit Kumar and Shweta Agrawal Most slides courtesy : Douglas Wilhelm Harder, MMath, UWaterloo
Lecture Objectives  To learn how to use a tree to represent a hierarchical organization of information  To learn how to use recursion to process trees.
Lecture 10 Trees –Definiton of trees –Uses of trees –Operations on a tree.
Tree (new ADT) Terminology:  A tree is a collection of elements (nodes)  Each node may have 0 or more successors (called children)  How many does a.
Binary Trees, Binary Search Trees RIZWAN REHMAN CENTRE FOR COMPUTER STUDIES DIBRUGARH UNIVERSITY.
Chapter 19: Binary Trees Java Programming: Program Design Including Data Structures Program Design Including Data Structures.
1 Chapter 17 Object-Oriented Data Structures. 2 Objectives F To describe what a data structure is (§17.1). F To explain the limitations of arrays (§17.1).
Binary Search Trees Binary Search Trees (BST)  the tree from the previous slide is a special kind of binary tree called a binary.
Topic 15 The Binary Search Tree ADT Binary Search Tree A binary search tree (BST) is a binary tree with an ordering property of its elements, such.
Binary Search Trees Nilanjan Banerjee. 2 Goal of today’s lecture Learn about Binary Search Trees Discuss the first midterm.
Outline Binary Trees Binary Search Tree Treaps. Binary Trees The empty set (null) is a binary tree A single node is a binary tree A node has a left child.
Preview  Graph  Tree Binary Tree Binary Search Tree Binary Search Tree Property Binary Search Tree functions  In-order walk  Pre-order walk  Post-order.
Starting Out with C++ Early Objects Seventh Edition by Tony Gaddis, Judy Walters, and Godfrey Muganda Modified for use at Midwestern State University Chapter.
Inheritance Notes Chapter 6 1. Inheritance  you know a lot about an object by knowing its class  for example what is a Komondor? 2
ADT Binary Search Tree Ellen Walker CPSC 201 Data Structures Hiram College.
Copyright © 2012 Pearson Education, Inc. Chapter 20: Binary Trees.
BINARY TREES Objectives Define trees as data structures Define the terms associated with trees Discuss tree traversal algorithms Discuss a binary.
Search: Binary Search Trees Dr. Yingwu Zhu. Review: Linear Search Collection of data items to be searched is organized in a list x 1, x 2, … x n – Assume.
Course: Programming II - Abstract Data Types HeapsSlide Number 1 The ADT Heap So far we have seen the following sorting types : 1) Linked List sort by.
(c) University of Washington20c-1 CSC 143 Binary Search Trees.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Chapter 20: Binary Trees.
(c) University of Washington20-1 CSC 143 Java Trees.
1 Binary Search Trees What are the disadvantages of using a linked list? What are the disadvantages of using an array- based list? Binary search trees.
SUYASH BHARDWAJ FACULTY OF ENGINEERING AND TECHNOLOGY GURUKUL KANGRI VISHWAVIDYALAYA, HARIDWAR.
Binary Search Trees Chapter 7 Objectives
Topic 2: binary Trees COMP2003J: Data Structures and Algorithms 2
The Tree ADT.
Non Linear Data Structure
Chapter 25 Binary Search Trees
Trees Chapter 11 (continued)
Recursive Objects (Part 4)
Trees Chapter 11 (continued)
Week 6 - Wednesday CS221.
Binary Search Tree (BST)
Problems with Linked List (as we’ve seen so far…)
Lecture 22 Binary Search Trees Chapter 10 of textbook
Trees.
Data Structures & Algorithm Design
i206: Lecture 13: Recursion, continued Trees
Chapter 17 Object-Oriented Data Structures
Chapter 20: Binary Trees.
Chapter 22 : Binary Trees, AVL Trees, and Priority Queues
Binary Search Trees.
Map interface Empty() - return true if the map is empty; else return false Size() - return the number of elements in the map Find(key) - if there is an.
CMSC 341 Lecture 10 B-Trees Based on slides from Dr. Katherine Gibson.
Chapter 21: Binary Trees.
More Data Structures (Part 1)
Find in a linked list? first last 7  4  3  8 NULL
CMSC 341 Binary Search Trees.
Trees Lecture 9 CS2110 – Fall 2009.
Lecture 12 CS203 1.
CMSC 341 Binary Search Trees.
More Data Structures (Part 1)
CSC 143 Java Trees.
CSC 143 Binary Search Trees.
Trees.
Trees.
CMSC 341 Binary Search Trees 2/21/2006.
Data Structures Using C++ 2E
Chapter 20 Binary Search Trees
Trees Lecture 10 CS2110 – Spring 2013.
Tree (new ADT) Terminology: A tree is a collection of elements (nodes)
Presentation transcript:

Exam information in lab Tue, 18 Apr 2017, 9:00-noon programming part from inheritance onwards but no GUI programming expect to see an inheritance question, recursion questions, data structure questions written part short questions (facts, definitions, etc.) covering everything in the course longer questions covering from inheritance onwards expect to see a proof of correctness and termination of recursive a method

Trees

Graphs a graph is a data structure made up of nodes each node stores data each node has links to zero or more nodes in graph theory the links are normally called edges graphs occur frequently in a wide variety of real-world problems social network analysis e.g., six-degrees-of-Kevin-Bacon, Facebook Friend Wheel transportation networks e.g., http://ac.fltmaps.com/en many other examples http://www.visualcomplexity.com/vc/

Trees trees are special cases of graphs a tree is a data structure made up of nodes each node stores data each node has links to zero or more nodes in the next level of the tree children of the node each node has exactly one parent node except for the root node

50 34 11 6 79 23 99 33 67 88 31 1 6 83

50 11 6 79 34 88 67 23 33 99 1 31 83

Trees the root of the tree is the node that has no parent node all algorithms start at the root

root 50 34 11 6 79 23 99 33 67 88 31 1 6 83

Trees a node without any children is called a leaf

50 34 11 6 79 23 99 33 67 88 31 1 6 83 leaf leaf leaf leaf leaf leaf

Trees the recursive structure of a tree means that every node is the root of a tree

50 34 11 6 79 23 99 33 67 88 31 1 subtree 6 83

50 34 11 6 79 23 99 33 67 88 31 1 subtree 6 83

50 subtree 34 11 6 79 23 99 33 67 88 31 1 6 83

50 34 11 6 subtree 79 23 99 33 67 88 31 1 6 83

50 34 11 6 79 23 99 33 67 88 subtree 31 1 6 83

Binary Tree a binary tree is a tree where each node has at most two children very common in computer science many variations traditionally, the children nodes are called the left node and the right node

50 left right 27 73 8 44 83 73 93

50 27 73 left right 8 44 83 73 93

50 27 73 right 8 44 83 73 93

50 27 73 8 44 83 left right 74 93

Binary Tree Algorithms the recursive structure of trees leads naturally to recursive algorithms that operate on trees for example, suppose that you want to search a binary tree for a particular element

examine root examine left subtree examine right subtree public static <E> boolean contains(E element, Node<E> node) { if (node == null) { return false; } if (element.equals(node.data)) { return true; boolean inLeftTree = contains(element, node.left); if (inLeftTree) { boolean inRightTree = contains(element, node.right); return inRightTree; examine root examine left subtree examine right subtree

t.contains(93) 50 27 73 8 44 83 74 93

50 50 == 93? 27 73 8 44 83 74 93

50 27 73 27 == 93? 8 44 83 74 93

50 27 73 8 44 83 8 == 93? 74 93

50 27 73 8 44 83 44 == 93? 74 93

50 27 73 73 == 93? 8 44 83 74 93

50 27 73 8 44 83 83 == 93? 74 93

50 27 73 8 44 83 74 93 74 == 93?

50 27 73 8 44 83 74 93 93 == 93?

Iteration visiting every element of the tree can also be done recursively 3 possibilities based on when the root is visited inorder visit left child, then root, then right child preorder visit root, then left child, then right child postorder visit left child, then right child, then root

50 27 73 8 44 83 74 93 inorder: 8, 27, 44, 50, 73, 74, 83, 93

50 27 73 8 44 83 74 93 preorder: 50, 27, 8, 44, 73, 83, 74, 93

50 27 73 8 44 83 74 93 postorder: 8, 44, 27, 74, 93, 83, 73, 50

Binary Search Trees

50 27 73 8 44 83 74 93

Binary Search Trees (BST) the tree from the previous slide is a special kind of binary tree called a binary search tree in a binary search tree: all nodes in the left subtree have data elements that are less than the data element of the root node all nodes in the right subtree have data elements that are greater than the data element of the root node rules 1 and 2 apply recursively to every subtree

50 27 73 8 44 51 83 74 93 76 right subtree (all elements > 50) left subtree (all elements < 50) 50 27 73 8 44 51 83 74 93 76

Implementing a BST what types of data elements can a BST hold? hint: we need to be able to perform comparisons such as less than, greater than, and equal to with the data elements

E must implement Comparable<G> where public class BinarySearchTree<E extends Comparable<? super E>> { E must implement Comparable<G> where G is either E or an ancestor of E

Implementing a BST: Nodes we need a node class that: has-a data element has-a link to the left subtree has-a link to the right subtree

public class BinarySearchTree<E extends Comparable< public class BinarySearchTree<E extends Comparable<? super E>> { private static class Node<E> { private E data; private Node<E> left; private Node<E> right; /** * Create a node with the given data element. The left and right child * nodes are set to null. * * @param data * the element to store */ public Node(E data) { this.data = data; this.left = null; this.right = null; }

Implementing a BST: Fields and Ctor a BST has-a root node creating an empty BST should set the root node to null

/. The root node of the binary search tree /** * The root node of the binary search tree. */ private Node<E> root; * Create an empty binary search tree. public BinarySearchTree() { this.root = null; }

Implementing a BST: Adding elements the definition for a BST tells you everything that you need to know to add an element in a binary search tree: all nodes in the left subtree have data elements that are less than the data element of the root node all nodes in the right subtree have data elements that are greater than the data element of the root node rules 1 and 2 apply recursively to every subtree

/. Add an element to the tree /** * Add an element to the tree. The element is inserted into the tree in a * position that preserves the definition of a binary search tree. * * @param element * the element to add to the tree */ public void add(E element) { if (this.root == null) { this.root = new Node<E>(element); } else { BinarySearchTree.add(element, null, this.root); // recursive static method

/** * Add an element to the subtree rooted at <code>root</code>. The element is inserted into the tree in a * position that preserves the definition of a binary search tree. * * @param element the element to add to the subtree * @param parent the parent node to the subtree * @param root the root of the subtree */ private static <E extends Comparable<? super E>> void add(E element, Node<E> parent, Node<E> root) { if (root == null && element.compareTo(parent.data) < 0) { parent.left = new Node<E>(element); } else if (root == null) { parent.right = new Node<E>(element); else if (element.compareTo(root.data) < 0) { BinarySearchTree.add(element, root, root.left); else { BinarySearchTree.add(element, root, root.right);

Predecessors and Successors in a BST in a BST there is something special about a node's: left subtree right-most child right subtree left-most child

50 27 73 8 44 51 83 74 93 76 right subtree (all elements > 50) left subtree (all elements < 50) 50 27 73 8 44 51 83 rightmost child leftmost child 74 93 76 rightmost child = inorder predecessor leftmost child = inorder successor

Predecessors and Successors in a BST in a BST there is something special about a node's: left subtree right-most child = inorder predecessor the node containing the largest value less than the root right subtree left-most child = inorder successor the node containing the smallest value greater than the root it is easy to find the predecessor and successor nodes if you can find the nodes containing the maximum and minimum elements in a subtree

/. Find the node in a subtree that has the smallest data element /** * Find the node in a subtree that has the smallest data element. * * @param subtreeRoot * the root of the subtree * @return the node in the subtree that has the smallest data element. */ public static <E> Node<E> minimumInSubtree(Node<E> subtreeRoot) { if (subtreeRoot.left() == null) { return subtreeRoot; } return BinarySearchTree.minimumInSubtree(subtreeRoot.left);

/. Find the node in a subtree that has the largest data element /** * Find the node in a subtree that has the largest data element. * * @param subtreeRoot * the root of the subtree * @return the node in the subtree that has the largest data element. */ public static <E> Node<E> maximumInSubtree(Node<E> subtreeRoot) { if (subtreeRoot.right() == null) { return subtreeRoot; } return BinarySearchTree.maximumInSubtree(subtreeRoot.right);

/** * Find the node in a subtree that is the predecessor to the root of the * subtree. If the predecessor node exists, then it is the node that has the * largest data element in the left subtree of <code>subtreeRoot</code>. * * @param subtreeRoot * the root of the subtree * @return the node in a subtree that is the predecessor to the root of the * subtree, or <code>null</code> if the root of the subtree has no * predecessor */ public static <E> Node<E> predecessorInSubtree(Node<E> subtreeRoot) { if (subtreeRoot.left() == null) { return null; } return BinarySearchTree.maximumInSubtree(subtreeRoot.left);

/. Find the node in a subtree that is the successor to the root of the /** * Find the node in a subtree that is the successor to the root of the * subtree. If the successor node exists, then it is the node that has the * smallest data element in the right subtree of <code>subtreeRoot</code>. * * @param subtreeRoot * the root of the subtree * @return the node in a subtree that is the successor to the root of the * subtree, or <code>null</code> if the root of the subtree has no * successor */ public static <E> Node<E> successorInSubtree(Node<E> subtreeRoot) { if (subtreeRoot.right() == null) { return null; } return BinarySearchTree.minimumInSubtree(subtreeRoot.right);

Deletion from a BST to delete a node in a BST there are 3 cases to consider: deleting a leaf node deleting a node with one child deleting a node with two children

Deleting a Leaf Node deleting a leaf node is easy because the leaf has no children simply remove the node from the tree e.g., delete 93

50 27 73 8 44 51 83 delete 93 74 93 76

50 27 73 8 44 51 83 74 76

Deleting a Node with One Child deleting a node with one child is also easy because of the structure of the BST remove the node by replacing it with its child e.g., delete 83

50 27 73 delete 83 8 44 51 83 74 76

50 27 73 8 44 51 74 76

Deleting a Node with Two Children deleting a node with two children is a little trickier can you see how to do it?

Deleting a Node with Two Children replace the node with its inorder predecessor OR inorder successor call the node to be deleted Z find the inorder predecessor OR the inorder successor call this node Y copy the data element of Y into the data element of Z delete Y e.g., delete 50

delete 50 using inorder predecessor 27 73 8 44 51 74 76

50 Z 27 73 8 44 51 74 Y inorder predecessor to Z 76

44 27 73 8 44 51 74 76 copy Y data to Z data Z Y inorder predecessor

44 Z 27 73 delete Y 8 44 51 74 Y 76

44 27 73 8 51 74 76

delete 50 using inorder successor 27 73 8 44 51 74 76

50 Z 27 73 8 44 51 74 Y inorder successor to Z 76

51 27 73 8 44 51 74 76 copy Y data to Z data Z Y inorder successor

51 Z 27 73 delete Y 8 44 51 74 Y 76

51 27 73 8 44 74 76

More Data Structures (Part 1) Stacks

Stack examples of stacks

Top of Stack top of the stack

Stack Operations classically, stacks only support two operations push add to the top of the stack pop remove from the top of the stack throws an exception if there is nothing on the stack

Push st.push("A") st.push("B") st.push("C") st.push("D") st.push("E") top "E" top "D" top "C" top "B" top "A"

Pop String s = st.pop() s = st.pop() top "E" top "D" top "C" top "B" "A"

Applications stacks are used widely in computer science and computer engineering undo/redo widely used in parsing a call stack is used to store information about the active methods in a Java program convert a recursive method into a non-recursive one

Example: Reversing a sequence a silly and usually inefficient way to reverse a sequence is to use a stack

Don't do this public static <E> List<E> reverse(List<E> t) { List<E> result = new ArrayList<E>(); Stack<E> st = new Stack<E>(); for (E e : t) { st.push(e); } while (!st.isEmpty()) { result.add(st.pop()); return result;

Converting a Recursive Method a stack can be used to convert a recursive method to a non-recursive method the key to understanding how to do this lies in the memory diagram for a recursive memory the following slides are from the Day 25 lecture

public static double powerOf10(int n) { double result; if (n < 0) { result = 1.0 / powerOf10(-n); } else if (n == 0) { result = 1.0; else { result = 10 * powerOf10(n - 1); return result;

double x = Recursion.powerOf10(3); 100 main method x powerOf10(3)

600 powerOf10 method 3 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 100 main method x powerOf10(3)

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3)

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result

600 3 10 * powerOf10(2) 100 powerOf10(3) 750 2 10 * powerOf10(1) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * powerOf10(1)

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * powerOf10(1) 800 powerOf10 method n 1 result 10 * powerOf10(0)

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * powerOf10(1) 800 powerOf10 method n 1 result 10 * powerOf10(0) 950 powerOf10 method n result

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * powerOf10(1) 800 powerOf10 method n 1 result 10 * powerOf10(0) 950 powerOf10 method n result 1

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * powerOf10(1) 800 powerOf10 method n 1 result 10 * 1 950 powerOf10 method n result 1

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * powerOf10(1) 800 powerOf10 method n 1 result 10

600 3 10 * powerOf10(2) 100 powerOf10(3) 750 2 10 * 10 800 1 10 double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 10 * 10 800 powerOf10 method n 1 result 10

600 powerOf10 method 3 10 * powerOf10(2) 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * powerOf10(2) 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 100

600 powerOf10 method 3 10 * 100 100 main method powerOf10(3) 750 double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 10 * 100 100 main method x powerOf10(3) 750 powerOf10 method n 2 result 100

600 powerOf10 method 3 1000 100 main method powerOf10(3) double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 1000 100 main method x powerOf10(3)

600 powerOf10 method 3 1000 100 main method 1000 double x = Recursion.powerOf10(3); 600 powerOf10 method n 3 result 1000 100 main method x 1000

double x = Recursion.powerOf10(3); 100 main method x 1000

Using a stack we to simulate what the JVM is doing during the recursive method each recursive call that is not a base case pushes a 10 onto the stack a recursive call that reaches a base case pushes a 1 onto the stack pop the stack until it is empty, multiplying the values as you go

public static int powerOf10(int n) { Stack<Integer> t = new Stack<Integer>(); // recursive calls while (n > 0) { t.push(10); n--; } // base case: n == 0 t.push(1); // accumulate the result int result = t.pop(); while (!t.isEmpty()) { result *= t.pop(); return result;

Converting a Recursive Method using a stack in the previous example is too complicated for the problem that we were trying to solve but it illustrates the basic idea of using a stack to convert a recursive method to an iterative method more complicated examples require greater sophistication in exactly what is pushed onto the stack see the make-up lab (Part 1) when it becomes available

Implementation with ArrayList ArrayList can be used to efficiently implement a stack the end of the list becomes the top of the stack adding and removing to the end of an ArrayList usually can be performed in O(1) time

public class Stack<E> { private ArrayList<E> stack; public Stack() { this.stack = new ArrayList<E>(); } public void push(E element) { this.stack.add(element); public E pop() { return this.stack.remove(this.stack.size() - 1);

Implementation with Array the ArrayList version of stack hints at how to implement a stack using a plain array however, an array always holds a fixed number of elements you cannot add to the end of the array without creating a new array you cannot remove elements from the array without creating a new array instead of adding and removing from the end of the array, we need to keep track of which element of the array represents the current top of the stack we need a field for this index

import java. util. Arrays; import java. util import java.util.Arrays; import java.util.EmptyStackException; public class IntStack { // the initial capacity of the stack private static final int DEFAULT_CAPACITY = 16; // the array that stores the stack private int[] stack; // the index of the top of the stack (equal to -1 for an empty stack) private int topIndex;

/. Create an empty stack. / public IntStack() { this /** * Create an empty stack. */ public IntStack() { this.stack = new int[IntStack.DEFAULT_CAPACITY]; this.topIndex = -1; }

Implementation with Array IntStack t = new IntStack(); this.topIndex == -1 this.stack 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 index

Implementation with Array pushing a value onto the stack: increment this.topIndex set the value at this.stack[this.topIndex]

Implementation with Array IntStack t = new IntStack(); t.push(7); this.topIndex == 0 this.stack 7 1 2 3 4 5 6 8 9 10 11 12 13 14 15 index

Implementation with Array IntStack t = new IntStack(); t.push(7); t.push(-5); this.topIndex == 1 this.stack 7 -5 1 2 3 4 5 6 8 9 10 11 12 13 14 15 index

Implementation with Array popping a value from the stack: get the value at this.stack[this.topIndex] decrement this.topIndex return the value notice that we do not need to modify the value stored in the array

Implementation with Array IntStack t = new IntStack(); t.push(7); t.push(-5); int value = t.pop(); // value == -5 this.topIndex == 0 this.stack 7 -5 1 2 3 4 5 6 8 9 10 11 12 13 14 15 index

/. Pop and return the top element of the stack /** * Pop and return the top element of the stack. * * @return the top element of the stack * @throws EmptyStackException if the stack is empty */ public int pop() { // is the stack empty? if (this.topIndex == -1) { throw new EmptyStackException(); } // get the element at the top of the stack int element = this.stack[this.topIndex]; // adjust the top of stack index this.topIndex--; // return the element that was on the top of the stack return element;

Implementation with Array // stack state when we can safely do one more push this.topIndex == 14 this.stack 7 -5 6 3 2 1 9 -3 -2 4 5 8 10 11 12 13 14 15 index

/. Push an element onto the top of the stack /** * Push an element onto the top of the stack. * * @param element the element to push onto the stack */ public void push(int element) { // is there capacity for one more element? if (this.topIndex < this.stack.length - 1) { // increment the top of stack index and insert the element this.topIndex++; this.stack[this.topIndex] = element; } else {

Adding Capacity if we run out of capacity in the current array we need to add capacity by doing the following: make a new array with greater capacity how much more capacity? copy the old array into the new array set this.stack to refer to the new array push the element onto the stack

else { // make a new array with double previous capacity int[] newStack = new int[this.stack.length * 2]; // copy the old array into the new array for (int i = 0; i < this.stack.length; i++) { newStack[i] = this.stack[i]; } // refer to the new array and push the element onto the stack this.stack = newStack; this.push(element);

Adding Capacity when working with arrays, it is a common operation to have to create a new larger array when you run out of capacity in the existing array you should use Arrays.copyOf to create and copy an existing array into a new array

else { // make a new array with greater capacity int[] newStack = new int[this.stack.length * 2]; // copy the old array into the new array for (int i = 0; i < this.stack.length; i++) { newStack[i] = this.stack[i]; } // refer to the new array and push the element onto the stack this.stack = newStack; this.push(element); int[] newStack = Arrays.copyOf(this.stack, this.stack.length * 2);