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

低代码建站下载建行手机银行官方正式版

低代码建站,下载建行手机银行官方正式版,求个网站这么难吗2022年贴吧,wordpress php.ini在🐵本篇文章将对双向链表进行讲解,模拟实现双向链表的常用方法 一、什么是双向链表 双向链表在指针域上相较于单链表,每一个节点多了一个指向前驱节点的引用prev以及多了指向最后一个节点的引用last: 二、双向链表的模拟实现 首先…

🐵本篇文章将对双向链表进行讲解,模拟实现双向链表的常用方法


一、什么是双向链表

双向链表在指针域上相较于单链表,每一个节点多了一个指向前驱节点的引用prev以及多了指向最后一个节点的引用last

二、双向链表的模拟实现

首先将要模拟实现的方法写到IList接口中:

public interface IList {//头插法插入节点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();}

之后再创建一个MyLinkedList类实现上述接口并重写接口中所有的方法

public class MySingleList implements IList{static class ListNode {public int val;public ListNode next;public ListNode prev;public ListNode(int val) {this.val = val;}}public ListNode head; //指向第一个节点public ListNode last; //指向最后一个节点/*以下是要重写IList接口中的方法*/...}

2.1 模拟实现

public void addFirst(int data);

双向链表的头插法和单链表基本一致,只不过当链表为空时不仅要让head指向新节点还要让last也指向新节点

    public void addFirst(int data) {ListNode newNode = new ListNode(data);if (head == null) {head = newNode;last = newNode;return;}newNode.next = head;head.prev = newNode;head = newNode;}

public void addLast(int data);

当链表为空时要让head和last都指向新节点,当链表部不为空时要让最后一个节点的next指向新节点,之后让新节点的prev指向原来的最后一个节点

    public void addLast(int data) {ListNode newNode = new ListNode(data);if (head == null) {head = newNode;last = newNode;return;}last.next = newNode;newNode.prev = last;last = newNode;}

public void addLast(int data);

在任意位置处插入一个节点,第一个节点的索引为0

首先要判断一下index是否合法:

public class IndexException extends RuntimeException{public IndexException(String message) {super(message);}
}=======================================================public void addIndex(int index, int data) {if (index < 0 || index > size()) { //size()为链表长度throw new IndexException("下标错误");}...
}

在任意位置插入节点,所以如果index为0或等于链表长度,就可以直接使用刚刚实现过的头插和尾插方法

public void addIndex(int index, int data) {if (index < 0 || index > size()) {throw new IndexException("下标错误");}if (index == 0) {addFirst(data);}if (index == size()) {addLast(data);}...
}

一般情况下(在中间插入),单链表中要通过循环找到插入位置的前一个节点,但在双向链表中,直接循环到插入位置(插入位置记为cur)即可

    public void addIndex(int index, int data) {if (index < 0 || index > size()) {throw new IndexException("下标错误");}if (index == 0) {addFirst(data);return;}if (index == size()) {addLast(data);return;}ListNode newNode = new ListNode(data);ListNode cur = head;for (int i = 0; i < index; i++) {cur = cur.next;}/*一般情况下*/newNode.next = cur;cur.prev.next = newNode;newNode.prev = cur.prev;cur.prev = newNode;}

public void remove(int key);

删除第一次出现val = key的节点

先考虑常规情况,即通过遍历找到要删除的节点,这里记为cur

让cur的前驱节点的next指向cur的后继节点,cur的后继节点的prev指向cur的前驱节点

    public void remove(int key) {ListNode cur = head;while(cur != null) {if (cur.val == key) {cur.prev.next = cur.next;cur.next.prev = cur.prev;return;}cur = cur.next;}}

之后有两种特殊情况需要考虑:1.cur为第一个节点;2.cur为最后一个节点;当cur为这两种情况时如果使用上述代码,会引发空指针异常,所以这两种情况要单独考虑

1.cur为第一个节点:此时需要让cur的后继节点prev指向空(cur.prev = null),并让head = head.next,但是这样还有一个小问题:当链表中只有一个节点时也会引发空指针异常,这个问题也要单独处理,只需要直接让head = null即可

if (cur == head) {head = head.next;if (head == null) {last = null;} else {head.prev = null;}return;
}

2.cur为最后一个节点:只需让cur的前驱节点的next指向空,并让last = last.prev;即可

if (cur.next == null) {cur.prev.next = null;last = last.prev;return;
}

remove的最终代码如下:

    public void remove(int key) {ListNode cur = head;while(cur != null) {if (cur.val == key) {if (cur == head) {head = head.next;if (head == null) {last = null;} else {head.prev = null;}return;}if (cur.next == null) {cur.prev.next = null;last = last.prev;return;}cur.prev.next = cur.next;cur.next.prev = cur.prev;return;}cur = cur.next;}}

void removeAllKey(int key);

删除所有val = key的节点,这里只需要将remove方法修改以下即可

    public void removeAllKey(int key) {ListNode cur = head;while(cur != null) {if (cur.val == key) {if (cur == head) {head = head.next;if (head == null) {last = null;} else {head.prev = null;}cur = head;continue;}if (cur.next == null) {cur.prev.next = null;last = last.prev;break;}cur.prev.next = cur.next;cur.next.prev = cur.prev;}cur = cur.next;}}

剩下的contains() 、size()、clear()、display()方法和上篇文章的单链表实现方法一致

三、LinkedList类讲解

LinkedList类是Java提供的类,底层是一个双向链表,包含我们刚刚实现过的方法,LinkedList也实现了List接口

3.1 LinkedList构造方法

LinkedList有两个构造方法:

1.无参构造方法

public LinkedList()

2. 带参构造方法

public LinkedList(Collection<? extends E> c)

该构造方法可以将c构造为双向链表,前提是c实现了Collection接口并且其泛型必须是E或是E的子类,例如:

ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);LinkedList<Integer> list = new LinkedList<>(list1); //list1属于ArrayList类,实现了Collection接口,泛型和list1一样都是Integer,此时顺序表list1就被构造为了双向链表list

3.2 LinkedList类常用方法

