链表的理解
一、链表的基本结构
链表程序的本质在于节点的相互引用,缺点就是数据的保存顺序就是你的添加顺序
public class Link{ private class Node{ private Object data; private Node next;//下一个节点;用作自身关联 public Node(Object data){ this.data=data;//创建节点的时候封装数据,由于节点有序,封装的数据也就有序了 } } /*----------------以下是Link的操作-------------------*/ private Node root; public void add(Object data){ ... } ... } 二、链表和动态数组关系: 1.数组的长度等于链表的长度,链表如果添加了数据,长度就发生了变化, 间接地数组的长度也就发生了变化,即可以实现动态数组(长度可变) private Object[] rdata; public Object[] toArray(){//将链表转化为对象数组 //判断链表是否为空 if(count==0 || this.root==null){ return null; } //count:链表的长度 this.rdata=new Object[count]; foot=0;//foot清零, //用this.root去获取数据(Node类来获取数据) this.root.toArrayNode(); return rdata; //在Node类中取数据 public void toArrayNode(){ Link_get.this.rdata[Link_get.this.foot++]=this.data; if(this.next!=null){ this.next.toArrayNode(); } } } 2.链表添加一个数据(实际是将数据封装在Node中) 然后将封装了数据的节点添加到链表中, 数组对应保存一个数据(采用索引foot++实现),链表 输出可以通过遍历数组获取数据 private Node root; public void add(Object data){ if(data==null) return ; Node newNode =new Node(data);//封装数据到节点中 if(this.root==null){ this.root=newNode;//将一个节点赋值给根节点 }else{ this.root.addNode(newNode);//交给Node类自己去完成节点的排序任务 } } //第一次调用:this代表的是Link.root(根节点) public void addNode(Node newNode){ if(this.next==null){ this.next=newNode; }else{ if(this.next!=null){ this.next.addNode(newNode); } } } 3.链表删除数据 public void delete(Object data){ if(this.contains(data)){//链表存在要删除的数据 if(this.root.data.equals(data)){//要删除的数据在根节点中 this.root=this.root.next;//删除根节点 }else{//要删除的数据不在根节点中 //删除其它节点的条件是:要被删除的节点的上一个节点.next=要被删除的节点.next //所以传入的参数应该有:调用方法的节点的上一个节点和要被删除的数据 this.root.next.deleteNode(this.root,data);//this.root就是调用deleteNode方法的节点this.root.next的上一个节点 } //注意:删除数据之后,链表的长度会发生改变 count--; } } //在Node类中 public void deleteNode(Node previous,Object data){ if(this.next.data.equals(data)){ previous.next=this.next; }else{ if(this.next!=null){ this.next.deleteNode(this,data); } } }
/* *自定义的一个较完整的链表类 */ package com.petshop; public class Link { private class Node{ private Object data; private Node next; public Node(Object data){ this.data=data; } //添加节点 public void addNode(Node newNode){ if(this.next==null){ this.next=newNode; }else{ this.next.addNode(newNode); } } public void toArrayNode(){ //将取出的数据放在rdata数组中 Link.this.rdata[Link.this.foot++]=this.data;//取出根节点的数据 if(this.next!=null){ this.next.toArrayNode(); } } //判断是否包含要查询的数据 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(Link.this.foot++ == index){ return this.data; }else{ if(this.next!=null){ return this.next.getNode(index); }else{ return null; } } } //根据索引修改数据 public void setNode(int index,Object data){ if(Link.this.foot++ == index){ this.data=data; }else{ if(this.next!=null){ this.next.setNode(index, data); } } } /* * 第一次调用:this:Link.root.next; previous:Link.root * 第二次调用:this:Link.root.next.next; previous:Link.root.next */ public void removeNode(Node previous,Object data){ if(this.data.equals(data)){ previous.next=this.next; }else{ if(this.next!=null){ this.next.removeNode(this, data);//this是this.next的上一个节点 } } } } /*---------------以下是Link的操作----------------------------*/ private Node root; private int count; private int foot; private Object[] rdata;//用于存储链表中的数据 //删除数据 public void remove(Object data){ if(this.contains(data)){//确保链表中包含有要删除数据 if(this.root.data.equals(data)){//判断删除数据是否在根节点中 //删除根节点 this.root=this.root.next; }else{ //要删除的数据不在根节点中 //删除其它节点:删除节点的上一个节点.next=删除节点.next; //所以传入参数有:删除节点的上一个节点和要删除的数据 this.root.next.removeNode(this.root,data); } //注意链表长度的改变 count--; } } //根据索引修改数据 public void set(int index,Object data){ if(index>=count || data==null || this.root ==null){ return; }else{ //Link类做一些判断,最终实现细节的操作都是由Node类来完成 /* *this.root.containsNode() *this.root.toArrayNode() *this.root.getNode() *... */ this.root.setNode(index,data); } } //根据索引获取数据 public Object get(int index){ if(index>=count || this.root==null){ //索引大于了链表的长度(数组的长度) return null; }else{ //从根节点(foot=0)开始查询,直到数组的索引等于要查询的索引为止 foot=0; return this.root.getNode(index); } } //判断链表是否存在有要被查询的数据 public boolean contains(Object data){ if(data==null || this.root==null){ return false; }else{ //从根节点开始查询是否存在查询的数据 return this.root.containsNode(data); } } public Object[] toArray(){ if(count==0 || this.root==null){ return null; } //忘记写了 rdata=new Object[count];//动态定义数组长度 foot=0; this.root.toArrayNode();//采用链表去获取数据 return this.rdata; } //获取链表数据的个数 public int size(){ return count; } //判断链表是否为空 public boolean isEmpty(){ return count==0 && this.root==null; } //链表添加数据 public void add(Object data){ if(data==null) return ; Node newNode=new Node(data); if(this.root==null){ this.root=newNode; }else{ this.root.addNode(newNode); } //记录链表长度 count++; } }