Chain Storage and Implementation of Linear List
- Another way to implement linear tables is chain storage, which uses pointers to connect the units that store data elements in linear tables in turn. This method avoids the disadvantage of using continuous cells to store elements in arrays, so it is no longer necessary to move elements to make room or fill vacancies when performing insertion or deletion operations. However, the price we pay for this is that we need to set pointers in each cell to represent the logical relationship between elements in the table, thus increasing the overhead of additional storage space.
Singly Linked List
- A linked list is a series of units that store data elements through pointers, so each unit has at least two domains, one for the storage of data elements and the other for pointers to other units. A storage unit with one data domain and multiple pointer domains is usually referred to as a node.
Node Interface
package com.wjy.Data_Structure.linearlist.common; public interface Node { /** * Getting Node Data Domain * * @return */ public Object getData(); /** * Setting Node Data Domain * * @param obj */ public void setData(Object obj); }
Single linked list node definition
package com.wjy.Data_Structure.linearlist.common; //Single linked list node definition public class SLNode implements Node { private Object element; private SLNode next; public SLNode() { } public SLNode(Object ele, SLNode next) { this.element = ele; this.next = next; } public SLNode getNext() { return next; } public void setNext(SLNode next) { this.next = next; } /******** Methods of Node Interface **********/ @Override public Object getData() { return element; } @Override public void setData(Object obj) { element = obj; } }
Realization of Linear List with Single Link List
- In order to make the program more concise, we usually add a dummy node, also known as the head node, in front of the single linked list when using the single linked list to realize the linear table. No real data objects are stored in the header node. The next domain of the header node points to the node of element 0 in the linear table. The introduction of the header node can make some boundary conditions in the linear table operation easier to handle.
package com.wjy.Data_Structure.linearlist.listslinkimpl; import com.wjy.Data_Structure.linearlist.common.DefaultStrategy; import com.wjy.Data_Structure.linearlist.common.List; import com.wjy.Data_Structure.linearlist.common.SLNode; import com.wjy.Data_Structure.linearlist.common.Strategy; import com.wjy.Data_Structure.linearlist.exception.OutOfBoundaryException; //Realization of Linear List with Single Link List public class ListSLinked implements List { private Strategy strategy; // Data element comparison strategy private SLNode head; // Single list header node reference private int size;// Number of data elements in a linear table public ListSLinked() { this(new DefaultStrategy()); } public ListSLinked(Strategy strategy) { this.strategy = strategy; head = new SLNode(); size = 0; } /** * Auxiliary Method: Get the precursor node of the node where the data element e is located * * @param e * @return */ private SLNode getPreNode(Object e) { SLNode p = head; while (p.getNext() != null) if (strategy.equal(p.getNext().getData(), e)) return p; else p = p.getNext(); return null; } /** * Auxiliary Method: Get the precursor node of the node where the element with serial number 0<=i<size is located. * * @param i * @return */ private SLNode getPreNode(int i) { SLNode p = head; for (; i > 0; i--) p = p.getNext(); return p; } /** * Auxiliary method: Obtain the node of the element whose serial number is 0<=i<size * * @param i * @return */ private SLNode getNode(int i) { SLNode p = head.getNext(); for (; i > 0; i--) p = p.getNext(); return p; } @Override public int getSize() { return size; } @Override public boolean isEmpty() { return size == 0; } @Override public boolean contains(Object e) { return indexOf(e) != -1; } @Override public int indexOf(Object e) { SLNode p = head.getNext(); int index = 0; while (p != null) if (strategy.equal(p.getData(), e)) { return index; } else { index++; p = p.getNext(); } return -1; } @Override public void insert(int i, Object e) throws OutOfBoundaryException { if (i < 0 || i > size) throw new OutOfBoundaryException("Error, specified insertion number crosses the boundary"); SLNode p = getPreNode(i); SLNode q = new SLNode(e, p.getNext()); p.setNext(q); size++; return; } @Override public boolean insertBefore(Object obj, Object e) { SLNode p = getPreNode(obj); if (p != null) { SLNode q = new SLNode(e, p.getNext()); p.setNext(q); size++; return true; } return false; } @Override public boolean insertAfter(Object obj, Object e) { SLNode p = head.getNext(); while (p != null) if (strategy.equal(p.getData(), obj)) { SLNode q = new SLNode(e, p.getNext()); p.setNext(q); size++; return true; } else { p = p.getNext(); } return false; } @Override public Object remove(int i) throws OutOfBoundaryException { if (i < 0 || i >= size) throw new OutOfBoundaryException("Error, the specified deletion number crosses the boundary."); SLNode p = getPreNode(i); Object obj = p.getNext().getData(); p.setNext(p.getNext().getNext()); size--; return obj; } @Override public boolean remove(Object e) { SLNode p = getPreNode(e); if (p != null) { p.setNext(p.getNext().getNext()); size--; return true; } return false; } @Override public Object replace(int i, Object e) throws OutOfBoundaryException { if (i < 0 || i >= size) throw new OutOfBoundaryException("Error. The specified serial number crosses the boundary."); SLNode p = getNode(i); Object obj = p.getData(); p.setData(e); return obj; } @Override public Object get(int i) throws OutOfBoundaryException { if (i < 0 || i >= size) throw new OutOfBoundaryException("Error. The specified serial number crosses the boundary."); SLNode p = getNode(i); return p.getData(); } }
Simple test cases
package com.wjy.Data_Structure.linearlist.listslinkimpl; import org.junit.Test; import com.wjy.Data_Structure.linearlist.listslinkimpl.ListSLinked; public class ListSLinkedTest { @Test public void testInsert() { ListSLinked list = new ListSLinked(); for (int i = 0; i < 10; i++) { list.insert(i, i + 1); } System.out.println("Delete:" + list.remove(0)); System.out.println(list.contains(1)); list.insertBefore(2, 100); list.insertAfter(2, 101); list.replace(list.getSize() - 1, 1000); for (int i = 0; i < list.getSize(); i++) { System.out.println(list.get(i)); } } }
Data Structure Learning Code Warehouse:
https://git.oschina.net/wjyonlyone/DataStructure