一、基本概念
- 这种以"链"状形式串起来的队列,就称为链表;
- 链表中的每个对象称为节点(Node);
- 最前面的节点称为链表头,最后面的节点称为链表尾;
public class Student {
private String name;
private int id;
//实现链表的关键属性
public Student head;
public Student next;
public Student(String name, int id) {
super();
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Student [name=" + name + ", id=" + id + "]";
}
}
public class Demo {
public static void main(String[] args) {
Student s1 = new Student("小强",001);
Student s2 = new Student("小李",002);
Student s3 = new Student("小王",003);
Student s4 = new Student("小张",004);
//利用next属性将所有的实例串联起来
s1.next=s2;
s2.next=s3;
s3.next=s4;
s4.next=null;
//获得链表头之后,就可以利用next属性进行节点遍历
Student node=s1;
while(node!=null) {
System.out.println("链表中的节点:"+node);
node=node.next;
}
}
}
二、节点的插入
1 . 将新节点追加到链表的尾端;
public class Demo {
public static void main(String[] args) {
Student s1 = new Student("小强",001);
Student s2 = new Student("小李",002);
Student s3 = new Student("小王",003);
Student s4 = new Student("小张",004);
//利用next属性将所有的实例串联起来
s1.next=s2;
s2.next=s3;
s3.next=s4;
s4.next=null;
//需要插入到尾部的新节点
Student s5 = new Student("小齐",005);
//通过遍历找到node.next==null的节点,此节点也就是尾节点
Student node=s1;
while(true) {
if(node.next==null) {
break;
}
node=node.next;
}
node.next=s5;
//遍历输出所有节点
Student m=s1;
while(m!=null) {
System.out.println(m.toString());
m=m.next;
}
}
}
2 . 将新节点插入到任意位置;
思路:只需要让前一个节点的next属性指向新节点,新节点的next属性指向之后的属性即可;
public class Demo {
public static void main(String[] args) {
Student s1 = new Student("小强",001);
Student s2 = new Student("小李",002);
Student s3 = new Student("小王",003);
Student s4 = new Student("小张",004);
//利用next属性将所有的实例串联起来
s1.next=s2;
s2.next=s3;
s3.next=s4;
s4.next=null;
//需要插入到尾部的新节点
Student s5 = new Student("小齐",005);
//将节点插入任意位置的思路
s2.next=s5;
s5.next=s3;
//遍历输出所有节点
Student m=s1;
while(m!=null) {
System.out.println(m.toString());
m=m.next;
}
}
}
三、无头链表
public class Student {
private String name;
private int id;
// 实现链表的关键属性
private static Student head;
public Student next;
/**
* @param name:学生姓名
* @param id:学生编号
* @param index:追加位置,0表示默认追加到链表末尾,1表示链表头,以此类推
*/
public Student(String name, int id, int index) {
if (index >= 0) {
this.name = name;
this.id = id;
if (index == 0) {
addNode(this);
} else {
addNode(this, index);
}
} else {
System.out.println("输入错误!index参数必须大于等于0!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static Student getHead() {
return head;
}
// 判断链表长度
public static int length() {
int num = 0;
if (head != null) {
Student node = head;
while (node != null) {
num++;
node = node.next;
}
}
return num;
}
// 在链表末尾进行节点追加的方法
private void addNode(Student s) {
if (head == null) {
head = s;
} else {
Student node = head;
while (true) {
if (node.next == null)
break;
node = node.next;
}
node.next = s;
}
}
// 将节点追加到任意位置的方法
private void addNode(Student s, int index) {
int length = Student.length();
int num = 0;
if (length == 0 || index > length) {
addNode(s);
} else if (index == 1 && length > 0) {
s.next = head;
head = s;
} else {
Student node = head;
while (node != null) {
num++;
if (index - num == 1) {
break;
}
node = node.next;
}
s.next = node.next;
node.next = s;
}
}
/**
* 删除节点方法
*
* @param index:要删除的节点的坐标,0表示不执行删除,1表示链表头,以此类推
*/
public static void delNode(int index) {
int length = Student.length();
if (length == 0) {
System.out.println("无节点状态不能执行删除操作!");
return;
}
if (index > length) {
System.out.println("待删除节点坐标不能大于链表长度!");
return;
}
if (index >= 1) {
int num = 0;
if (length == 1 && index == 1) {
head = null;
System.out.println("删除成功!");
} else if (index == 1 && length != 1) {
head = head.next;
System.out.println("删除成功!");
} else if (index > 1 && index <= length) {
Student nodeBefore = head;
Student nodeDelete = head;
while (nodeBefore != null) {
num++;
if (index - num == 1) {
break;
}
nodeBefore = nodeBefore.next;
}
num = 0;
while (nodeDelete != null) {
num++;
if (num == index) {
break;
}
nodeDelete = nodeDelete.next;
}
nodeBefore.next = nodeDelete.next;
System.out.println("删除成功!");
}
} else {
System.out.println("执行删除操作的节点坐标不能小于1!");
}
}
@Override
public String toString() {
return "Student [name=" + name + ", id=" + id + "]";
}
}
无头链表是将第一个写入的节点作为头节点,之后写入的节点依次追加,可以在构造方法中指定节点插入的位置,在插入删除的时候需要进行多重判断,代码较为繁琐;
四、有头链表
有头链表是在程序中事先给定head,称为假节点,head.next作为头节点,在插入删除的时候简化了需要判断的条件;
public class Teacher {
private String name;
private int id;
// 实现链表的关键属性
private final static Teacher head = new Teacher("假节点", 0);
public Teacher next;
// 私有构造方法,用来创建假节点head
private Teacher(String name, int id) {
this.name = name;
this.id = id;
}
// 增加节点的构造方法
public Teacher(String name, int id, int index) {
if (index >= 0) {
this.name = name;
this.id = id;
addNode(this, index);
} else {
System.out.println("参数index不能小于0!");
}
}
// 判断链表长度的方法
public static int length() {
int num = 0;
Teacher t = head.next;
while (t != null) {
num++;
t = t.next;
}
return num;
}
// 增加节点的方法
private void addNode(Teacher t, int index) {
int length = Teacher.length();
if ((index == 0 && length == 0) || length == 0) {
head.next = t;
return;
}
if (index > length || (index == 0 && length != 0)) {
Teacher c = head.next;
while (c != null) {
if (c.next == null)
break;
c = c.next;
}
c.next = t;
} else if (index == 1) {
Teacher c = head.next;
int num = 0;
while (c != null) {
num++;
if (index - num == 0)
break;
c = c.next;
}
t.next = c;
head.next = t;
} else {
Teacher c = head.next;
int num = 0;
while (c != null) {
num++;
if (index - num == 1)
break;
c = c.next;
}
t.next = c.next;
c.next = t;
}
}
// 删除节点方法
public static void delNode(int index) {
int length = Teacher.length();
Teacher t = head.next;
if (length == 0) {
System.out.println("无节点!");
return;
}
if(index>length) {
System.out.println("index超出范围!");
return;
}
if (index >= 1) {
if (length == 1 && index == 1) {
head.next = null;
}
if(length!=1&&index==1) {
head.next=head.next.next;
}
if(length!=1&&index>1&&!(index>length)) {
int num=0;
while(t!=null) {
num++;
if(index-num==1) {
break;
}
t=t.next;
}
t.next=t.next.next;
}
} else {
System.out.println("index不能小于1!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static Teacher getHead() {
return head;
}
@Override
public String toString() {
return "Teacher [name=" + name + ", id=" + id + "]";
}
}