链表结构
链表是有序的列表,以节点的形式储存,是链式存储。每个节点包括data(数据)和pointer(指针)。
链表的各个节点不一定是连续存储。
链表分为带头节点的链表和不带头节点的链表。
带头结点和不带头节点链表的区别
带头节点和不带头节点链表的优劣
不带头结点的单链表对于第一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常在单链表的开始结点之前附设一个头结点。
实现一个单链表
单链表节点实现
class Node
{
public int data;
public Node next;
public Node(int data){
this.data = data;
this.next = null;
}
}
单链表类实现
基础的链表类包括一下几种功能。
class SingleChainList
{
private Node headNode;
private int length;
//链表判空
//返回链表节点个数。
//插入
//头节点插入法
//尾节点插入法
//删除
//修改节点内容
}
链表判空
当链表中只有一个头节点时,链表就是空的
public boolean isNull(){
if (this.headNode.next == null)
{
return true;
}
return false;
}
插入
链表是否为空对插入节点没有影响,这是带头链表的优点之一
头插法的优点
不用遍历整个链表就可以插入节点
头插法插入节点
头节点插入法只需要两步
- 将待插入节点的next指针指向headNode.next
- 将headNode.next 指向待插入节点
- 节点个数加一
这里是引用
public void insertBing(Node temp){
temp.next = this.headNode.next;
this.headNode.next = temp;
this.length++;
}
尾差法插入节点
在尾部插入节点需要遍历整个链表
- 定义eagle指针存头节点开始遍历整个链表,当
eagle.next == null时说明到达链表尾部。可以插入节点。- eagle.next =temp
- temp.next = null 这句必须有,若end.next有值则会发生未知的错误,且很难调试出来
- 节点个数加一
public void insertEnd(Node temp){
Node eagle = this.headNode;
//找到链表尾部
while (eagle.next!=null)
{
eagle = eagle.next;
}
eagle.next = temp;
temp.next = null;
this.length++;
}
返回节点个数
public int getLength(){
return this.length;
}
修改节点内容
定义eagle指针遍历整个链表,知道eagle.next == null
在遍历过程中使用if语句判断该节点是否需要修改。
public void upData(int data,int newData){
Node eagle = this.headNode.next;
while (eagle != null)
{
if(eagle.data == data){
eagle.data = newData;
}
eagle = eagle.next;
}
}
删除节点
毫无疑问,删除节点是单链表的难点,需要关注的地方有:
- 链表是否为空
- 单链表不能实现自我删除(双链表可以)那么如何删除节点。
- 循环结束条件怎么写
- 最后一个节点和其他节点的删除操作有何不同
public void delete(int data){
if(this.isNull()){
return;
}
Node eagle = this.headNode;
while (eagle.next != null)
{
if(eagle.next.data == data){
eagle.next = eagle.next.next;
this.length--;
}
else if (eagle.next!=null) {
eagle = eagle.next;
}
}
}
运行结果展示
主方法
package SingleChainList;
import java.util.Scanner;
public class SingleChainListDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
SingleChainList list = new SingleChainList();
char ch;
boolean flag = true;
System.out.println("******** 菜单 ********");
System.out.println("\t在头部添加节点 < h >");
System.out.println("\t在尾部添加节点 < l >");
System.out.println("\t删除节点 < d >");
System.out.println("\t修改节点内容 < u >");
System.out.println("\t查看链表长度 < g >");
System.out.println("\t输出链表内容 < p >");
System.out.println("********************");
while (flag) {
System.out.println("请选择操作:");
ch = input.next().charAt(0);
switch (ch) {
case 'h':
System.out.println("请输入待加入的节点");
list.insertBing(new Node(input.nextInt()));
break;
case 'l':
System.out.println("请输入待加入的节点");
list.insertEnd(new Node(input.nextInt()));
break;
case 'd':
System.out.println("请输入待删除的节点");
list.delete(input.nextInt());
break;
case 'u':
System.out.println("请输入原内容和更正内容");
list.upData(input.nextInt(), input.nextInt());
break;
case 'g':
System.out.println("链表长度为:" + list.getLength());
break;
case 'p':
System.out.println(list);
break;
case 'e':
flag = false;
System.out.println("已退出!");
break;
default:
break;
}
}
input.close();
}
}
运行结果
Home is the destination of one’s soul
我会住在其中的一颗星星上面,在某一颗星星上微笑着,每当夜晚你仰望星空的时候,就会像是看到所有的星星都在微笑一般。
----小王子