代码实现了单链表的插入、删除、打印、获取链表长度。
完整代码:
package com.dhasa.test;
/**
* 测试类
* @author DL
*/
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add(0, "hello");
ll.add(0, "linkedlist");
ll.add(0, "I");
ll.add(0,"enjoy");
ll.add(0, "this time");
ll.add(0,"no");
ll.add(4, "this time");
ll.add(1, "this time");
ll.delAllNode("this time");
//ll.add(6, "no");
System.out.println(ll.getListLength(ll.getHead()));
ll.printNode(ll.getHead());
}
}
/**
* 链表实现
* @author DL
*/
class LinkedList{
private Node head = null;
//get方法用于外部获取私有变量head
public Node getHead() {
return head;
}
public void setHead(Node head) {
this.head = head;
}
/**
* 定义一个节点内部类
*/
private class Node{
private Object obj;//节点的数据域
private Node next;//节点的索引域
public Node(Object obj){
this.obj = obj;
//新建一个节点时,其索引域是空的,毋庸置疑,所以构造方法可以不写
this.next = null;
}
}
/**
* 指定位置,插入一个新节点
* 此方法在插入头结点或者在第0个位置插入时有问题
*/
// public void add(int index, Object obj) {
// int pos = 0;
// Node node = new Node(obj);
// Node current = head;
// Node previous = head;
// while ( pos != index) {
// previous = current;
// current = current. next;
// pos++;
// }
// node. next = current;
// previous. next = node;
// }
/**
* 指定位置,插入一个新节点
* 此方法导致头插入有问题
* 当index==0,head不为null时,进入else分支会有问题
*/
// public void add(int index,Object obj){
// Node descNode = new Node(obj);
// if(0==index && null==head){
// descNode.next = head;
// head = descNode;
// }else if(0!=index && null==head){
// System.out.println("插入不合理!插入失败!");
// }else{
// int pos = 0;
// Node current = head;
// Node previous = head;
// while ( pos != index) {
// previous = current;
// current = current. next;
// pos++;
// }
// descNode.next = current;
// previous.next = descNode;
// }
// }
/**
* 指定位置,插入一个节点
*/
public void add(int index,Object obj){
Node descNode = new Node(obj);
if(0!=index && null==head){
System.out.println("插入不合理!插入有失败!");
}else if(index>getListLength(head)){//参数head不是同一份儿,所以不会将链表置空
System.out.println("索引存在不合理!插入有失败!");
}else if(0==index ||null==head){//保证头插法以及head为空的插入
//因为index为0,所以均为头插法
descNode.next = head;
head = descNode;
}else{//保证尾插法
int pos = 0;
Node current = head;//当前节点
//记录上一个节点,当前节点为目标节点时,无论是删除还是插入都需要上一个节点的信息
Node previous = head;
while ( pos != index) {
previous = current;
current = current. next;
pos++;
}
//插入新节点(因为index不为0,所以均为尾插法)
descNode.next = current;
previous.next = descNode;
}
}
/**
* 得到链表的长度,此方法会影响后面的打印方法,打印得不到任何数据
* 因为头指针赋值为null
*/
// public int getListLength(){
// int length = 0;
// while(head!=null){
// length++;
// head = head.next;
// }
// return length;
// }
/**
* 得到链表的长度
* node为参数,在内存中的另外一份儿,其改变不影响原链表
*/
public int getListLength(Node node){
int length = 0;
while(node!=null){
length++;
node = node.next;
}
return length;
}
/**
* 递归打印链表
*/
public void printNode(Node head){
if(null!=head){
System.out.print(head.obj+"->");
Node node = head.next;
printNode(node);
}
}
/**
* 非递归打印链表
*/
// public void printNode(Node head){
// while(head!=null){
// System.out.println(head.obj);
// head=head.next;//索引向后移位
// }
// }
/**
* 根据节点数据删除节点
* (1)如果有连续重复数据,只能删除一个
* (2)如果重复数据不连续,则可以全部删除
*/
// public void delNode(Object obj){
// if(null==head){
// System.out.println("此链表为空!");
// }else if(head.obj.equals(obj)){
// head = head.next;
// }else{
// Node previous = head;
// Node current = head.next;
// while(null!=current){
// if(current.obj.equals(obj)){
// previous.next = current.next;
// }
// previous = current;
// current = current.next;
// }
// }
// }
/**
* 稍作修改,删除全部目标节点
* 如果没有目标节点,则执行完毕即可
* @param obj
*/
public void delAllNode(Object obj){
if(null==head){
System.out.println("此链表为空!");
}else if(head.obj.equals(obj)){
head = head.next;
}else{
Node previous = head;
Node current = head.next;
while(null!=current){
if(current.obj.equals(obj)){
previous.next = current.next;
current = current.next;//避免无法删除连续重复数据
}else{
previous = current;
current = current.next;
}
}
}
}
}