• 链表


    链表是一种用于存储数据集合的数据结构。链表有以下属性:

    • 相邻元素之间通过指针连接。

    • 最后一个元素的后继指针为NULL。

    • 在程序执行过程中,链表的长度可以增加或缩小。

    • 链表的空间能按需分配(直到内存耗尽)。

    • 没有内存空间的浪费(但链表中的指针需要一些额外的内存开销)
      Snipaste_2019-05-09_20-06-30.jpg

    与链表对应的数组

    整个数组所有的元素都存储在操作系统分配的一块内存中。访问该数组内的元素时,根据数组元素数据类型的存储空间大小,数组对象的基地址和要访问的元素距基地址的偏移量,就可以在常数时间内计算出元素的地址。

    1、因此数组的优点有

    • 简单且易用
    • 访问元素快(常数时间)

    2、数组的缺点有

    • 大小固定:数组的大小静态的(在使用前指定数组的大小)
    • 分配一个连续的空间块
    • 基于位置的插入操作实现复杂

    单向链表

    链表通常指单向链表,它包含多个结点,每个结点有一个指向后继元素的next(下一个)指针。表中最后一个结点的next指针为NULL,表示该链表的结束:
    Snipaste_2019-05-09_20-34-10.jpg

    实现:

    public class ListNode {
    	private int data;
    	private ListNode next;
    	public ListNode(int data) {
    		this.data = data;
    	}
    	public int getData() {
    		return data;
    	}
    	public void setData(int data) {
    		this.data = data;
    	}
    	public ListNode getNext() {
    		return next;
    	}
    	public void setNext(ListNode next) {
    		this.next = next;
    	}
    	
    	// 链表的遍历
    	public void listPrint(ListNode headNode) {
    		ListNode currentNode = headNode;
    		while(currentNode != null) {
    			System.out.print(currentNode.getData()+" ");
    			currentNode = currentNode.getNext();
    		}
    	}
    	// 统计链表的长度
    	public int listlength(ListNode headNode) {
    		int length = 0;
    		ListNode currentNode = headNode;
    		while(currentNode != null) {
    			length++;
    			currentNode = currentNode.getNext();
    		}
    		return length;
    	}
    	
    	// 链表的插入
    	public ListNode InsertLinkedList(ListNode headNode, ListNode nodeToInsert, int position) {
    		if (headNode == null){ // 若链表为空,插入
    			return nodeToInsert;
    		}
    		int size = listlength(headNode);
    		if(position > size+1 || position < 1) {
    			System.out.println("Position of node to insert is invalid. The valid inputs are 1 to"+ (size+1));
    			return headNode;
    		}
    		if(position == 1) { // 在链表开头插入
    			nodeToInsert.setNext(headNode);
    			return nodeToInsert;
    		} else { 	// 在中间或者末尾插入
    			ListNode previousNode = headNode;
    			int count = 1;
    			while(count < position-1) {
    				previousNode = previousNode.getNext();
    				count++;
    			}
    			ListNode currentNode = previousNode.getNext();
    			nodeToInsert.setNext(currentNode);
    			previousNode.setNext(nodeToInsert);
    		}
    		return headNode;
    	}
    	
    	// 删除链表的结点
    	public ListNode deleteNodeFromLinkedList(ListNode headNode, int position) {
    		int size = listlength(headNode);
    		if (position > size || position < 1) {
    			System.out.println("Position of node to delete is invalid,The valid inputs are 1 to "+size);
    			return headNode;
    		}
    		if (position == 1) { // 删除表头结点
    			ListNode currentNode = headNode.getNext();
    			headNode = null;
    			return currentNode;
    		} else {			// 删除中间或表尾结点
    			ListNode previousNode = headNode;
    			int count = 1;
    			while(count < position-1) {
    				previousNode = previousNode.getNext();
    				count++;
    			}
    			ListNode currentNode = previousNode.getNext();
    			previousNode.setNext(currentNode.getNext());
    			currentNode = null;
    		}
    		return headNode;
    	}
    	
    	// 删除链表
    	public void deleteLinkedList(ListNode head) {
    		ListNode auxiliaryNode, iterator = head;
    		while(iterator != null) {
    			auxiliaryNode = iterator.getNext();
    			iterator = null;			// 在Java中,垃圾回收器自动处理
    			iterator = auxiliaryNode;	
    		}
    	}
    

    双向链表

    双向链表:对于表中的一个结点,可以从两个方向进行操作,每个结点有前驱指针和后继指针。

  • 相关阅读:
    专题1
    HDU-6968(DP,和DP)
    ios环境下H5 input 选择图片在函数回调中失效的问题
    vue自定义组件的坑:数组绑定与引号的使用
    关于布局的胡言乱语
    flex布局小结
    微信小程序中overflow:scroll失效的问题
    微信小程序图片的比例问题
    vue用多了反而疏忽了选择器的使用
    在vue项目中做一个类ctrl+f的搜索功能
  • 原文地址:https://www.cnblogs.com/minghaiJ/p/10841236.html
Copyright © 2020-2023  润新知