java 线性表---------双向链表(源代码)

2023-11-17

1.public class DuLinkList<T>   
2.{   
3.    //定义一个内部类Node,Node实例代表链表的节点。   
4.    private class Node   
5.    {   
6.        //保存节点的数据   
7.        private T data;   
8.        //指向上个节点的引用   
9.        private Node prev;   
10.        //指向下个节点的引用   
11.        private Node next;   
12.        //无参数的构造器   
13.        public Node()   
14.        {   
15.        }   
16.        //初始化全部属性的构造器   
17.        public Node(T data , Node prev , Node next)   
18.        {   
19.            this.data = data;   
20.            this.prev = prev;   
21.            this.next = next;   
22.        }   
23.    }   
24.    //保存该链表的头节点   
25.    private Node header;   
26.    //保存该链表的尾节点   
27.    private Node tail;   
28.    //保存该链表中已包含的节点数   
29.    private int size;   
30.    //创建空链表   
31.    public DuLinkList()   
32.    {   
33.        //空链表,header和tail都是null   
34.        header = null;   
35.        tail = null;   
36.    }   
37.    //以指定数据元素来创建链表,该链表只有一个元素   
38.    public DuLinkList(T element)   
39.    {   
40.        header = new Node(element , null , null);   
41.        //只有一个节点,header、tail都指向该节点   
42.        tail = header;   
43.        size++;   
44.    }   
45.    //返回链表的长度      
46.    public int length()   
47.    {   
48.        return size;   
49.    }   
50.  
51.    //获取链式线性表中索引为index处的元素   
52.    public T get(int index)   
53.    {   
54.        return getNodeByIndex(index).data;   
55.    }   
56.    //根据索引index获取指定位置的节点   
57.    private Node getNodeByIndex(int index)   
58.    {   
59.        if (index < 0 || index > size - 1)   
60.        {   
61.            throw new IndexOutOfBoundsException("线性表索引越界");   
62.        }   
63.        if (index <= size / 2)   
64.        {   
65.            //从header节点开始   
66.            Node current = header;   
67.            for (int i = 0 ; i <= size / 2 && current != null  
68.                ; i++ , current = current.next)   
69.            {   
70.                if (i == index)   
71.                {   
72.                    return current;   
73.                }   
74.            }   
75.        }   
76.        else  
77.        {   
78.            //从tail节点开始搜索   
79.            Node current = tail;   
80.            for (int i = size - 1 ; i > size / 2 && current != null  
81.                ; i++ , current = current.prev)   
82.            {   
83.                if (i == index)   
84.                {   
85.                    return current;   
86.                }   
87.            }   
88.        }   
89.        return null;   
90.    }   
91.    //查找链式线性表中指定元素的索引   
92.    public int locate(T element)   
93.    {   
94.        //从头节点开始搜索   
95.        Node current = header;   
96.        for (int i = 0 ; i < size && current != null  
97.            ; i++ , current = current.next)   
98.        {   
99.            if (current.data.equals(element))   
100.            {   
101.                return i;   
102.            }   
103.        }   
104.        return -1;   
105.    }   
106.    //向线性链式表的指定位置插入一个元素。   
107.    public void insert(T element , int index)   
108.    {   
109.        if (index < 0 || index > size)   
110.        {   
111.            throw new IndexOutOfBoundsException("线性表索引越界");   
112.        }   
113.        //如果还是空链表   
114.        if (header == null)   
115.        {   
116.            add(element);   
117.        }   
118.        else  
119.        {   
120.            //当index为0时,也就是在链表头处插入   
121.            if (index == 0)   
122.            {   
123.                addAtHeader(element);   
124.            }   
125.            else  
126.            {   
127.                //获取插入点的前一个节点   
128.                Node prev = getNodeByIndex(index - 1);   
129.                //获取插入点的节点   
130.                Node next = prev.next;   
131.                //让新节点的next引用指向next节点,prev引用指向prev节点   
132.                Node newNode = new Node(element , prev , next);   
133.                //让prev的next指向新节点。   
134.                prev.next = newNode;   
135.                //让prev的下一个节点的prev指向新节点   
136.                next.prev = newNode;   
137.                size++;   
138.            }   
139.        }   
140.    }   
141.    //采用尾插法为链表添加新节点。   
142.    public void add(T element)   
143.    {   
144.        //如果该链表还是空链表   
145.        if (header == null)   
146.        {   
147.            header = new Node(element , null , null);   
148.            //只有一个节点,header、tail都指向该节点   
149.            tail = header;   
150.        }   
151.        else  
152.        {   
153.            //创建新节点,新节点的pre指向原tail节点   
154.            Node newNode = new Node(element , tail , null);   
155.            //让尾节点的next指向新增的节点   
156.            tail.next = newNode;   
157.            //以新节点作为新的尾节点   
158.            tail = newNode;   
159.        }   
160.        size++;   
161.    }   
162.    //采用头插法为链表添加新节点。   
163.    public void addAtHeader(T element)   
164.    {   
165.        //创建新节点,让新节点的next指向原来的header   
166.        //并以新节点作为新的header   
167.        header = new Node(element , null , header);   
168.        //如果插入之前是空链表   
169.        if (tail == null)   
170.        {   
171.            tail = header;   
172.        }   
173.        size++;   
174.    }   
175.    //删除链式线性表中指定索引处的元素   
176.    public T delete(int index)   
177.    {   
178.        if (index < 0 || index > size - 1)   
179.        {   
180.            throw new IndexOutOfBoundsException("线性表索引越界");   
181.        }   
182.        Node del = null;   
183.        //如果被删除的是header节点   
184.        if (index == 0)   
185.        {   
186.            del = header;   
187.            header = header.next;   
188.            //释放新的header节点的prev引用   
189.            header.prev = null;   
190.        }   
191.        else  
192.        {   
193.            //获取删除点的前一个节点   
194.            Node prev = getNodeByIndex(index - 1);   
195.            //获取将要被删除的节点   
196.            del = prev.next;   
197.            //让被删除节点的next指向被删除节点的下一个节点。   
198.            prev.next = del.next;   
199.            //让被删除节点的下一个节点的prev指向prev节点。   
200.            if (del.next != null)   
201.            {   
202.                del.next.prev = prev;   
203.            }          
204.            //将被删除节点的prev、next引用赋为null.   
205.            del.prev = null;   
206.            del.next = null;   
207.        }   
208.        size--;   
209.        return del.data;   
210.    }   
211.    //删除链式线性表中最后一个元素   
212.    public T remove()   
213.    {   
214.        return delete(size - 1);   
215.    }   
216.    //判断链式线性表是否为空链表   
217.    public boolean empty()   
218.    {   
219.        return size == 0;   
220.    }   
221.    //清空线性表   
222.    public void clear()   
223.    {   
224.        //将底层数组所有元素赋为null   
225.        header = null;   
226.        tail = null;   
227.        size = 0;   
228.    }   
229.    public String toString()   
230.    {   
231.        //链表为空链表时   
232.        if (empty())   
233.        {   
234.            return "[]";   
235.        }   
236.        else  
237.        {   
238.            StringBuilder sb = new StringBuilder("[");   
239.            for (Node current = header ; current != null  
240.                ; current = current.next )   
241.            {   
242.                sb.append(current.data.toString() + ", ");   
243.            }   
244.            int len = sb.length();   
245.            return sb.delete(len - 2 , len).append("]").toString();   
246.        }   
247.    }   
248.    public String reverseToString()   
249.    {   
250.        //链表为空链表时   
251.        if (empty())   
252.        {   
253.            return "[]";   
254.        }   
255.        else  
256.        {   
257.            StringBuilder sb = new StringBuilder("[");   
258.            for (Node current = tail ; current != null    
259.                ; current = current.prev )   
260.            {   
261.                sb.append(current.data.toString() + ", ");   
262.            }   
263.            int len = sb.length();   
264.            return sb.delete(len - 2 , len).append("]").toString();   
265.        }   
266.    }   
267.       
268.    public static void main(String[] args)    
269.    {   
270.        DuLinkList<String> list = new DuLinkList<String>();   
271.        list.insert("aaaa" , 0);   
272.        list.add("bbbb");   
273.        list.insert("cccc" , 0);   
274.        //在索引为1处插入一个新元素   
275.        list.insert("dddd" , 1);   
276.        //输出顺序线性表的元素   
277.        System.out.println(list);   
278.        //删除索引为2处的元素   
279.        list.delete(2);   
280.        System.out.println(list);   
281.        System.out.println(list.reverseToString());   
282.        //获取cccc字符串在顺序线性表中的位置   
283.        System.out.println("cccc在顺序线性表中的位置:"    
284.            + list.locate("cccc"));   
285.        System.out.println("链表中索引1处的元素:"    
286.            + list.get(1));   
287.        list.remove();   
288.        System.out.println("调用remove方法后的链表:" + list);   
289.        list.delete(0);   
290.        System.out.println("调用delete(0)后的链表:" + list);   
291.    }   
292.}  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 线性表---------双向链表(源代码) 的相关文章

