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

java 双向链表循环_Java实现双向循环链表

双向循环链表定义

相比于单链表,有两个指针,next指针指向下一个结点,prior指针指向上一个结点,最后一个结点的next指针指向头结点,头结点的prior指针指向最后一个结点

代码实现:

我们对单链表的实现加以修改

package algorithm.datastructure.doublelinkedlist;

import java.util.NoSuchElementException;

/**

* 双向循环链表

* 两个指针,next指针指向下一个结点,prior指针指向上一个结点,最后一个结点的next指针指向头结点,

* 头结点的prior指针指向最后一个结点

* */

public class LinkedList {

private Node head;//头节点

private int size;//链表长度

static private class Node{

private int data;//数据

private Node next;//下一个结点

private Node prior;//上一个结点

public Node(){

}

public Node(int data){

this.data=data;

}

private Node(int data,Node next){

this.data=data;

this.next=next;

}

public Node(Node prior,int data,Node next){

this.prior=prior;

this.data=data;

this.next=next;

}

}

//初始化空链表

public LinkedList(){

//head=null;

}

//添加元素

public Boolean add(int element){

linkLast(element);

return true;

}

//在某个位置之前添加元素

public Boolean add(int index,Integer element){

checkPositionIndex(index);

if (index==size){

linkLast(element);

} else {

linkBefore(element,node(index));

}

return true;

}

//根据下标获取元素

public int get(int index){

checkElementIndex(index);

return node(index).data;

}

//获取第一个元素

public Integer getFirst(){

Node f=head;

if (f==null){

throw new NoSuchElementException();

} else {

return f.data;

}

}

//获取最后一个元素

public Integer getLast(){

if (size==0){

throw new NoSuchElementException();

}

return head.prior.data;

}

//删除第一个元素

public Integer removeFirst(){

Node f=head;

if (f==null){

throw new NoSuchElementException();

} else {

return unlink(head);

}

}

//删除最后一个元素

public Integer removeLast(){

if (size==0){

throw new NoSuchElementException();

}

int index=size-1;

return unlink(node(index));

}

//根据索引删除元素

public Integer remove(int index){

checkElementIndex(index);

return unlink(node(index));

}

//销毁链表

public void destroyList(){

clearList();

}

//将链表置为空表

public void clearList() {

for (Node p=head;p!=null;){

Node next=p.next;//记录下一个结点

p=null;//删除当前结点

p=next;//指向下一个结点

}

size=0;

head=null;

}

//遍历链表

public void traverseList(Boolean isReverseVisited){

if (!isEmpty()){

if (!isReverseVisited){

for (Node p=head;p!=head.prior;p=p.next){

System.out.println(p.data);

}

System.out.println(head.prior.data);

} else {

for (Node p=head.prior;p!=head;p=p.prior){

System.out.println(p.data);

}

System.out.println(head.data);

}

}

}

//返回链表元素个数

public int size(){

return size;

}

public Boolean isEmpty(){

return size==0;

}

/**双向链表插入一个结点,要改变的指针如下:

*

*(1)前一个结点的next指针

*(2)后一个结点的prior指针

*(3)新创建的结点的prior指针和next指针

* */

//尾部添加结点

private void linkLast(int element){

if (size==0){//没有结点时

head=new Node(element);

head.next=head;

head.prior=head;

size++;

} else {

//得到最后一个结点

Node oldTail=head.prior;

//new新的尾结点 newTail

//newTail的前一个结点设置为旧的尾结点,

//newTail的后一个结点指向head

Node newTail=new Node(oldTail,element,head);

//head的下一个结点指向newTail

head.prior=newTail;

//旧的尾结点的下一个结点指向新的尾结点

oldTail.next=newTail;

size++;

}

}

//在某结点之前插入结点

private void linkBefore(int element,Node node){

if (node==null){

linkLast(element);

} else {

Node p=head;

if (node.data==p.data){

Node q=p.prior;

Node newNode=new Node(q,element,p);

q.next=newNode;

p.prior=newNode;

size++;

} else {

for (p=p.next;p!=head;){

if (node.data==p.data){

Node q=p.prior;

Node newNode=new Node(q,element,p);

q.next=newNode;

p.prior=newNode;

size++;

}

p=p.next;

}

}

}

}

/*

* 双向链表删除一个结点:

* (1)找到该结点

* (2)找到该结点的前一结点(prior)p和下一结点(next)q

* (3)p的next指针指向q,q的prior指针指向p

* (4)如果是删除的是头结点,指明当前头结点

* */

//删除结点

private Integer unlink(Node node){

Integer deleteNodeData=node.data;

Node p=null,q=null;

if (deleteNodeData==head.data){//该结点为头结点

Node cur=head;

p=head.prior;

q=head.next;

p.next=q;

q.prior=p;

head=q;

cur=null;

size--;

} else {

Node m;

for (m=head.next;m!=head;){

if (m.data==deleteNodeData){

p=m.prior;

q=m.next;

p.next=q;

q.prior=p;

m=null;

size--;

break;

}

m=m.next;

}

}

return deleteNodeData;

}

//数组下标是否越界

private Boolean isElementIndex(int index){

return index>=0&&index

}

//插入位置是否越界

public Boolean isPositionIndex(int index){

return index>=0&&index<=size;

}

//检验下标是否越界,抛出异常

private void checkElementIndex(int index){

if(!isElementIndex(index)){

try {

throw new IndexOutOfBoundsException("下标越界");

} catch (Exception e) {

e.printStackTrace();

}

}

}

//检验插入下标是否越界,抛出异常

private void checkPositionIndex(int index){

if(!isPositionIndex(index)){

try {

throw new IndexOutOfBoundsException("下标越界");

} catch (Exception e) {

e.printStackTrace();

}

}

}

//返回指定位置的元素

private Node node(int index){

int nowIndex = 0;

if(size>0){

for (Node p=head;p!=head.prior;){

if (nowIndex==index){

return p;

}

p=p.next;

nowIndex++;

}

if (nowIndex==index){

return head.prior;

}

}

return null;

}

public static void main(String[] args) {

java.util.LinkedList linkedList0=new java.util.LinkedList();

linkedList0.add(6);

linkedList0.remove(0);

linkedList0.size();

linkedList0.peek();

//linkedList0.getFirst();

linkedList0.clear();

//测试

LinkedList linkedList=new LinkedList();

linkedList.add(2);

linkedList.add(3);

linkedList.add(5);

linkedList.add(7);

linkedList.add(1);

linkedList.add(33);

linkedList.add(4,0);

linkedList.add(3,1);

linkedList.add(7,6);

linkedList.add(0,10);

linkedList.add(10,11);

linkedList.remove(0);

linkedList.remove(0);

linkedList.remove(0);

linkedList.remove(1);

linkedList.remove(4);

linkedList.remove(5);

linkedList.remove(0);

// linkedList.remove(0);

// linkedList.remove(0);

// linkedList.remove(0);

// linkedList.remove(0);

System.out.println(linkedList.get(0));

System.out.println(linkedList.get(1));

System.out.println(linkedList.get(2));

System.out.println(linkedList.get(3));

System.out.println(linkedList.getFirst());

System.out.println(linkedList.getLast());

linkedList.removeFirst();

linkedList.removeLast();

System.out.println("遍历链表");

linkedList.traverseList(false);

// System.out.println("逆向遍历链表");

// linkedList.traverseList(true);

System.out.println("链表长度");

System.out.println(linkedList.size());

linkedList.clearList();

}

}

