zoukankan      html  css  js  c++  java
  • 单链表的插入,查找,删除

    链表是一种重要的数据结构,相比于数组,数组更像是一个顺序表,数组只要第一个元素固定,那么在他后面的元素的地址一定固定,数组在内存中是一块连续的存储区域,我们可以根据下标找到他的每个元素,这是数组和链表的一个区别

    链表,见名思意,一个链子连接起来的表,元素之间的联系靠的是这个链子,这也决定了链表中的每个元素不是连续的,第一个元素在内存中的一个地方,而下一个元素可以在离他很远的地方,他们之间有一个链子连接着,这个链子准确来说是指针,第一个元素指向第二个,依次指向下去,我们对某个元素进行操作的时候,我们只能从头依次查找找到这个元素再进行操作。单链表是指单向的链表,我们只能从他的头向后查找,而双向链表,不光可以从头部向后查找,也可以从后向前查找。

    数组的查找,更改方便,而数组的增加,删除方便。数组可以根据下标找到元素,而链表只能从头部依次向后查找,相比于数组的增加,删除操作会涉及到元素的移动,链表就方便很多,我们只需要把他前后的指向的元素改变一下,就可以实现元素的增加和删除。

    对链表的操作也是很基本的操作,下面只是对单链表的操作

    定义一个节点类,定义他的数据域,和next指针(不能说是一个指针,他是下一个元素,指针更好理解)

    package demo_linkedlist;
    
    public class Node {
    	public int element;
    //	public Node pre;
    	public Node next;
    	public Node(){
    		
    	}
    //	public Node(int element,Node pre,Node next){
    //		this.element=element;
    //		this.pre=pre;
    //		this.next=next;
    //	}
    	public Node(int element,Node next){
    		this.element=element;
    		this.next=next;
    	}
    	@Override
    	public String toString() {
    		return element + "->"+next;
    	}
    	
    	
    
    }
    

    在定义节点的时候,定义了一个head头节点,头节点始终指向链表中的第一个元素。这样对链表中的第一个数据进行操作的时候,可以方便些


    一个节点的初始化方法,为什么倒过来定义,因为在定义指向下一个元素的next指针的时候是先定义前一个元素的next指向,然而后一个节点还没有定义,倒过来就解决了。

            private Node n10 = null;
    	private Node n8 = null;
    	private Node n7 = null;
    	private Node n6 = null;
    	private Node n5 = null;
    	private Node n4 = null;
    	private Node n3 = null;
    	private Node n2 = null;
    	private Node n1 = null;
    	private Node head = null;
    
    	public void init() {
    		n10 = new Node(10, null);
    		n8 = new Node(8, n10);
    		n7 = new Node(7, n8);
    		n6 = new Node(6, n7);
    		n5 = new Node(5, n6);
    		n4 = new Node(4, n5);
    		n3 = new Node(3, n4);
    		n2 = new Node(2, n3);
    		n1 = new Node(1, n2);
    		head = new Node(0, n1);
    	}

    遍历节点方法

    /**
    	 * 打印每个节点的值
    	 */
    	public void print() {
    		Node star = head;
    		while (star != null) {
    			System.out.print(star.element + " ");
    			star = star.next;
    		}
    		System.out.println();
    	}

    查找结点值为a的某个节点

    /**
    	 * 查找结点的值
    	 */
    	public Node find(int a) {
    		Node current = n1;
    		while (current.element != a) {
    			if (current.next == null) {
    				return null;
    			}
    			current = current.next;
    		}
    		return current;
    	}

    插入节点,这时候头节点head的作用就用上了,当插入节点值小于链表中的任何元素的时候,为了保证链表的有序,只需要改变头节点的指向就可以

    /**
    	 * 插入一个节点,并保证链表依然有序
    	 */
    	public Node insert(int a) {
    		Node n9 = new Node(a, null);
    		Node current = head;
    		while (current.next != null) {
    			if (a < current.element) {
    				n9.next = current;
    				current.next = n9;
    				break;
    			}
    			if (current.element <= a && current.next.element > a) {
    				n9.next = current.next;
    				current.next = n9;
    				break;
    			}
    			current = current.next;
    		}
    		if (current.element < a && current.next == null) {
    			n9.next = null;
    			current.next = n9;
    		}
    		return current;
    	}

    删除某个节点的方法,由于单链表的特点,我们只能从前向后查找,这样当我们找到要删除的节点的时候,由于前一个节点已经过去了,所以我们只能获得后一个节点,改变不了前一个节点的指向,解决的办法就是只需要定义两个节点,一个指向前一个,另一个指向后一个,每次遍历的时候这两个节点依次向后移动,当找到要操作的节点的时候,由于我们已经记录了前一个节点,这样只需要见到的改变一下指向即可。

    /**
    	 * 删除值为a的节点
    	 */
    	public Node delete(int a) {
    		Node current = head;
    		Node current1 = head.next;
    		while (current1.next != null) {
    			if (current1.element == a) {
    				current.next = current1.next;
    				return current;
    			}
    			current = current.next;
    			current1 = current1.next;
    		}
    		if (current1.next == null) {
    			current.next = null;
    		}
    		return current;
    	}

    完整代码:

    package demo_linkedlist;
    
    /**
     * 在链表中定义了一个head头节点,时钟在链表的头部,在执行插入操作的时候会方便些
     * 
     */
    
    public class LinkedLists {
    	private Node n10 = null;
    	private Node n8 = null;
    	private Node n7 = null;
    	private Node n6 = null;
    	private Node n5 = null;
    	private Node n4 = null;
    	private Node n3 = null;
    	private Node n2 = null;
    	private Node n1 = null;
    	private Node head = null;
    
    	public void init() {
    		n10 = new Node(10, null);
    		n8 = new Node(8, n10);
    		n7 = new Node(7, n8);
    		n6 = new Node(6, n7);
    		n5 = new Node(5, n6);
    		n4 = new Node(4, n5);
    		n3 = new Node(3, n4);
    		n2 = new Node(2, n3);
    		n1 = new Node(1, n2);
    		head = new Node(0, n1);
    	}
    
    	public static void main(String[] args) {
    		LinkedLists l = new LinkedLists();
    		l.init();
    		l.print();// 遍历链表
    		System.out.println("查找:" + l.find(6));
    		l.insert(11);
    		System.out.println("插入数据后:" + l.head);
    		l.delete(11);
    		System.out.println("删除后:" + l.head);
    	}
    
    	/**
    	 * 打印每个节点的值
    	 */
    	public void print() {
    		Node star = head;
    		while (star != null) {
    			System.out.print(star.element + " ");
    			star = star.next;
    		}
    		System.out.println();
    	}
    
    	/**
    	 * 查找结点的值
    	 */
    	public Node find(int a) {
    		Node current = n1;
    		while (current.element != a) {
    			if (current.next == null) {
    				return null;
    			}
    			current = current.next;
    		}
    		return current;
    	}
    
    	/**
    	 * 插入一个节点,并保证链表依然有序
    	 */
    	public Node insert(int a) {
    		Node n9 = new Node(a, null);
    		Node current = head;
    		while (current.next != null) {
    			if (a < current.element) {
    				n9.next = current;
    				current.next = n9;
    				break;
    			}
    			if (current.element <= a && current.next.element > a) {
    				n9.next = current.next;
    				current.next = n9;
    				break;
    			}
    			current = current.next;
    		}
    		if (current.element < a && current.next == null) {
    			n9.next = null;
    			current.next = n9;
    		}
    		return current;
    	}
    
    	/**
    	 * 删除值为a的节点
    	 */
    	public Node delete(int a) {
    		Node current = head;
    		Node current1 = head.next;
    		while (current1.next != null) {
    			if (current1.element == a) {
    				current.next = current1.next;
    				return current;
    			}
    			current = current.next;
    			current1 = current1.next;
    		}
    		if (current1.next == null) {
    			current.next = null;
    		}
    		return current;
    	}
    
    }
    

    如有不对的地方欢迎指正!

  • 相关阅读:
    luogu P3375 【模板】KMP字符串匹配
    leetcode[129]Sum Root to Leaf Numbers
    leetcode[130]Surrounded Regions
    leetcode[131]Palindrome Partitioning
    leetcode[132]Palindrome Partitioning II
    leetcode[133]Clone Graph
    leetcode[134]Gas Station
    leetcode[135]Candy
    leetcode[136]Single Number
    leetcode[137]Single Number II
  • 原文地址:https://www.cnblogs.com/duzhentong/p/7816601.html
Copyright © 2011-2022 走看看