单链表的逻辑就不多说了,别的文章有很多细致的分析,直接上代码
首先是节点的实现:
public class Node{ private Node next;//下一节点地址 private E e;//数据域 //构造方法 public Node (){ } public Node (E e){ this.e = e; next = null; } //构造器和读取器 public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } public E getE() { return e; } public void setE(E e) { this.e = e; } }
接下来是单链表的实现:
public class linkList{ private Node head;//头结点 private Node last;//尾结点 private int size = 0;//链表长度 //创建链表 public linkList(){ head = new Node (); last = head; } public linkList(E e){ head = new Node (); last = head; } public boolean isEmpty(){ if(head == last){ return false; } return true; } public void clear(){ head = last; } public int size(){ return size; } public Node find(int i){ if(i < 0 || i >= size){ return null; } Node temp = head.getNext(); for(int k = 0 ; k < i ; k ++){ temp = temp.getNext(); } return temp; } public E getE(int i){ if(i < 0 || i >= size){ return null; } Node temp = find(i); return temp.getE(); } public int getI(E e){ E temp = e; int i; //找到指定位置 for(i = 0 ; ; i ++){ temp = getE(i); if(temp == e) { break; } if(temp == null){ return -1; } } return i; } public boolean exist(E e){ int i = getI(e); if(i == -1){ return false; } return true; } public boolean exist(int i){ if(find(i) == null){ return false; } return true; } public void add(E e){ Node newNode = new Node (e); last.setNext(newNode); last = newNode; size++; } public void add(E e,int i){ if(i >= 0 && i < size){ Node newNode = new Node (e); //如果添加位置为第一个节点则改变头结点next地址 if(i == 0){ newNode.setNext(head.getNext()); head.setNext(newNode); } else if(i == (size-1)){ last.setNext(newNode); last = newNode; } else{ newNode.setNext(find(i)); find(i-1).setNext(newNode); } } //将在队列中的添加到最后 else { add(e); } size++; } public void delete(int i){ if(i >= 0 && i < size){ Node temp = find(i); //当删除第一个节点时,改变头结点的next if(i == 0){ head.setNext(find(i+1)); } find(i-1).setNext(temp.getNext());//删除k位置的节点 } size--; } public void delete(E e){ int i = getI(e);//查找目标位置 if(i != -1){ Node temp = find(i); //当删除第一个节点时,改变头结点的next if(i == 0){ head.setNext(find(i+1)); } find(i-1).setNext(temp.getNext());//删除k位置的节点 size--; if(i < size){ delete(e); } } } public void remodel(E e,int i){ if(i >= 0 && i < size){ find(i).setE(e); } } public void remodel(E x,E e){ int i = getI(e); if(i != -1){ find(i).setE(x); if(i < size){ remodel(x,e); } } } public void remodel(Node node,int i){ if(i >= 0 && i < size){ find(i).setE(node.getE()) ; } } public void remodel (Node newNode,Node node){ int i = getI(node.getE()); if(i != -1){ find(i).setE(newNode.getE()) ; } } public String toString(){ String temp = new String(); for(int i = 0 ; i < size ; i ++){ if(i == 0 ){ E e = getE(i); temp = (String)e; } else{ E e = getE(i); temp = temp+","+(String)e; } } return temp; } }
顺便提供一个测试类:
class Main{
public static void main(String[] adsb){
linkList a = new linkList();//创建新链表
System.out.println(a.isEmpty());//判断是否为空
//添加节点
a.add("123");
a.add("456");
a.add("789");
System.out.println(a.toString());//输出链表
System.out.println(a.isEmpty());//再次判空
System.out.println(a.size());//判断长度
//在指定位置添加节点
a.add("234",1);
a.add("245",0);
System.out.println(a.toString());
//获取节点数据域与获得数据位置
System.out.println(a.getE(1));
System.out.println(a.getI("123"));
//测试各种删除模式
System.out.println(a.toString());//首先输出列表用于比对
a.delete(1);//删除1的节点
System.out.println(a.toString());
a.delete("234");//删除数据域为“234”的节点
System.out.println(a.toString());
//判断元素是否在单链表中
System.out.println(a.exist("234"));
System.out.println(a.exist("789"));
//各种替换测试
a.remodel("567", 2);//替换固定位置节点数据域
System.out.println(a.toString());
a.remodel("789","567");//用数据域替换节点数据域
System.out.println(a.toString());
Node b = new Node("789");//定义新的节点用于测试节点替换
Node c = new Node("567");//同上
a.remodel(c, 2);//固定位置的节点替换
System.out.println(a.toString());
a.remodel(b, c);//用节点替换节点
System.out.println(a.toString());
//测试清除方法
a.clear();
System.out.println(a.isEmpty());
}
}
链表的逻辑部分还有很大优化的空间,还有很多功能没有实现,不过对于我这次的实验来说已经够用了,所以就先这样,把这个单链表放在这里当做备忘录,也希望对大家有所帮助。



