写给自己的JAVA工程师之路-链表
来源:互联网 发布:如何提高唱歌水平 知乎 编辑:程序博客网 时间:2024/06/07 04:19
1.1 认识链表
链表 = 可变长的对象数组,属于动态对象数组的范畴。
传统对象数组:
作用:对象数组可以保存一组对象方便开发。
缺点:对象数组的长度固定,而且数据的修改,删除,增加处理麻烦。
正因为如此,如果想要让其编写出便于维护的代码,那么就需要实现一个动态对象数组,于是可以使用链表完成。
1.2 实现链表
问题:保存数据为了方便使用Object;
数据本身不包含有先后的逻辑关系,所以将数据封装在一个Node类,负责关系的维护。
class Node{//表示定义的节点private Object data;//表示保存的数据private Node next;//保存下一个节点public Node(Object data){//有数据才可以保存节点this.data=data;}public void setNext(Node next){//设置节点this.next=next;}public Node getNext(){//取得节点return this.next;}}
虽然以上的代码已经实现了链的形式,但是实际上Node类对用户没有。所以还需要一个类,这个类可以负责所有Node的关系匹配,而用户只需通过这个类保存数据,取得数据即可。
于是代码变成:
class Node{//表示定义的节点private Object data;//表示保存的数据private Node next;//保存下一个节点public Node(Object data){//有数据才可以保存节点this.data=data;}public void setNext(Node next){//设置节点this.next=next;}public Node getNext(){//取得节点return this.next;}public Object getData(){//取得数据return this.data;}//第一次调用:this=Link.root//第二次调用:this=Link.root.next//第三次调用:this=Link.root.next.nextpublic void addNode(Node newNode){if(this.next==null){//当前节点后没有节点this.next=newNode;}else{//当前节点后有节点this.next.addNode(newNode);}}public void printNode(){System.out.println(this.data);if(this.next!=null){this.next.printNode();}}}class Link{//表示一个链表操作类,利用此类来隐藏Node的节点匹配private Node root;//根元素public void add(Object obj){//向链表里追加数据Node newNode = new Node(obj);//将数据包装为Node对象,这样才可以进行先后关系排列//没有根节点时if(this.root==null){this.root=newNode;//第一个节点作为根节点}else{//根节点存在,交由Node处理this.root.addNode(newNode);}}public void print(){//输出全部数据this.root.printNode();}}
链表在整个实现过程最关键的就是Node类,Node类要保存数据与下一个节点。
2.1 开发可用链表
以上的代码只能够说是基本的链表形式,可是如何才能实现一个好的链表呢?
1.让Node类只为Link类服务,但是又不让其他类访问。
2.如果要开发程序,那么一定要创建出自己的操作标准,那么一旦说到标准,就应该使用到接口完成。
于是代码结构变成:
interface Link{}class LinkImpl implements Link{private class Node{//使用私有内部类,防止外部使用此类private Object data;//表示保存的数据private Node next;//保存下一个节点public Node(Object data){//有数据才可以保存节点this.data=data;}}//*******************************************private Node root;//根节点}在随后完善的代码过程之中,除了功能的实现之外,实际上也属于接口功能的完善。
2.2 完整链表实现
interface Link{public void add(Object data);//数据增加public int size();//获得链表大小public boolean isEmpty();//判断是否为空集合public boolean contains(Object data);//判断是否存在指定元素public Object get(int index);//根据索引取得数据public void set(int index,Object obj);//修改数据public void remove(Object data);//数据删除public void clear();//清空链表public Object[] toArray();//对象数组转换}class LinkImpl implements Link{private class Node{//使用私有内部类,防止外部使用此类private Object data;//表示保存的数据private Node next;//保存下一个节点public Node(Object data){//有数据才可以保存节点this.data=data;}//第一次调用:this=LinkImpl.root//第二次调用:this=LinkImpl.root.next//第三次调用:this=LinkImpl.root.next.nextpublic void addNode(Node newNode){if(this.next==null){//当前节点后没有节点this.next=newNode;}else{//当前节点后有节点this.next.addNode(newNode);}}public boolean containsNode(Object data){if(this.data.equals(data)){//该节点数据束符合于查找数据return true;}else {//继续向下查找if(this.next!=null){//当前节点还有下一个节点return this.next.containsNode(data);}else {return false;}}}public Object getNode(int index){//传递索引序号if(LinkImpl.this.foot++==index){//当前的索引为要查找的索引return this.data;//返回节点对象}else {return this.next.getNode(index);}}public void setNode(int index,Object data){if(LinkImpl.this.foot++==index){//当前的索引为要查找的索引this.data=data;//重新保存数据}else {this.next.setNode(index, data);}}public void removeNode(Node pre,Object data){if(this.data.equals(data)){//为当前要删除的数据pre.next=this.next;}else {pre.next.removeNode(this, data);}}public void toArrayNode(){LinkImpl.this.retData[LinkImpl.this.foot++]=this.data;if(this.next!=null){this.next.toArrayNode();}}}//*******************************************private Node root;//根节点private int count=0;//纪律链表大小private int foot=0;//操作的索引脚标private Object retData[]=null;public void add(Object data){if(data==null){//没有增加的数据return ;//结束调用}Node newNode = new Node(data);//将数据包装为Node对象,这样才可以进行先后关系排列//没有根节点时if(this.root==null){this.root=newNode;//第一个节点作为根节点}else{//根节点存在,交由Node处理this.root.addNode(newNode);}this.count++;//添加成功 ,链表长度+1}public int size(){//获得链表大小return this.count;}public boolean isEmpty(){return this.root==null;}public boolean contains(Object data) {if(this.root==null){return false;}return this.root.containsNode(data); }public Object get(int index) {if(index>=this.count){//索引不存在return null;}this.foot=0;//查询之前进行初始化return this.root.getNode(index);}public void set(int index, Object obj) {if(index>=this.count){//索引不存在return ;}this.foot=0;//查询之前进行初始化this.root.setNode(index, obj);}public void remove(Object data) {if(this.contains(data)){//数据如果存在即删除if(this.root.data.equals(data)){//跟元素为要删除的元素this.root=this.root.next;}else {//不是根元素this.root.next.removeNode(this.root, data);}}count--;}public void clear() {this.root=null;this.count=0;System.gc();//内存清空}public Object[] toArray() {if(this.root==null){return null;}this.retData=new Object[this.count];this.foot=0;this.root.toArrayNode();return this.retData;}}以上的设计都没有考虑过性能问题,只是简单的单向链表,重点是方法的理解与实现
阅读全文
0 0
- 写给自己的JAVA工程师之路-链表
- 写给自己的JAVA工程师之路-数据链路层
- 写给自己的JAVA工程师之路-计划
- 写给自己的JAVA工程师之路-异常
- 写给自己的JAVA工程师之路-单例模式
- 写给自己的JAVA工程师之路-网络体系结构
- 写给自己的JAVA工程师之路-抽象类
- 写给自己的JAVA工程师之路-物理层
- 写给自己的JAVA工程师之路-接口
- 写给自己的JAVA工程师之路-MySQL函数
- 写给自己的JAVA工程师之路-枚举
- 写给自己的JAVA工程师之路-多线程
- 写给自己的JAVA工程师之路-基础类库
- 写给自己的JAVA工程师之路-正则表达式
- 写给自己的JAVA工程师之路-约束和修改数据表
- 写给自己的JAVA工程师之路-子查询与连接
- 写给我的JAVA工程师之路-数据表操作
- 写给自己——我的求职之路
- Codeforces Round #441 B.Divisiblity of Differences
- Codeforces 876E:2-SAT 或者 瞎搞
- 【C语言】【unix c】web服务器项目笔记
- P1103
- rhs和rhsa文件属性的文件删除方法
- 写给自己的JAVA工程师之路-链表
- ios-闭包的写法
- 2016CCPC东北地区大学生程序设计竞赛
- 【C语言】【unix c】web服务器项目代码
- Ubuntu下更改用户名和主机名
- VS2013使用MySql.Data.Entity.EF6实体数据模型向导闪退的问题解决
- ARM笔记
- C语言应用:游戏框架
- Git入门与进阶