    boolean add(E e)  //尾插 evoid add(int index, E element)  //将 e 插入到 index 位置boolean addAll(Collection<? extends E> c) //尾插 c 中的元素E remove(int index)  //删除 index 位置元素boolean remove(Object o)  //删除遇到的第一个 oE get(int index) //获取下标 index 位置元素E set(int index, E element) //将下标 index 位置元素设置为 elementvoid clear() //清空链表boolean contains(Object o) //判断 o 是否在线性表中int indexOf(Object o) //返回第一个 o 所在下标int lastIndexOf(Object o) //返回最后一个 o 的下标List<E> subList(int fromIndex, int toIndex) //截取链表,按左闭右开的区间截取[fromIndex, toIndex)

这些方法的底层实现方式和我们上述模拟实现的方法的实现方式相同

3.3 LinkedList遍历

1. for循环

for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) +" ");
}

2. for-each

for (int x : list) {System.out.print(x +" ");
}

3.迭代器

顺向遍历

ListIterator<Integer> it = list.listIterator();
while(it.hasNext()) {System.out.print(it.next() +" ");
}

逆向遍历

ListIterator<Integer> it1 = list.listIterator(list.size());
while(it1.hasPrevious()) {System.out.print(it1.previous() +" ");
}

🙉本篇文章到此结束,下篇文章会对栈相关知识进行讲解

http://www.yayakq.cn/news/241580/

相关文章:

  • 自助业务网站系统dede企业网站
  • 厚街响应式网站设计dede网站建设很卡
  • 成华区微信网站建设深圳网站建设公司专业
  • 保定网站制作策划网络购物系统
  • 网站名称和备案名称不一样双鸭山建设局网站
  • 企业网站建设代理商网站怎么做域名
  • 网站域名需icp备案wap网页游戏轮回ol
  • 响应式网站 尺寸wordpress 导入数据
  • 佛山网站制作维护哪里有建设网站
  • 网站开发规范有哪些茂南手机网站建设公司
  • 常州网站建设哪家便宜网站建设 设备
  • 用什么制作网站昆明自助建站软件
  • 宿迁做企业网站深圳网站建设 华信科
  • 网站建设实施进度与资源管理网站建设综合报告
  • 淘宝优惠券网站开发wordpress用redis
  • 怎么做论坛的网站学室内设计就是失业
  • 山东莱州市建设局网站qq网页版登录官网登录入口网站
  • 网上做网站怎么赚钱吗页面设计span
  • 国内十大网站建设文创产品推广方案
  • 一个服务器下怎么做两个网站吗360网站建设价格
  • 微信免费建站网站被盗用
  • 动易学校网站管理系统 漏洞云主机 做网站
  • 邯郸本地网站亿驱动力竞价托管
  • 网站推广 公司网站如何建立数据库
  • 学做网站论坛VIP怎么样商标logo设计公司
  • 石家庄网站建设q.479185700棒如何用代码制作网站
  • 廊坊建设网站wordpress 首页无法访问
  • 青岛网站制作计划网页模板图片
  • 许昌知名网站建设价格网页传奇手游游戏大全
  • 怎么把网站提交专业网站的建设设行吗