简单链表的原理在这里就不赘述了,推荐一篇比较不错的博客:链表原理
需要实现的操作包括:
- 在头节点之前插入节点;
- 在尾节点之后插入节点;
- 删除包含指定数据的节点;
- 删除尾节点;
- 查找包含指定数据的节点;
- 获取链表的长度;
辅助操作包括:
- 清空链表;
- 判断链表是否为空。
下面是简单链表的实现
/**
* 注意:该链表实现不适合用于保存有重复元素的集合
*/
public class SingleList<Type> {
public static class SingleNode<Type> {
//节点作为内部静态类
private Type data;
private SingleNode next;
/**
* 三种构造方法
*/
public SingleNode(){
this.data = null;
this.next = null;
}
public SingleNode(Type data){
this.data = data;
next = null;
}
public SingleNode(Type data, SingleNode next){
this.data = data;
this.next = next;
}
/**
* data 的 get()和 set()方法
*/
public Type getData(){
return this.data;
}
public void setData(Type data){
this.data = data;
}
/**
* next 的 get()和 set()方法
*/
public SingleNode getNext(){
return this.next;
}
public void setNext(SingleNode next){
this.next = next;
}
}
private SingleNode head;
private SingleNode tail;
public SingleList(){
head = tail = null;
}
public SingleNode getHead(){
return this.head;
}
public SingleNode getTail() {
return tail;
}
/**
* 从头部添加节点
* @param data:添加的节点的数据
*/
public void addNodeBeforeHead(Type data){
if (this.head == null)//当前链表为空,则将这个新节点设置为头节点和尾节点
this.head = this.tail = new SingleNode(data,null);
else {//当前链表不为空,则将这个新节点放到头节点前,让这个新节点作为头节点
SingleNode node = new SingleNode(data,head);
head = node;
}
}
/**
* 从尾部添加节点
* @param data:添加的节点的数据
*/
public void addNodeAfterTail(Type data){
if (this.head == null){//当前链表为空,将这个新节点设置为头节点和尾节点
this.head = this.tail = new SingleNode(data,null);
} else {//当前链表不为空,将这个新节点放到尾节点后,让这个新节点作为尾节点
SingleNode node = new SingleNode(data,null);
tail.next = node;
tail = tail.next;
}
}
/**
* 根据数据删除节点
* @param data:需要删除的节点的数据
* 注意:会将数据域与 data 相同的、最靠近链表头的那一个节点删除掉
* @return 删除的节点 n
*/
public SingleNode removeNodeByData(Type data){
SingleNode n,before,current;
before = head;
if (before.getData().equals(data)){//删除的数据是链表头
n = before;//记录下表头节点
head = before.next;
return n;
}
while (before.next != null){//没有到链表末尾
current = before.next;//设置当前节点的值,即 before 的下一个节点
if (current.data.equals(data)){//如果当前节点的数据即为指定的数据 data
n = current;//保存下当前节点
before.next = current.next;//将 before 节点的后继节点设置为 current 节点的后继节点,实现删除current节点
return n;//删除完成
}
before = current;
}
return null;
}
/**
* 删除尾节点 tail
* @return 删除掉的原来的尾节点 tail
*/
public SingleNode removeTail(){
SingleNode current = head;
SingleNode oldTail = tail;
while (current.next.next != null){//下一个节点不是尾节点 tail
current = current.next;
}
//下一个节点是尾节点
current.next = null;//设置当前节点的后继节点为空
tail = current;//将当前节点设置为尾节点 tail
return oldTail;
}
/**
* 根据数据查找节点
* @param data :节点的数据
* @return :查找到的节点
* 注意 :该方法只返回满足要求的、离头节点最近的节点
*/
public SingleNode findNodeByData(Type data){
SingleNode current = head;
while (current.next != null) {
if (current.data.equals(data))
return current;
else
current = current.next;
}
return null;
}
/**
* 计算链表长度
* @return 链表的节点个数(即链表长度)
*/
public int getListLength(){
int count = 1;
SingleNode current = head;
while (current.next != null){
current = current.next;
count++;
}
return count;
}
/**
* 清空链表
*/
public void clear(){
head = null;
}
/**
* 判断链表是否为空
* @return 链表是否为空
*/
public boolean isEmpty(){
if ((head == null) && (tail == null))
return true;
return false;
}
/**
* 打印链表中的数据,仅用于测试
*/
public void display(){
SingleNode current = head;
while (current != null){
System.out.print(" " + current.data);
current = current.next;
}
System.out.println("\n");
}
}
下面是测试代码
public class SingleTest {
private static final int MULTI = 6;
private int data;
private SingleList<Integer> list = new SingleList();
private SingleList.SingleNode node;
public static void main(String[] args) {
SingleTest s = new SingleTest();
s.run();
}
public void run(){
System.out.println("新建链表:");
list.display();
System.out.println("初始化链表:使用addNodeAfterHead()方法");
for (int i = 0; i < 5; i++) {//初始化链表
list.addNodeBeforeHead(i*MULTI);
}
list.display();//打印链表
testAddNodeAfterHead(); //测试方法 addNodeBeforeHead()
testAddNodeAfterTail(); //测试方法 addNodeAfterTail()
testRemoveNodeByData(); //测试方法 removeNodeByData()
testRemoveTail(); //测试方法 removeTail()
testFindNodeByData(); //测试方法 findNodeByData()
testGetListLength(); //测试方法 getListLength()
}
public void testAddNodeAfterHead(){
data = -1;
System.out.println("从链表头部添加数据:" + data);
list.addNodeBeforeHead(data);
list.display();
}
public void testAddNodeAfterTail(){
data = 100;
System.out.println("从链表尾部添加数据:" + data);
list.addNodeAfterTail(data);
list.display();
}
public void testRemoveNodeByData(){
data = 24;
System.out.println("从链表中删除数据:" + data);
node = list.removeNodeByData(data);
if (node == null)
System.out.println("数据:" + data + " 不存在!");
else
System.out.println("删除数据:" + data + " 成功!");
list.display();
}
public void testRemoveTail(){
System.out.print("删除链表的尾部节点:");
node = list.removeTail();
if (node == null)
System.out.println("链表为空!");
else
System.out.println(node.getData());
list.display();
}
public void testFindNodeByData(){
data = 15;
System.out.println("查找数据:" + data);
node = list.findNodeByData(data);
if (node == null)
System.out.println("数据:" + data + " 不存在!");
else {
System.out.println(" 数据:" + node.getData());
System.out.println(" 后继节点:" + node.getNext());
}
list.display();
}
public void testGetListLength(){
int length = list.getListLength();
System.out.println("当前链表长度为:" + length);
}
}
格式不够好,还望多多包涵~/bq