Linked List
unknown
java
3 years ago
11 kB
12
Indexable
import java.util.Collection; import java.util.Iterator; public class linkedLists{ public static void main(String[] args){ //Create 10 names stored in a linked list //test each method //methods to test //add, remove, indexOf, get, lastIndexOf, set, isEmpty, addFirst, addLast, getLast, removeFirst, removeLast MyLinkedList<String> list = new MyLinkedList<>(); list.add("Dog"); for (String e: list){ System.out.println("1"); } } } //lets make the myList interface and then we will use it to build the linked list class //start by writing down all the methods, then go back later to implement when designing linked list class interface myList<E> extends Collection<E>{ //add it onto this specific index, the current element at this index is shifted to the right of the list(index +1) public void add(int index, E e); //value at certain index public E get(int index); //first matching index of e //-1 if not there public int indexOf(Object e); //return the last index seen of E //Run and use logic: if ele == e, int = index, return int at end //how do we know we've reached the end? while list.next != null //-1 if not there public int lastIndexOf(E e); //traverse index times, remove it. Update pointer of last dude, or do we just let it point? //return the removed item public E remove(int index); //traverse index times, update value //return the new Object public E set(int index, E e); @Override //add something to the end, while next not null, keep going. when next is null add to end, modify pointer public default boolean add(E e){ add(size(), e); return true; } @Override public default boolean isEmpty(){ return size()==0; } @Override public default boolean remove(Object e){ if (indexOf(e) >= 0){ remove(indexOf(e)); return true; } else return false; } } class MyLinkedList<E> implements myList<E>{ //What is Node? A self-defined class to help us keep track of who we are and who is next. //By default Node<E>.next is null until we link them with our implemented methods private static class Node<E> { E element; Node<E> next; public Node(E e) { this.element = e; } } private Node<E> head, tail; private int size = 0; public MyLinkedList(){ //this is just a list with nodes both head and tail with values Null } public MyLinkedList(E[] objects){ for(int i = 0; i < objects.length; i++){ add(objects[i]); } } public E getFirst(){ if (size() == 0){ return null; } else return head.element; } public E getLast(){ if (size() == 0){ return null; } else return tail.element; } public void addFirst(E e){ Node<E> newNode = new Node<>(e); //this spawns a new node, lets connect it to our current list by making this the head Node //and our newNode.next to be the previous head, then increase the size newNode.next = head; head = newNode; size++; //what if we only have one element? We can tell if this the last one when tail is null //then we set if (tail == null){ tail = head; head.next = null; } } public void addLast(E e){ Node<E> newNode = new Node<>(e); //we get the end.next and set it to newNode. How do we get to end? //we are constantly tracking the end with tail. Tail's .next always should point to null //so lets assign tail.next to newNode and then update tail to newNode //Once tail = newNode, it's .next won't be defined anymore and is null //if the list we're adding to is empty if (tail == null){ head = tail = newNode; } else{ tail.next = newNode; tail = newNode; } size++; //dont forget the size } public E removeFirst(){ //to remove, we have to set head to head.next and decrement size if (size() == 0){ return null; }else{ Node<E> newNode = head; head = head.next; size--; if (head == null){ tail = null; }//if our operation results in an empty list lets delete relationships return newNode.element; } } public E removeLast(){ //we have to know what comes before tail, so we need traversal if (size() == 0){ return null; }else if(size == 1){ Node<E> newNode = head; head = null; tail = head; size = 0; return newNode.element; }else{ Node<E> current = head; for (int i = 0; i < size()-2; i++){ current = current.next; } tail = current; tail.next = null; size--; return current.element; } } //Benearth are all of the need to be implemented methods @Override public String toString(){ StringBuilder result = new StringBuilder("["); Node<E> current = head; for (int i = 0; i < size; i++){ result.append(current.element); if (current != null){ result.append(", "); } else{ result.append("]"); } } return result.toString(); } @Override public int size() { // TODO Auto-generated method stub return size; } @Override public boolean contains(Object o) { //edge cases? if (size() == 0){ return false; } Node<E> current = head; while(current != null){ if (current.element == o){ return true; } } return false; } @Override public Iterator<E> iterator() { // TODO Auto-generated method stub return new LinkedListIterator(); } private class LinkedListIterator implements java.util.Iterator<E>{ Node<E> current = head; @Override public boolean hasNext() { return (current != null); } @Override public E next() { E e = current.element; current = current.next; return e; } @Override public void remove(){ current = current.next; size--; } } @Override public Object[] toArray() { // TODO Auto-generated method stub return null; } @Override public <T> T[] toArray(T[] a) { // TODO Auto-generated method stub return null; } @Override public boolean containsAll(Collection<?> c) { // TODO Auto-generated method stub return false; } @Override public boolean addAll(Collection<? extends E> c) { // TODO Auto-generated method stub return false; } @Override public boolean removeAll(Collection<?> c) { // TODO Auto-generated method stub return false; } @Override public boolean retainAll(Collection<?> c) { // TODO Auto-generated method stub return false; } @Override public void clear() { //empty everything size = 0; head = tail = null; //by setting head tail and size to 0 we have eliminated a wa } @Override public void add(int index, E e) { //how do we add? Well lets think about edge cases. //If we have no elements, lets do a simple add(e) //If we want to add to the front, lets addFirst(e) //if we want to add to the end, lets do addLast(e) //addlast handles issues for empty list, but we specify an index if (index == 0){ addFirst(e); } else if(index >= size()){ addLast(e); } //we shall start at the head and move .next until we get to our specified index //take note of our location our location's .next will be held temporarily //We set our location's next to e, then we set e's next to temp Node<E> current = head; for (int i = 0; i < index; i++){ current=current.next; } Node<E> temp = current.next; current.next = new Node<>(e); current.next.next = temp; size++; //increase size the ocky way } @Override public E get(int index) { //traverse to index, return element if(index > size()){ return null; } Node<E> current = head; for (int i = 0; i < index; i++){ current = current.next; } return current.element; } @Override public int indexOf(Object e) { // return index of occurance of e // return -1 if not found Node<E> current = head; for(int i = 0; i < size(); i++){ if (current.element == e){ return i; } } return -1; } @Override public int lastIndexOf(E e) { Node<E> current = head; int idx = -1; for(int i = 0; i < size(); i++){ if (current.element == e){ idx = i; } current = current.next; } return idx; } @Override public E remove(int index) { //traverse to an index while keeping track of previous //edge cases like removing from empty list or removing from index > size handled by removeLast() if (index == 0){ return removeFirst(); } if (index == size()-1){ return removeLast(); } Node<E> prev = head; //how we start at the top for (int i=0; i < index; i ++){ prev = prev.next; } //after arriving at the element, we shall link to to nextnext instead //we need to know what curr is to return it Node<E> current = prev.next; prev.next = prev.next.next; size--; return current.element; } @Override public E set(int index, E e) { if (index >= size()){ return null; } //traversal code Node<E> current = head; for (int i = 0; i < index; i++){ current = current.next; } current.element = e; return current.element; } }
Editor is loading...