总结

以上就是Java简单实现双向链表,更多功能可参考Java集合中的LinkedList实现。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章:

  • java 段错误_[原创]记一次java执行段错误及解决过程
  • java反射查询数据库_java反射与注解结合使用(根据传入对象输出查询sql)
  • Java 类Servletrequest_java中servlet中有关HttpServletRequest的不理解
  • java 值 继承_java中的继承
  • java 颜色条_具有多个颜色条的子图
  • java 图片数据管理_Java实现图片内容无损任意角度旋转
  • java流量监控系统demo_搭建一个简单的基于web的网络流量监控可视化系统
  • jquery与java_纯javascript和jquery实现增删改查
  • mysql 批量字段前缀_sqlserver数据库,批量更改表名和字段的前缀 | 学步园
  • pdfpcell 怎么设置单元格大小_PdfPCell的方法隐藏单元格的边框
  • java strace_用strace排查故障的5种简单方法(每日一译)
  • java银行账户系统_用java编的银行账户系统代码
  • java扩展包_CodeRunner 的 Java 扩展 Jar 包支持
  • java session 修改_修改 Servlet 的sessionId
  • qt添加qwt帮助文件_win 7下安装qwt 6.1.0,基于qt 4.8.5
  • 【EOS】Cleos基础
  • 【node学习】协程
  • android 一些 utils
  • CSS居中完全指南——构建CSS居中决策树
  • vue-router的history模式发布配置
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 入门级的git使用指北
  • 数据仓库的几种建模方法
  • 我从编程教室毕业
  • 一道闭包题引发的思考
  • 一份游戏开发学习路线
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • FaaS 的简单实践
  • ​水经微图Web1.5.0版即将上线
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (编译到47%失败)to be deleted
  • (超详细)语音信号处理之特征提取
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (多级缓存)缓存同步
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (九)c52学习之旅-定时器
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (新)网络工程师考点串讲与真题详解
  • .equals()到底是什么意思?
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net mvc 获取url中controller和action
  • .NET Standard 的管理策略
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .sh 的运行
  • /var/log/cvslog 太大
  • @RequestMapping-占位符映射
  • @SuppressWarnings注解