1、定义结点Node
这里结点的数据域是(int,String,String)
下一节点next统一初始化为null
并且提供一个有参构造函数public Node(int no,String name,String nickName)
为了方便实例输出,还重写了方法toString()
class Node
{
//数据域
int no;
String name;
String nickName;
//下一节点
Node next=null;
//构造器
public Node(int no,String name,String nickName)
{
this.no=no;
this.name=name;
this.nickName=nickName;
}
//为了显示方便,重写toString()
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '}';
}
}
2、链表的总体结构
首先是定义一个头结点head,后续的增删改操作都是得通过head来实现的,但是并不是以head来遍历操作,而是为其创建一个副本来操作,因为需要根据头结点head来找到这个链表,因此不能修改head相关的值,应该是为其创建副本
方法 add(Node node) 是直接在链表的结尾添加新结点
方法 addByOrder(Node node) 是根据结点的数据域中的no值来按顺序添加结点
方法 printList() 是输出链表的值
方法 update(Node node,int pos) 是根据下标pos(由0开始)来更改结点,将下标为pos的结点修改为node
方法 delete(int pos) 是根据下标pos(由0开始)来删除结点
3、在链表尾部添加结点
public void add(Node node)
{
//找到最后一个结点,将其next域指向新结点即可
//由于head不能修改,因此需要一个辅助指针
Node temp=head;
//遍历链表找到最后一个结点
while(true)
{
if(temp.next==null)
{
break;
}
else
{
//后移
temp=temp.next;
}
}
//当退出循环时,此时temp即链表的最后一个结点,使temp指向新的结点
temp.next=node;
node.next=null;
}
4、根据结点数据域中的no值来添加结点
public void addByOrder(Node node)
{
Node pNode=head;
if(null==head.next)
{
add(node);
}
else
{
/*找到符合插入位置的前一个结点pNode,判断node与pNode.next之间的关系
若pNode.next.no<=node.no,那么还得接着往后找
若pNode.next.no>node.no,那么就找到了位置,修改
node.next=pNode.next; pNode.next=node;*/
while(pNode.next!=null)
{
if(pNode.next.no>node.no)
{
node.next=pNode.next;
pNode.next=node;
return; //添加完毕,直接退出
}
pNode=pNode.next;
}
if(pNode.next==null)
{
add(node); //如果到了这一步,说明其值是最大的,直接在结尾添加
}
}
}
5、更新结点
public void update(Node node,int pos)
{
Node pNode=head.next;
int i=0;
//寻找修改的位置,若位置超过链表长度或者链表初始长度为0,那么不会经过此循环
while(i<pos && pNode!=null)
{
i++;
pNode=pNode.next;
}
if(i==pos && pNode!=null) //i能到达pos且此结点不是不存在的结点,则能修改
{
pNode.no=node.no;
pNode.name=node.name;
pNode.nickName=node.nickName;
System.out.printf("修改位置%d的结点成功\n",i);
}
else
{
System.out.printf("修改位置%d的结点失败\n",i);
}
}
6、删除结点
public void delete(int pos) //找到待删除结点的前一个结点
{
Node pNode=head;
boolean flag=false;
int i=-1;
while(true) //退出条件为到达找到待删除结点的前一个结点位置,或者是到达最后一个结点,到达最后一个结点说明无法删除该元素
{
if(pNode.next==null) //先判断位置是否合理再判断是否为待删除结点的前一个位置,否则会出现pNode.next.next的空指针报错
{
//说明是遍历到最后一个位置了,说明删除的位置有问题
System.out.println("删除位置有问题");
break;
}
else if (i+1 == pos)
{
Node temp = pNode.next;
pNode.next = pNode.next.next;
flag=true;
System.out.println("删除结点成功,结点为" + temp.toString());
break;
}
else
{
//继续遍历
pNode=pNode.next;
i++;
}
}
}
7、打印链表
public void printList()
{
if(head.next==null)
{
//说明此时链表中无任何元素
return; //退出此方法
}
Node tempHead=head.next;//指向链表的第一个元素
while(tempHead!=null)
{
System.out.println(tempHead.toString());
tempHead=tempHead.next;
}
}
8、测试样例
public class MyLinkedList {
public static void main(String args[])
{
Node node1=new Node(1,"宋江","及时雨");
Node node2=new Node(2,"卢俊义","玉麒麟");
Node node3=new Node(3,"吴用","智多星");
Node node5=new Node(3,"武松","智多星");
Node node4=new Node(4,"林冲","豹子头");
//创建链表
linkedList L=new linkedList();
L.addByOrder(node1);
L.addByOrder(node4);
L.addByOrder(node3);
L.addByOrder(node2);
L.addByOrder(node5);
//显示
L.printList();
System.out.println("------------------------------------修改节点-------------------------------------------");
L.update(new Node(10,"小林","木木"),3);
System.out.println("修改后的链表:");
L.printList();
L.update(new Node(9,"赵明","小明"),0);
System.out.println("修改后的链表:");
L.printList();
L.update(new Node(8,"张三","小张"),4);
System.out.println("修改后的链表:");
L.printList();
L.update(new Node(7,"李四","小李"),5);
System.out.println("修改后的链表:");
L.printList();
System.out.println("------------------------------------删除节点-------------------------------------------");
for(int i=4;i>=0;i--)
{
L.delete(i);
System.out.println("删除后的链表");
L.printList();
}
}
}
运行结果:
源代码:
package linkedList;
class Node
{
//数据域
int no;
String name;
String nickName;
//下一节点
Node next=null;
//构造器
public Node(int no,String name,String nickName)
{
this.no=no;
this.name=name;
this.nickName=nickName;
}
//为了显示方便,重写toString()
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
", nickName='" + nickName + '}';
}
}
//定义一个链表
class linkedList
{
//初始化一个头结点,并且之后都不要对其进行修改,因为要靠这个头结点访问后续的结点
private Node head=new Node(0,"","");
//添加结点到链表
public void add(Node node)
{
//找到最后一个结点,将其next域指向新结点即可
//由于head不能修改,因此需要一个辅助指针
Node temp=head;
//遍历链表找到最后一个结点
while(true)
{
if(temp.next==null)
{
break;
}
else
{
//后移
temp=temp.next;
}
}
//当退出循环时,此时temp指向新的结点
temp.next=node;
node.next=null;
}
public void addByOrder(Node node)
{
Node pNode=head;
if(null==head.next)
{
add(node);
}
else
{
/*找到符合插入位置的前一个结点pNode,判断node与pNode.next之间的关系
若pNode.next.no<=node.no,那么还得接着往后找
若pNode.next.no>node.no,那么就找到了位置,修改
node.next=pNode.next; pNode.next=node;*/
while(pNode.next!=null)
{
if(pNode.next.no>node.no)
{
node.next=pNode.next;
pNode.next=node;
return; //添加完毕,直接退出
}
pNode=pNode.next;
}
if(pNode.next==null)
{
add(node); //如果到了这一步,说明其值是最大的,直接在结尾添加
}
}
}
public void printList()
{
if(head.next==null)
{
//说明此时链表中无任何元素
return; //退出此方法
}
Node tempHead=head.next;//指向链表的第一个元素
while(tempHead!=null)
{
System.out.println(tempHead.toString());
tempHead=tempHead.next;
}
}
public void update(Node node,int pos)
{
Node pNode=head.next;
int i=0;
//寻找修改的位置,若位置超过链表长度或者链表初始长度为0,那么不会经过此循环
while(i<pos && pNode!=null)
{
i++;
pNode=pNode.next;
}
if(i==pos && pNode!=null) //i能到达pos且此结点不是不存在的结点,则能修改
{
pNode.no=node.no;
pNode.name=node.name;
pNode.nickName=node.nickName;
System.out.printf("修改位置%d的结点成功\n",i);
}
else
{
System.out.printf("修改位置%d的结点失败\n",i);
}
}
public void delete(int pos) //找到待删除结点的前一个结点
{
Node pNode=head;
boolean flag=false;
int i=-1;
while(true) //退出条件为到达找到待删除结点的前一个结点位置,或者是到达最后一个结点,到达最后一个结点说明无法删除该元素
{
if(pNode.next==null) //先判断位置是否合理再判断是否为待删除结点的前一个位置,否则会出现pNode.next.next的空指针报错
{
//说明是遍历到最后一个位置了,说明删除的位置有问题
System.out.println("删除位置有问题");
break;
}
else if (i+1 == pos)
{
Node temp = pNode.next;
pNode.next = pNode.next.next;
flag=true;
System.out.println("删除结点成功,结点为" + temp.toString());
break;
}
else
{
//继续遍历
pNode=pNode.next;
i++;
}
}
}
}
public class MyLinkedList {
public static void main(String args[])
{
Node node1=new Node(1,"宋江","及时雨");
Node node2=new Node(2,"卢俊义","玉麒麟");
Node node3=new Node(3,"吴用","智多星");
Node node5=new Node(3,"武松","智多星");
Node node4=new Node(4,"林冲","豹子头");
//创建链表
linkedList L=new linkedList();
L.addByOrder(node1);
L.addByOrder(node4);
L.addByOrder(node3);
L.addByOrder(node2);
L.addByOrder(node5);
//显示
L.printList();
System.out.println("------------------------------------修改节点-------------------------------------------");
L.update(new Node(10,"小林","木木"),3);
System.out.println("修改后的链表:");
L.printList();
L.update(new Node(9,"赵明","小明"),0);
System.out.println("修改后的链表:");
L.printList();
L.update(new Node(8,"张三","小张"),4);
System.out.println("修改后的链表:");
L.printList();
L.update(new Node(7,"李四","小李"),5);
System.out.println("修改后的链表:");
L.printList();
System.out.println("------------------------------------删除节点-------------------------------------------");
for(int i=4;i>=0;i--)
{
L.delete(i);
System.out.println("删除后的链表");
L.printList();
}
}
}