随机推荐

  • 三相电表接线图

    三相电表主要用于工厂等负荷较大得场景中 而客户使用三相电表时问题最多的就是三相电表的接线方法 因此湖南云集就为大家介绍一下三相电表的接线方法和三相电表接线图 供大家参考 三相电表分为三相三线电表和三相四线电表 主要的接线方式有三种 直接接入
  • 数据库——SQL语句(查询操作)

    目录 1 单表查询 1 1 按列名选择 1 2 含有表达式 1 3 给列起别名 1 4 取消重复行 1 5 条件查询 1 6 排序 1 7 限制返回行数 1 8 聚集函数 统计个数 求和 求平均值 求极值 1 9 分组 1 10 聚集函数后
  • Postman —— 配置环境变量

    PostMan是一套比较方便的接口测试工具 但我们在使用过程中 可能会出现创建了API请求 但API的URL会随着服务器IP地址的变化而改变 这样的情况下 如果每一个API都重新修改URL的话那将是非常的麻烦 所以PostMan中也提供环境
  • python数据挖掘分析案例python_Python 数据挖掘实例 决策树分析

    友情提示 此篇文章大约需要阅读 7分钟57秒 不足之处请多指教 感谢你的阅读 安装Anaconda Python集成环境 下载环境 anaconda下载选择 安装环境 下载过程中使用默认 但有一个页面需要确认 如下图 anaconda选择页
  • android4.4.2 以太网代理,Android2.3.4系统添加Ethernet框架支持

    参照网上的移植过一次 有以下3个问题先需要注意 一 下载相应的android x86版本代码 否则出错的几率很大 二 如出现android net ethernet ethernetstatetracker cpp stripped of
  • RabbitMQ的transaction、confirm、ack三个概念的解释

    在使用RabbitMQ的过程中 肯定会遇到这样的几个概念 transaction confirm ack 本文介绍一下这几个概念 以及他们之间的关系 RabbitMQ是采用的AMQP协议 AMQP协议定义了 确认 acknowledgeme
  • MySQL基础总结

    首先 今天学习遇到一点小问题 mysql中出现 Unknown column xxx in having clause 这是因为在使用group by分组时 后面如果需要再加一个having进行判断 则所判断的字段需要在select后面出现
  • 【计算机视觉

    文章目录 一 CSPResNeXt 二 ProxylessNet Mobile 三 ProxylessNet CPU 四 RandWire 五 MCKERNEL 六 Assemble ResNet 七 Convolution enhance
  • 短信信息服务器保存时效,长时间保存信息

    长时间保存信息 内容精选 换一换 华为云帮助中心 为用户提供产品简介 价格说明 购买指南 用户指南 API参考 最佳实践 常见问题 视频帮助等技术文档 帮助您快速上手使用华为云服务 向YARN服务器提交MapReduce任务后 客户端提示如
  • CentOS8结束生命周期后如何切换镜像源

    CentOS8结束生命周期后如何切换镜像源 官方提供了一个替代源 但不再进行任何更新 仅提供软件包 CentOS8系统在国内推荐使用阿里云的镜像源 具体切换过程如下 备份现有的repo配置文件 rename repo repo bak et
  • 【Python三大结构练习3】

    1 温度转换 题目描述 输入摄氏温度 华氏温度 输出对应的华氏温度 摄氏温度 这里采用82F表示华氏82度 采用28C表示摄氏28度 实数部分是温度值 转换算法 C F 32 1 8 F C 1 8 32 其中 C表示摄氏温度 F表示华氏温
  • [其他]IDEA中Maven项目配置国内源

    配置国内源主要解决了 在maven项目中pom xml下载jar包失败或过慢的问题 在IDEA中的设置分成两种 设置当前项目与新创项目 我们就需要两种都进行设置 不然只有在当前项目配置了国内源 新创项目的时候还是默认的状态 由于下面两种设置
  • msvcr120.dll丢失的解决方法-一键解决提示msvcr120.dll丢失问题

    msvcr120 dll是的动态链接库文件之一 它在Windows操作系统中发挥着重要的作用 它提供了应用程序所需的各种功能和方法 该文件返回编译后的代码所需的支持库 msvcr120 dll包含用于C C 编译器生成的应用程序所需的重要功
  • 区块链的结构和原理

    区块链的结构和原理 文章目录 区块链的结构和原理 区块链原理 区块链结构 关于区块链的几个问题 结语 区块链原理 区块链是一个链表 链表上存有交易信息 所有人共享同一个链表 因此它也是一个没有管理员的分布式数据库 即去中心化数据库 所有人都
  • 《Java并发编程的艺术》知识点

    目录 一 并发编程挑战 1 上下文切换 2 死锁 二 并发机制底层实现原理 1 volatile原理 2 synchronized原理 3 原子类实现原理 CAS存在的三大问题 三 内存模型 1 指令重排 四 并发编程基础 1 概念 2 优
  • myisamchk是用来做什么的?

    myisamchk是MySQL数据库管理系统中的一个工具 而不是Java编程语言的一部分 myisamchk是用于维护和修复MySQL数据库中MyISAM存储引擎表的工具 MyISAM是MySQL数据库中一种常用的存储引擎 它适用于读取频率
  • 冒泡排序代码python

    冒泡排序的python代码如下 def bubbleSort arr n len arr Traverse through all array elements for i in range n Last i elements are al
  • 微信小程序官方组件展示之画布canvas源码

    以下将展示微信小程序之画布canvas源码官方组件能力 组件样式仅供参考 开发者可根据自身需求定义组件样式 具体属性参数详见小程序开发文档 功能描述 画布 2 9 0 起支持一套新 Canvas 2D 接口 需指定 type 属性 同时支持
  • 数字IC设计——跨时钟域篇3(单比特处理)

    数字IC设计 跨时钟域篇3 单比特处理 下面介绍常见的单比特跨时钟域的处理方法 一 慢时钟域信号同步到快时钟域的处理方法 两级寄存器同步 慢时钟信号进入到更快的时钟域时 频率相差2倍以上 此时不用考虑快时钟域信号采样丢失问题 可以考虑使用两
  • java 线性表---------双向链表(源代码)

    1 public class DuLinkList