当前位置: 首页 > news >正文

【数据结构】双向链表 - 指南

文章目录

  • 什么是LinkedList
  • LinkedList的使用
    • LinkedList的构造
    • LinkedList的其他常用方法
    • LinkedList的遍历
  • ArrayList和LinkedList的区别


小贴士:建议学习这章之前先看一下上一章的单向链表哦

什么是LinkedList

LinkedList的底层是双向链表结构(链表后面介绍),由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。

在这里插入图片描述
在集合框架中,LinkedList也实现了List接口,具体如下:
在这里插入图片描述
【说明】

  1. LinkedList实现了List接口
  2. LinkedList的底层使用了双向链表
  3. LinkedList没有实现RandomAccess接口,因此LinkedList不支持随机访问
  4. LinkedList的任意位置插入和删除元素时效率比较高,时间复杂度为O(1)
  5. LinkedList比较适合任意位置插入的场景

LinkedList的使用

LinkedList的构造

在这里插入图片描述
我们在顺序表那一章节中(详见顺序表)详细的探讨过构造函数的问题,当时我们知道构造函数时可以传递一个ArrayList类型的表的参数。不过由于只要是Collection的子类都可以传参,所以传递的参数不仅可以是ArrayList,还可以是任意的其他的类型。比如下面这个案例:

public static void main(String[] args) {
// 构造一个空的LinkedList
List<
Integer> list1 = new LinkedList<
>();
List<
String> list2 = new java.util.ArrayList<
>();
list2.add("JavaSE");
list2.add("JavaWeb");
list2.add("JavaEE");
// 使用ArrayList构造LinkedList
List<
String> list3 = new LinkedList<
>(list2);
}

LinkedList的其他常用方法

在这里插入图片描述
这些常用的方法我们很容易就可以模拟实现,并且这些方法在ArrayList那一章中我们就模拟实现过了,所以我们实现一些特殊的方法,具体如下:
还是先建立一个MyList接口,然后再用链表类实现它:

package demo;
public interface MyList {
//头插法
public void addFirst(int data);
//尾插法
public void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key);
//删除第一次出现关键字为key的节点
public void remove(int key);
//删除所有值为key的节点
public void removeAllKey(int key);
//得到单链表的长度
public int size();
public void clear() ;
public void display() ;
}

双向链表类:

package demo;
// 2、无头双向链表实现
public class MyLinkedList
implements MyList{
static class ListNode
{
public ListNode next;
public ListNode prev;
int val;
public ListNode(int val) {
this.val = val;
}
}
ListNode head;
ListNode last;
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data);
if(head == null){
head = last = node;
return;
}
head.prev = node;
node.next = head;
head = node;
}
//尾插法
public void addLast(int data){
ListNode node = new ListNode(data);
if(last == null){
last = head = node;
return;
}
node.prev = last;
last.next = node;
last = node;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
ListNode cur = head;
ListNode node = new ListNode(data);
if(index == 0){
node.next = head;
head.prev = node;
head = node;
return;
}
if(index == size()){
node.prev = last;
last.next = node;
last = node;
return;
}
while(index != 0){
cur = cur.next;
index--;
}
node.next = cur;
node.prev = cur.prev;
cur.prev.next = node;
cur.prev = node;
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = head;
while(cur != null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur = head;
while (cur != null) {
if(cur.val == key) {
//开始删除
if(cur == head) {
head = head.next;
if(head != null) {
head.prev = null;
}
}else {
cur.prev.next = cur.next;
if(cur.next == null) {
last = last.prev;
}else {
cur.next.prev = cur.prev;
}
}
return;
}
cur = cur.next;
}
}
//删除所有值为key的节点
public void removeAllKey(int key){
ListNode cur = head;
while (cur != null) {
if(cur.val == key) {
//开始删除
if(cur == head) {
head = head.next;
if(head != null) {
head.prev = null;
}
}else {
cur.prev.next = cur.next;
if(cur.next == null) {
last = last.prev;
}else {
cur.next.prev = cur.prev;
}
}
}
cur = cur.next;
}
}
//得到单链表的长度
public int size(){
ListNode cur = head;
int count = 0;
while(cur != null){
count++;
cur = cur.next;
}
return count;
}
public void display(){
ListNode cur = head;
while(cur != null){
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
public void clear(){
last = null;
head = null;
}
}

还是建议大家可以跟着自己尝试模拟实现一下

LinkedList的遍历

public static void main(String[] args) {
LinkedList<
Integer> list = new LinkedList<
>();
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(2);
list.add(2,3);
list.add(0,9);
list.addLast(6);
System.out.println("====for循环====");
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
System.out.println("====for each循环====");
for(Integer x : list){
System.out.print(x + " ");
}
System.out.println();
System.out.println("====iterator====");
Iterator<
Integer> it = list.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
System.out.println("====listIterator反向输出====");
ListIterator<
Integer> it2 = list.listIterator(list.size());
while(it2.hasPrevious()){
System.out.print(it2.previous() + " ");
}
System.out.println();
}

在这里插入图片描述
遍历这一部分跟顺序表大差不差,其中迭代器输出的方法还是着重理解一下。

ArrayList和LinkedList的区别

在这里插入图片描述


http://www.sczhlp.com/news/125442/

相关文章:

  • 告别“能源糊涂账”:MyEMS如何帮企业把能耗数据“算明白、用到位”
  • 闸北区网站设计与制作网络域名注册多少钱
  • 新鸿儒网站建设企业网站设计需要了解
  • 大连网站设计哪里有做新手如何建立自己网站
  • 网站建设 服务器 预算报价清单乡村建设网站
  • 免费制作动画网站wordpress搜索页增强
  • 小企业网站建设哪里做得好如果自己制作网站
  • 龙岩网站建设teams熊掌号.net网站模版
  • 写作网站挣钱对比南宁seo诊断
  • 网站展示七牛 wordpress
  • 企业网站的页面信息该如何排放做外贸网站需要注册公司吗
  • 哪些网站是做包装的买好域名之后怎么做网站
  • 更新网站要怎么做呢中国菲律宾签证免签吗
  • 检测网站是否被墙wordpress社交链接设置
  • 建筑公司网站模板网站后台添加图片显示不了
  • 网站怎么设置关键词WordPress 评论框表情
  • 怎么用阿里云做网站正规seo多少钱
  • 产品工业设计网站wordpress 跳转到指定页面 无效
  • 微网站开发项目合作协议新手如何优化网站排名
  • 手机网站如何做外链合肥网站设计建设
  • 怎么建立自己的网站卖东西ps临摹图片做网站的图片犯法吗
  • 酒店网站建设方案书企业网站策划建设方案
  • 完整教程:线程、进程、协程
  • CF913G Power Substring
  • 网站制作哪种好设计新颖的兰州h5制作
  • 怎么用2级目录做网站手机登录不了建设银行网站
  • 网站怎么做百度才会收录医院 网站建设
  • 单页网站 挣钱简单网站首页怎么做
  • net网站开发视频企业网站建设的要素
  • 软件工程第二次作业——第一次个人编程作业