面向对象来理解链表
Posted niaonao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象来理解链表相关的知识,希望对你有一定的参考价值。
目录
一、链表知识
1.1 链表定义
1.2 链表结构
1.3 说明
二、面向对象分析链表
2.1 节点封装类Node.java
2.2 链表封装类ChainTable.java
2.3 关于环的补充
2.4 链表测试类TestChainTable.java
一、链表知识
1.1 链表定义
百度百科:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
1.2 链表结构
链表的元素是节点,由一个或多个结点组成。节点包括两个元素:数据域(存储数据的)和指针域(指向下一个结点地址)。
简单理解的话,类似链条,一节一节相连,每个链节都有自己的零件(数据)并且链接下一个链接(指针)。
自行车的车链是一个环状的链子,或者说是首位相连的,这是链表中环结构下面会有说明。
我们可以从图1-1 链表中抽象出链表如图1-2 所示,从首节点headNode 依此指向下一个node,直至尾节点tailNode
图1-2、抽象链表图
进而具体到单向链表
- 初始化指针指向首节点headNode
- 每一个节点node 都由数据域和指针域组成,数据域存放当前节点的数据,指针域存放当前指针的下一个指向节点
- 尾节点tailNode 的指针为空
1.3 说明
常见链表有单向链表和双向链表,单向链表是只有一个方向,从链表的首节点headNode 一直指向尾节点tailNode。双向链表是链表即可从headNode 指向tailNode 又可反向从tailNode 指向heaNode。
此处以单向链表为例,面向对象分析链表结构,将节点对象化,链表对象化,此处使用Java 语言演示。
本文涉及到链表的初始化,添加节点,删除节点,查询节点,链表的逆置,模拟链表的环结构,判断链表是否存在环结构,寻找环的入口。关于链表的相交问题暂不涉及。
二、面向对象分析链表
2.1 节点封装类Node.java
有两个属性,当前节点存储的数据Object data,指向下一节点的指针Node next。
2.2 链表封装类ChainTable.java
封装单链表的常用方法包括插入首节点,插入尾节点,指定位置插入节点,删除指定位置节点等。
方法不一一分开介绍了,其中的方法都有注释说明。
基本方法:
- void insert(Object val) 插入链表元素的方法(插入链表首位, 插入链表尾部, 插入链表指定位置)
- int getLength() 获取链表长度的方法
- Node getPosition(int position) 获取链表指定位置元素(正序获取, 逆序获取)
- boolean judgeLoop() 判断链表是否有环的方法
- int getLoopLength() 获取环的长度
- Node entryLoop() 查找环入口的方法
- Node reverse() 逆置链表的方法
- void clear() 清除链表
2-4 链表测试类TestChainTable.java
测试链表封装类的常用方法,以供参考。
/** * @Description :链表测试类 * @Author: niaonao * @Date: 2018/8/11 16:11 */ public class TestChainTable { //声明链表 private static ChainTable chainLink; public static void main(String a[]) { testChainMethod(); } /** * 测试链表方法 */ private static void testChainMethod() { System.out.println(" 1.1 初始化链表数据"); init(); if (chainLink == null || chainLink.getLength() < 1) { return; } showChain(); System.out.println(" 2.1 链表第三个节点之后插入数据为Three 的节点"); chainLink.insert("Three", 3); showChain(); System.out.println(" 3.1 获取链表中第5 个节点的数据: " + chainLink.getPosition(5).getData()); showChain(); System.out.println(" 4.1 获取链表中倒数第5 个节点的数据: " + chainLink.getBackPosition(5).getData()); showChain(); System.out.println(" 5.1 链表删除第2 个节点 "); chainLink.delete(2); showChain(); System.out.println(" 6.1 链表逆序"); chainLink.reverse(); showChain(); System.out.println(" 7.1 链表是否相交: " + chainLink.judgeLoop()); showChain(); System.out.println(" 7.2 模拟环模型, 使当前链表尾节点的Next 指向首节点"); Node firstNode = chainLink.getPosition(1); Node lastNode = chainLink.getBackPosition(1); lastNode.setNext(firstNode); //出现环时, 链表遍历是个死循环 //showChain(); if (chainLink.judgeLoop()){ System.out.print(" 7.3 链表是否有环: " + Boolean.TRUE + " 出现环时, 链表遍历是个死循环"); System.out.print(" 环的长度: " + chainLink.getLoopLength()); System.out.print(" 环的入口: " + chainLink.entryLoop() + " 环入口节点的数据data: " + chainLink.entryLoop().getData() + " 下一个节点对象node: " + chainLink.entryLoop().getNext()); } else { System.out.println(" 7.3 链表是否有环: " + Boolean.TRUE + " " + chainLink); } } /** * 初始化数据 */ private static void init() { chainLink = new ChainTable(); System.out.println(" 在链表首位添加A,链表尾部依此添加B、C、D、E"); chainLink.insertHead("A"); chainLink.insertTail("B"); chainLink.insertTail("C"); chainLink.insertTail("D"); chainLink.insertTail("E"); } /** * 链表数据显示 */ private static void showChain() { System.out.println(" 链表长度: " + chainLink.getLength()); System.out.print(" 链表数据: "); for (int i = 0; i < chainLink.getLength(); i++) { Node node = chainLink.getPosition(i + 1); System.out.print(" " + node.getData()); } } }
测试结果:
1.1 初始化链表数据
在链表首位添加A,链表尾部依此添加B、C、D、E
链表长度: 5
链表数据: A B C D E
2.1 链表第三个节点之后插入数据为Three 的节点
链表长度: 6
链表数据: A B Three C D E
3.1 获取链表中第5 个节点的数据: D
链表长度: 6
链表数据: A B Three C D E
4.1 获取链表中倒数第5 个节点的数据: B
链表长度: 6
链表数据: A B Three C D E
5.1 链表删除第2 个节点
链表长度: 5
链表数据: A Three C D E
6.1 链表逆序
链表长度: 5
链表数据: E D C Three A
7.1 链表是否相交: false
链表长度: 5
链表数据: E D C Three A
7.2 模拟环模型, 使当前链表尾节点的Next 指向首节点7.3 链表是否有环: true
出现环时, 链表遍历是个死循环
环的长度: 1
环的入口: [email protected]
环入口节点的数据data: E
下一个节点对象node: [email protected]
以上是关于面向对象来理解链表的主要内容,如果未能解决你的问题,请参考以下文章