// File: LinkedList.java // Date: 7/4/2008 package org.bot.jscheme.linkedlist; /** * A Node has two fields, data and next (or car and cdr). * This forms the basis of a simple, singly-linked list structure * whose contents can be manipulated with cons, car, and cdr. * * @author Berlin Brown */ public class LinkedList { /** * Head element in linked list. */ public Node head; private LinkedList() { } public LinkedList(Node head) { this.head = head; } public LinkedList(String data) { this.head = new Node(data, null); } public Node getHead() { return this.head; } /** * Add a new node and replace the "root" node with the new one. * * @param node * @return */ public LinkedList insertHead(final Node node) { node.setNext(head); head = node; return this; } public void insertTail(final Node node) { if (head == null) { head = node; } else { Node p, q; // Traverse to the end of the list for (p = head; (q = p.getNext()) != null; p = q) { ; } p.setNext(node); } } public String traverse() { // Append the contents to a string StringBuffer buf = new StringBuffer(); buf.append("("); buf.append(this.getHead()); for (Node node = this.getHead().getNext(); node != null; node = node.getNext()) { buf.append(' '); buf.append(node.getData()); } buf.append(")"); return buf.toString(); } /** * Perform an arithmetic operation on the List. * @param operation * @return */ public double numCompute(final char operation) { double result = 0.0; if (operation == '+' || operation == '-') { result = 0.0; } else if (operation == '*' || operation == '/') { result = 1.0; } else { throw new RuntimeException("Invalid Operation: try +, -, *, /"); } for (Node node = this.getHead(); node != null; node = node.getNext()) { Double d = new Double((String) node.getData()); double x = d.doubleValue(); switch (operation) { case '+': result += x; break; case '-': result -= x; break; case '*': result *= x; break; case '/': result /= x; break; default: throw new RuntimeException("Invalid Operation: try +, -, *, /"); } } return result; } public String stringify() { return this.getHead().stringifyNode(); } public String toString() { //return this.stringify(); return this.traverse(); } private int passed = 0; public Object fail(final String msg, final String a, final String b) { testStatus(); throw new RuntimeException("FAIL: ! Test Failed [" + msg + "] a => " + a + " b => " + b); } public void testStatus() { System.out.println("#Tests passed => " + passed); } public void assertEquals(final String a, final String b) { if ((a == b) && a == null) { // TODO: ok, I had a "what is pi" moment with this one passed++; return; } else if ((a == null) || b == null) { fail("null found", a, b); } else if (a.equals(b)) { passed++; return; } else { fail("not equal", a, b); } } public static void main(String [] args) { System.out.println("Running linked list test"); final LinkedList list = new LinkedList("+"); list.assertEquals("" + list, "(+)"); // Start off backwards; insert using insertHead. list.insertHead(new Node("1", null)); list.insertHead(new Node("2", null)); list.insertHead(new Node("3", null)); list.assertEquals("" + list, "(3 2 1 +)"); list.testStatus(); list.assertEquals( "(3 2 1 +)", list.getHead().stringifyNode()); final Node node = new Node("+", new Node("1", null)); list.assertEquals( "(+ 1)", node.stringifyNode()); final Node node2 = new Node("+", new Node("1", new Node("2", null))); list.assertEquals( "(+ 1 2)", node2.stringifyNode()); final Node node3 = new Node("+", new Node("1", new Node("2", null))); final LinkedList list2 = new LinkedList(node3); list.assertEquals( "(+ 1 2)", list2.getHead().stringifyNode()); list.assertEquals( "(+ 1 2)", "" + list2); final LinkedList list3 = new LinkedList("+"); list3.assertEquals("" + list3, "(+)"); list3.insertTail(new Node("1", null)); list3.insertTail(new Node("2", null)); list3.insertTail(new Node("3", null)); list.assertEquals("" + list3, "(+ 1 2 3)"); list.testStatus(); final LinkedList list4 = new LinkedList("1"); list4.insertTail(new Node("2", null)); list4.insertTail(new Node("3", null)); list4.insertTail(new Node("4", null)); list.assertEquals("" + list4, "(1 2 3 4)"); list.assertEquals("" + list4.numCompute('+'), "10.0"); list.assertEquals("" + list4.numCompute('*'), "24.0"); } }