1. Implementation of linked list: without sentinel

1. Linked list linked list

1. Definition

A linked list is a linear collection of data elements, each of which points to the next element, and the storage of elements is not continuous, but the linked list is logically continuous.

2. Classification

①One-way linked list: each element only knows who the next element is

②Doubly linked list: Each element knows its previous element and the next element

 ③ circular linked list

3. Sentinel node

No data is stored, it is used as head and tail to simplify boundary judgment

4. Linked list performance

①Random access (read)

According to the index search, the time complexity is O(n).

When searching for elements based on the index, search one by one from the head node

② Insert or delete

Starting position: O(1)

End position: known tail node is O(1), unknown tail node is O(n)

Middle position: search time according to index + O(1)

Two, one-way linked list, without sentinel

1. Code implementation

 ① Define the node

public class SinglyLinkedList{

	/**
	 * 节点类
	 * 数据域和地址域
	 */
	private static class Node {
		int value;// 值
		Node next;// 指向下一个节点,因为节点的类型是Node

		public Node() {
		}

		public Node(int value, Node next) {
			this.value = value;
			this.next = next;
		}

	}

	private Node head; //头指针
}

②Adding to the head: Each time it is added to the header in turn, pointing the new node to the head at this time. Then let head point to the new node again.

If head is null, head = new Node(value,null)

	public void addFirst(int value) {
		// 1.链表为空时,head是null 相当于head = new Node(value,null)
		// 2.链表不为空时,new Node(value,head) 然后把新节点当为头结点head = new Node(value,head)
		// 3.优化如下
		head = new Node(value, head);
	}

②Tail addition: first find the address of the last node while (p.next != null), if the linked list is empty, return null

	public Node findLast() {
		// 判断是否为空
		if (head == null) {
			return null;
		}
		// 链表不为空
		Node p = head;
		while (p.next != null) {
			p = p.next;
		}
		return p;
	}

What is returned is the address of the last node last.next=new Node(value, null); if the returned value is null, then add it to the header.

	public void addLast(int value) {
		Node last = findLast();
		if (last == null) {
			addFirst(value);
			return;
		}
		// 找到尾巴节点
		last.next = new Node(value, null);
	}

③Traverse node 1: define an auxiliary node p pointing to the head node, the condition is while(p!=null), until the linked list is empty

	/**
	 * 2.遍历节点1
	 */
	public void loop1() {
		Node p = head;
		while (p != null) {
			System.out.println(p.value);
			p = p.next;
		}
	}

	/**
	 * 遍历节点2
	 */
	public void loop2() {
		for (Node p = head; p != null; p = p.next) {
			System.out.println(p.value);
		}
	}

You can also use the enhanced for loop to rewrite iterator()

public class SinglyLinkedList implements Iterable<Integer> {


....

	@Override
	public Iterator<Integer> iterator() {
		return new Iterator<Integer>() {
			Node p = head;
			// 是否有下一个元素
			@Override
			public boolean hasNext() { 
				return p != null;
			}
			// 返回当前元素,指向下一个元素
			@Override
			public Integer next() { 
				int value = p.value;
				p = p.next;
				return value;
			}
		};
	}
}

test with this

Iterator<Integer> iterator = singlyLinkedList.iterator();
		for (Integer integer:singlyLinkedList){
			System.out.println(integer);
		}

④Search get(i) 0,1,2,3... according to the index, first search the node of this index. If not found, return null, if found, return the current node

	public Node findNode(int index) {
		Node p = head;
		int i = 0;
		while (p != null) {
			// 找到了
			if (index == i) {
				return p;
			}
			i++;
			p = p.next;//指向下一个节点
		}
		// 没找到
		return null;
	}

If it is null, it means it is illegal at this time

	public int get(int index){
		Node node = findNode(index);
		if (node == null){
			throw new IllegalArgumentException(
					String.format("inndex[%d]不合法%n",index)
			);
		}
		return node.value;
	}

⑤Insert into the index position, first define the auxiliary node p to point to the previous address of the index, first let the address of the new node point to the address of p, and then let the p node point to the address of the new node. Insertion fails if p is empty. If the index is 0, then call the method added by the header

	/**
	 * 4.insert(int index)
	 * 根据索引插入,插在索引的位置,所以找索引前面的节点
	 */
	public void insert(int index,int value){
		if (index == 0){
			// 插入头位置
			addFirst(value);
			System.out.println("插入成功");
			return;
		}

		Node p = findNode(index-1); // 找到索引的前一个节点
		if (p == null){
			// 链表为空,或者索引超出了范围
			System.out.println("插入失败");
			return;
		}
		// 找到索引的前一个节点
		Node newNode = new Node(value,p.next);
		p.next = newNode;
		System.out.println("插入成功");
	}

⑥: Delete nodes according to the index, first realize the deletion of the head node, let head point to head.next

	public void removeFirst(){
		if (head == null){
			System.out.println("链表为空,删除失败");
			return;
		}
		head = head.next; //
	}

 // delete node

	/**
	 * 删除节点:按照索引
	 */
	public void removeIndex(int index){
		if (index == 0){
			// 删除头结点
			removeFirst();
			return;
		}
		Node prev= findNode(index - 1);
		// 如果为空
		if (prev == null){
			// 链表为空或者超过了索引范围
			System.out.println("删除失败");
			return;
		}
		// 此时node是删除索引的前一个节点
        Node removed = prev.next;
        if (removed == null ){
            System.out.println("删除失败");
        }
		prev.next=removed.next;// 索引的前一个节点,指向索引的后一个节点
		System.out.println("删除成功");
	}

Guess you like

Origin blog.csdn.net/jbkjhji/article/details/130957764