《大话数据结构》之双向链表
时间:2022-07-26
本文章向大家介绍《大话数据结构》之双向链表,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1. 简介
前面讲了单向链表实际上就是在保存数据的同时并保存下一个元素的地址值来进行关联,这样就像锁链一样一个套着一个,但是他只能通过当前地址找到下一个元素,不能反向找,就好比我存了我儿子的电话,而我儿子对我不怎么上心手机一直没有存储我的电话,所以他只能等我去联系他,从来不会主动来联系我,因为没办法进行联系。
有一天我很生气,因为我生日他都不给我打电话,因为没有我的联系方式,事后他很内疚,然后存储了我的联系方式,而这就是双向链表就是你可以找到我我也可以找到你,也就是在单向链表中再加一个地址用于存储上一个数据的地址。
双向链表结构如下。
2. 优缺点
和单向链表一样,他的插入和删除操作效率是比线性表的顺序存储要快的,却比单向链表慢因为他在插入和删除时需要维护上一个地址和下一个地址,而单向只需要维护下一个地址,但是他相比单向链表而言可以通过当前的节点找到上一个数据,时间复杂度为O(1),而单向链表要找到上一个节点的数据,那么就需要从头遍历,所以是O(n)。
3. 使用Java代码实现双向链表
package com.bigcat;
/** * 双向链表实现新增 插入 删除 查询 * @param <E> * @author damao * @date 2019/11/13 */public class TwoWayLinkedList<E>{
/** * 头链表,用于后面的遍历 */ Node<E> firstNode;
private Node<E> prevAddress = null;
private int size = 0;
public boolean add(E e){ if(firstNode == null){ prevAddress = firstNode = new Node(null,null,e); size++; return true; } prevAddress = prevAddress.next = new Node(prevAddress,null,e); size++; return true; }
public boolean add(int index,E e){ if(index <= 0){ throw new RuntimeException("Index must be greater than zero"); } if(firstNode == null || index == 1){ firstNode = new Node(null, firstNode, e); size++; return true; } Node<E> theNode = firstNode.next; Node<E> prevNode = firstNode; for (int i = 2; i <= index; i++) { if(i == index){ Node<E> newNode = new Node(prevNode,theNode,e); theNode.prev = newNode; prevNode.next = newNode; size++; return true; } theNode = theNode.next; prevNode = theNode.prev; } return false; }
public boolean remove(int index){ if(index <= 0 || index > size){ throw new RuntimeException("Out of index range"); } if(index == 1){ Node<E> newfirstNode = firstNode.next; firstNode.next = null; firstNode.value = null; firstNode = newfirstNode; size--; return true; } Node<E> theNode = firstNode.next; Node<E> prevNode = firstNode; Node<E> nextNode = theNode.next; for (int i = 2; i <= index; i++) { if(i == index){ theNode.value = null; prevNode.next = theNode.next; if(i != size) { theNode.next.prev = prevNode; } theNode.next = null; theNode.prev = null; size--; return true; } theNode = nextNode.next; prevNode = theNode.prev; nextNode = theNode.next; } return false; }
public E get(int index){ if(index <= 0 || index > size){ throw new RuntimeException("Out of index range"); } Node<E> theNode = firstNode; for (int i = 1; i <= index; i++) { if(i == index){ return theNode.value; } theNode = theNode.next; } return null; }
public int getSize(){ return this.size; }
private static class Node<E>{ Node<E> prev; Node<E> next; E value;
public Node(Node<E> prev, Node<E> next, E value) { this.prev = prev; this.next = next; this.value = value; } }
}
测试结果如下
- 1684: [Usaco2005 Oct]Close Encounter
- 算法模板——Dinic最小费用最大流
- 算法模板——Dinic网络最大流 1
- SQL Server 使用全文索引进行页面搜索
- 2764: [JLOI2011]基因补全
- 1000: A+B Problem(NetWork Flow)
- 博弈论进阶之Multi-SG
- 2929: [Poi1999]洞穴攀行
- SQL Server 执行计划缓存
- 1081: [SCOI2005]超级格雷码
- 1715: [Usaco2006 Dec]Wormholes 虫洞
- 博弈论入门之斐波那契博弈
- 3018: [Usaco2012 Nov]Distant Pastures
- 1755: [Usaco2005 qua]Bank Interest
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 线上工程启动日志不滚动了——通过查看堆栈信息排查的过程(ES批量插入)
- Java中使用方法的注意事项
- 微信小程序转发朋友圈详解
- Error: Protocol error, got "H" as reply type byte
- 树莓派基础实验33:TCRT5000红外循迹传感器实验
- 10W个Java对象有多大
- 一次线程池引发的线上故障分析
- dubbo 启动Failed to save registry store file报错
- 大数据的列式存储格式:Parquet
- springBoot 入门(六)—— 整合Spring框架开启自带的任务调度器执行任务(注解方式)
- java字节流入门(缓冲输出流)
- EsotericSoftware Kryo —— 官方(1)
- Java的I/O类库的基本架构一句话介绍
- 树莓派综合项目1:智能温度测量系统实验
- 一句话ListenableFuture简介