The data and methods that a common one-way linked list should contain:
Node class:
Properties:
AnyType value; / / any type of data
Node* next; / / pointer to the next node
Methods:
The construction method Node(AnyType* value, Node* next);
Linked list class:
Node* head; / / pointer to the node in the chain header
Node* tail; / / the pointer to the end node of the list. Optional
int length; / / list length, optional
int isEmpty(); / / whether the list is empty
int contains(); / / does the list contain a value
void addToHead(AnyType value); / / add data to the chain header
void addToTail(AnyType value); / / add data to the end of the list
void addNode(AnyType value, int index) / / add data to the specified subscript of the linked list
int deleteFromHead(); / / delete a data from the chain header and return the deleted data
int deleteFromTail(); / / delete a data from the end of the linked list and return the deleted data
int deleteNode(); / / delete the data at the specified subscript and return the deleted data
How to realize each method:
1. Because the properties of LinkedList class are: head, tail, length
So we need to update the three attributes according to different situations
2. Each method should deal with:
1) head changes
2) tail changes
Situation of
Here is the Java code:
//Linked list class public class LinkedList { // Node head; //Pointer to the node in the chain header Node tail; //Pointer to the end node of the list, optional int length; //Chain length, optional int isEmpty() { //Whether the list is empty //The head node is empty and the link list is empty return head == null ? 1 : 0; }; int contains(int value) { //Whether the linked list contains a value //Traverse linked list, find value for (Node now=head; now!=null; now=now.next) if (now.value == value) return 1; return 0; } void addToHead(int value) { //Add data to chain header //If the list is empty, update the head and tail if (head == null) head = tail = new Node(value); //Otherwise add directly else this.head = new Node(value, this.head); this.length++; } void addToTail(int value) { //Add data to the end of the list //If the list is empty, update the head and tail if (head == null) head = tail = new Node(value); //Otherwise add directly else tail = tail.next = new Node(value); length++; } void addNode(int value, int index) { //Add data to the specified subscript of the linked list //If the subscript to be added is illegal, return directly if (index <= 0) return; //If the list is empty and inserted in the first position if (head == null && index == 1) { head = tail = new Node(value); length++; return ; } //If the list is empty, insert it in an illegal position else if (head == null && index != 1) { return ; } //If you insert in the head, update the head if (index == 1) { head = new Node(value, head); length++; return ; } //Insert in other places Node aheadOfAdd = null; int cnt = 1; //Loop through the linked list, find the node at index-1, and store it in ahead of add //There are two conditions that make the cycle stop: //Case 1: ahead of add = null is set independently, indicating that the sequence number to be added has exceeded the length of the existing linked list //Case 2: cnt+1=index is set and ahead of add is empty, indicating that the position to be inserted is just the second position behind the end of the list //Case 3: cnt+1=index holds independently, indicating that the previous node of the node to be inserted is found for (aheadOfAdd=head,cnt=1; aheadOfAdd!=null&&cnt+1<index; cnt++,aheadOfAdd=aheadOfAdd.next); //System.out.println(cnt); //System.out.println(aheadOfAdd); //Situation 1 if (index != cnt+1) return ; //Situation 2 if (aheadOfAdd == null) return ; //Situation 3 aheadOfAdd.next = new Node(value, aheadOfAdd.next); length++; if (aheadOfAdd.next.next == null) tail = aheadOfAdd.next; } int deleteFromHead() { //Delete a data from the chain header and return the deleted data int deletedValue = -1; //Link list is empty, return directly if (head == null) return -1; deletedValue = head.value; //There is only one element in the linked list. Delete and update the head and tail if (head == tail) head = tail = null; //Delete header else head = head.next; length--; return deletedValue; } int deleteFromTail() { //Delete a data from the end of the list and return the deleted data int deletedValue = -1; //Link list is empty, return directly if (head == null) return -1; //There is only one element in the linked list. Delete and update the head and tail if (head == tail) { deletedValue = head.value; head = tail = null; } //Delete tail else { Node now = null; //Traverse to find the tail for (now = head; now.next!=tail; now=now.next); deletedValue = now.next.value; now.next = null; tail = now; } length--; return deletedValue; } int deleteNode(int index) { //Delete the data at the specified subscript and return the deleted data //Illegal subscript, direct return if (index <= 0) return -1; int deletedValue = -1; int cnt = 1; Node now = null; //Link list is empty, return directly if (head == null) return -1; //There is only one node in the linked list and the node to be deleted if (head == tail && index == 1) { deletedValue = head.value; head = tail = null; } //If you want to delete the first node, there will be problems in the lower loop, so handle it separately if (index == 1) { deletedValue = head.value; head = head.next; } else { //Loop to find the node to delete //There are two conditions for loop termination //Case 1: now==null is true. The node to be deleted has reached the end of the list before it is found //Case 2: cnt+1=index is set, and the previous node of the node to be deleted is found for(now=head; cnt+1<index && now!=null; cnt++,now=now.next); //Situation 1 if(now == null) return -1; //Situation 2 deletedValue = now.next.value; if (now.next == tail) tail = now; now.next = now.next.next; } length--; return deletedValue; } //Convert to string for easy display public String toString() { StringBuilder sb = new StringBuilder("LinkedList: ["); for (Node now = head; now!=null; now=now.next) { sb.append(now.value + ", "); } sb.append("]"); if (head != null) sb.append("\n\t\t@ StartValue: " + head.value + "; TailValue: " + tail.value + "; Length: " + length); return sb.toString(); } //Print linked list content void printSelf() { System.out.println(this.toString()); } //Test function static public void main(String[] argv) { LinkedList list = new LinkedList(); list.addToHead(1);list.addToHead(2);list.addToHead(5);list.printSelf(); //list.deleteFromHead();list.deleteFromTail();list.printSelf(); list.addNode(12, 1);list.printSelf(); list.deleteNode(1);list.printSelf(); //System.out.println(list.contains(5)); //System.out.println(list.isEmpty()); } } //Node of linked list class Node{ int value; //Node value Node next; //Pointer to next node //Two constructors public Node(int value) { this.value = value; this.next = null; } public Node(int value, Node next) { this.value = value; this.next = next; } }