Chapter 4 Data Structures ADT Examples Stack Queue Trees
Data structures in Java Java provides a set of data structures… well, we can implement a set of data structures using Java. There is a major difference between C/C++ and Java –dynamic data structures (C/C++ uses pointers) –static data structures (no pointers, however this does not prevent us from implementing data structures in Java)
Stack Class Stack (LIFO data structure) can be implemented as the following Class: class Stack { …. Stack() { … } boolean empty() { … } void push(Object o) { … } Object pop() { … } Object peek() { … } } An application - check if balanced parentheses, e.g. (a+sin(x)-A[i-j])/(cos(x)+{p-q}/{m-n})
An Application - Balanced Parenthesis Checking class ParenMatcher { …. private boolean match(char c,char d) { switch(c) { case ‘(‘ : return (d==‘)’); case ‘[‘ : return (d==‘]’); case ‘{‘ : return (d==‘}’); default : return false; }
...Parenthesis Checking public void parenMatch() { Stack s = new Stack(); int n = inputString.length(); int i= 0; char c,d; while (i<n) { d=inputString.charAT(i); if (d==‘(‘ || d==‘[‘ || d==‘{‘) s.push(new Character(d)); else if (d==‘)‘ || d==‘]‘ || d==‘}‘) if (s.empty()){ output(“More right parenthesis than left”); return;} else {c = ((Character)s.pop()).charValue(); if (!match(c,d)){ output(“Mismatched parenthesis”); return;}} ++i;} }
Array Implementation (for Stack) class Stack { private int count, capacity, capacityIncr; private Object[] itemArray; public Stack() { count=0; capacity=10; capacityIncr=5; itemArray = new Object[capacity]; } itemArray countcapacity capacityIncr
Stack Methdos public boolean empty() {return (count==0); } public Object pop(){ if (count==0) return null; else {return itemArray[--count];} } public Object peek(){ if (count==0) { return null; } else {return itemArray[count-1];} }
More Methods public void push(Object ob) { if (count==capacity){ capacity += capacityIncr; Object[] tempArray = new Object[capacity]; for (int i=0; i<count; i++) {tempArray[i] = itemArray[i];} itemArray=tempArray; } itemArray[count++]=ob; }
Linked-List Implementation (for Stack) class StackNode { Object item; StackNode link; } itemlink An Object
Stack Class class Stack { private StackNode topNode; public Stack() { topNode=null; } public boolean empty() {return(topNode==null);} public Object pop() { if (topNode==null) { return null; } else { StackNode temp=topNode; topNode=topNode.link; return temp.item; }
More Methods public Object peek() { if (topNode==null) return null; else return topNode.item; } public void push(Object ob) { StackNode newNode = new StackNode(); newNode.item = ob; newNode.link = topNode; topNode = newNode; }
Queue Class Stack (LIFO data structure) can be implemented as the following Class: class Stack { …. Queue() { … } ; boolean empty() { … }; void insert(Object o) { … };// at back Object remove() { … };// from fornt } Useful for simulation, etc. Queue on a Circular Track – Advance front & rear one, as follows: front=(front+1) % size; rear=(rear+1) % size; front rear A B C D E F G count 7
Circular Array Implementation (for Queue) class Stack { private int front,rear,count,capacity, capacityIncr; private Object[] itemArray; public Queue() { front=0; rear=0; count=0; capacity=10; capacityIncr=5; itemArray = new Object[capacity]; } public boolean empty() {return (count==0); } public Object remove() { if (count==0) { return null; } else {Object tempitem = itemArray[front]; front=(front+1) % capacity; count--; return tempitem;} }
More Methods public void insert(Object ob) { if (count==capacity){ capacity+=capacityIncr; Object[] tempArray = new Object[capacity];..copy to new array & assign to itemArray.. } itemArray[rear]=ob; rear=read+1 % capacity; count++; }
Trees Trees are useful for organising complex data & for representing expressions. * fact if 5 > n root internal nodes leaves Level 0 Level 1 Level 2 Level 3
Binary Trees A binary tree is either an empty tree, or a node whose left and right subtrees are binary trees. class TreeNode{ Object info; TreeNode left, right; TreeNode(Object ob, TreeNode l,r) {info=ob;left=l;right=r;} TreeNode(Object ob) {info=ob;left=null;right=null;} } data constructor
Creating a tree: * + / empty trees t2 t1 TreeNode t1=new TreeNode(“/”,new TreeNode(“6”),new TreeNode(“3”)); TreeNode t2=new TreeNode(“*”,new TreeNode(“8”),new TreeNode(“+”,t1,new TreeNode(“7”)));
Tree Traversals There are three common ways of tree traversals pre-order traversal in-order traversal post-order traversal
void preOrder(TreeNode t) { if (t!=null) { process(t.info); preOrder(t.left); preOrder(t.right); } void inOrder(TreeNode t) { if (t!=null) { inOrder(t.left); process(t.info); inOrder(t.right); } void postOrder(TreeNode t) { if (t!=null) { postOrder(t.left); postOrder(t.right); process(t.info); } preOrder(t2) * 8 + / inOrder(t2) 8 * 6 / post-Order(t2) / 7 + *
Data for Binary Search Tree class TreeNode{ CompareKey key; TreeNode left; TreeNode right; } class BinarySearchTree { private TreeNode rootNode; public BinarySearchTree() {TreeNode = null} …// methods static TreeNode find(TreeNode t, CompareKey k) {…} void insert(CompareKey k) {…} } Node and BST declarations.
CompareKey Interface For polymorphism, BST stores Objects. However their keys need to be comparable. Hence, we should define an interface of the following. interface CompareKey { // if k1 & k2 are CompareKeys, then k1.compareTo(k2) // returns either // 0, +1, -1 according to k1==k2, k1>k2, or k1<k2 in the // ordering defined int compareTo(CompareKey value); }
IntegerKey class IntegerKey implements CompareKey{ private Integer key; … // additional data possible IntegerKey(Integer value) {key=value); IntegerKey(int value) {key=new Integer(value)); public int compareTo(CompareKey val){ int a = this.key; int b = ((IntegerKey)val).key; if (a.intvalue == b.intvalue) return 0; else return (a.intvalue < b.intvalue) ? -1 : +1 ; }
BST Method : Find a Node To find a node in a BST, we have: static TreeNode find(TreeNode t, CompareKey k) { if (t==null) return null; else if ((result=k.compareTo(t.key))==0) return t; else if (result >0) return find(t.right,k); else return find(t.left,k); }
BST Method : Insert a Node a recursive insertion function: void insert(CompareKey k) { rootNode = insertKey(rootNode,k); } private static TreeNode insertKey(TreeNode t,CompareKey k) { if (t==null) { TreeNode n = new TreeNode(); n.key = k; return n; } else if (k.compareTo(t.key)>0 { t.right = insertKey(t.right,k); return t; } else { t.left = insertKey(t.left,k); return t; }