Algorithm and data structure [Java]: common one-way linked list

Keywords: Java

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;
	}
}

 

74 original articles published, 53 praised, 40000 visited+
Private letter follow

Posted by alexks on Sun, 26 Jan 2020 07:01:46 -0800