链表相比与数组,在进行循环遍历时效率不高,但是插入和删除的优势明显。
链表实际上是由节点组成的,一个链表对外暴露的只有根节点,我们对链表的所以操作都是直接或间接的通过根节点来进行的。
而节点是由一个需要存储的对象和对下一节点的引用组成的,即节点拥有两个成员:存储的对象、下一节点的引用。
写一个简单链表。
package jun.text;
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);
}
}
//第一次调用(Link):this = Link.root
//第二次调用(Node):this = Link.root.next
public boolean contaionsNode(Object data) {
if(data.equals(this.data)){
return true;
}else{ //当前节点不满足查询要求
if(this.next != null){ //有后续节点
return this.next.contaionsNode(data);
}else{
return false;
}
}
}
public Object getNode(int index) {
//使用当前的foot内容与要查询的索引进行比较,
//随后将foot的内容自增,目的是为了方便下次查询
if(Link.this.foot ++ == index){
return this.data;
}else{
if(this.next != null){
return this.next.getNode(index);
}
return null;
}
}
public void removeNode(Node pre,Object data){
if(data.equals(this.data)){ //当前节点为要删除的节点
pre.next = this.next; //空出当前节点
}else{
this.next.removeNode(this, data);
}
}
public void toArrayNode() {
Link.this.array[Link.this.foot ++] = this.data;
if(this.next != null){
this.next.toArrayNode();
}
}
}
private Node root; //需要根节点
private int count = 0;//保存元素的个数
private int foot = 0;
private Object[] array;//返回的数组
public void add(Object data){
if(data == null){//假设不允许为空
return;
}
Node newNode = new Node(data);//要保存的数据
if(this.root==null){ //当前没有根节点
this.root = newNode;//保存根节点
}
else{//根节点存在,其他节点交给Node类处理
this.root.addNode(newNode);
}
this.count++;
}
public int size(){//取得保存的数据量
return this.count;
}
public boolean isEmpty(){//判断链表是否为空
return this.count==0;
}
public Object get(int index){
if(index>this.count){
return null;
}
this.foot = 0;//表示从前向后查询
return this.root.getNode(index);//查询过程交给Node类处理
}
public boolean contains(Object data){//判断数据是否存在
//如果没有要查询的数据,根节点也不保存数据
if(data == null|| this.root == null){
return false;
}
//交给Node类查询
return this.root.contaionsNode(data);
}
public Object[] toArray(){
if(this.root == null){
return null;
}
this.foot = 0;
this.array = new Object[this.count];
this.root.toArrayNode();
return this.array;
}
public void remove(Object data){
if(this.contains(data)){
//要删除数据是否是根节点数据
//root是Node类的对象,此处直接访问了内部类的私有操作
if(data.equals(this.root.data)){ //为要删除节点
this.root = this.root.next; //空出当前根节点
}else{ //不是根元素
//从第二个元素开始判断
this.root.next.removeNode(this.root, data);
}
this.count--;
}
}
}
public class LinkDemo {
public static void main(String[] args) {
Link all = new Link();
all.add("qq");
all.add("ww");
all.add("ee");
Object[] data = all.toArray();
for(int i=0; i<data.length; i++){
System.out.print(data[i]+" ");
}
}
}