首先说一下单链表的添加,需要传入一个已初始化的头结点,可以参照初级链表简单案例—java版
核心代码如下
//在添加结点的时候顺便排好序,很重要
public void addByOrder(Node Head,Node newNode){
Node Temp = Head;
boolean flag = false;
while (true){
if (Temp.next == null){
break;
}
if (Temp.next.no == newNode.no){
flag = true;
break;
}
if (Temp.next.no > newNode.no){
break;
}
//指针后移
Temp = Temp.next;
}
if (flag == true) System.out.printf("链表中已经存在 %d 号元素啦!",newNode.no);
else{
newNode.next = Temp.next;
Temp.next = newNode;
}
}
现在很少人用单链表了,但单链表是很重要的,在把数据放入数据库或者是文件前,可以先把这些数据在单链表中排好序再放入,效率会比直接用sql语句排序要高
下面是几个重要的步骤
1. 添加结点,首先要遍历链表去找符合条件的结点,所以要把头结点赋给Temp结点,让Temp结点去操作
2. 此时定义一个flag变量来记录是否有与待插入结点相同编号的结点
3. 开始循环了,首先要判断是否来到链表的末尾?这就意味着如果来到链表末尾,此结点是此链表中数值最大的结点
4. 要判断是否有相同序号的结点,相同的话也会截止(当然也小伙伴们可以取消此判断,这样就可以插入相同序号的结点)
5. 最后一个判断是:如果后一个结点比待插入结点序号大,那么就结束循环了,因为这个插入的机制就是从小到大插入,所以首次判断后一个结点比待插入结点序号大的条件为true的时候就是要插入的位置
可能有点绕哈,其实也不难理解,我们可以把判断条件深入探究一下,判断条件为Temp.next.no > newNode.no,而恰好链表中是1,2,3,5,那么插入4会插在哪里呢?
解释这个条件→只要发现链表内结点序号大于新结点序号,就停止循环,循环外的Temp刚好在这个位置,5大于4,所以此时的Temp是3。
最后别忘了指针后移Temp = Temp.next
下面结点的删除修改和查询一起展示,大体思路都差不多
public class SingleLinkedList {
public static void main(String[] args) {
LinkListOptions linkListOptions = new LinkListOptions();
Node Head = linkListOptions.init();
Node newNode1 = new Node(1,"张三");
Node newNode2 = new Node(2,"李四");
Node newNode3 = new Node(3,"张三");
Node newNode4 = new Node(4,"李四");
Node newNode5 = new Node(5,"张三");
Node newNode6 = new Node(6,"李四");
//排序添加
linkListOptions.addByOrder(Head,newNode1);
linkListOptions.addByOrder(Head,newNode3);
linkListOptions.addByOrder(Head,newNode6);
linkListOptions.addByOrder(Head,newNode4);
linkListOptions.addByOrder(Head,newNode5);
linkListOptions.addByOrder(Head,newNode2);
linkListOptions.DeleteSomeNode(Head,newNode6);
linkListOptions.Traverse(Head);
/*
*
* System.out.println("修改后的链表如下");
Node newNode7 = new Node(3,"小旋风");
linkListOptions.updateSomeNode(Head,newNode7);
linkListOptions.Traverse(Head);
* */
}
}
//管理结点
class LinkListOptions{
public LinkListOptions(){
}
//初始化头节点
public Node init(){
return new Node(0,"");
}
//修改结点
public void updateSomeNode(Node Head,Node newNode){
if (Head.next == null){
System.out.println("链表为空,无法修改结点!");
return;
}
//把第一个数据结点赋给Temp,而不是Head
Node Temp = Head.next;
boolean flag = false;
while(true){
if (Temp == null){
System.out.println("链表已经到头啦!无法找到代修改的结点!");
break;
}
if (Temp.no == newNode.no){
flag = true;
break;
}
Temp = Temp.next;
}
if (flag == false) System.out.println("没有找到当前元素哦!");
else Temp.name = newNode.name;
}
//删除某个结点
public void DeleteSomeNode(Node Head,Node newNode){
if (Head.next == null){
System.out.println("链表为空,无法删除结点!");
return;
}
Node Temp = Head;
boolean flag = false;
while(true){
if (Temp.next == null){
System.out.println("已经到链表最后啦!无法找到待删除的结点!");
break;
}
if (Temp.next.no == newNode.no){
//标记为true,意为已找到该结点
flag = true;
break;
}
//指针后移
Temp = Temp.next;
}
if (flag == true){
Temp.next = Temp.next.next;
}
}
//遍历结点
public void Traverse(Node Head){
if (Head.next == null){
System.out.println("链表为空!");
return;
}
Node Temp = Head.next;
while(true){
if (Temp == null){
System.out.println("已经遍历完链表啦!");
break;
}
System.out.println(Temp);
Temp = Temp.next;
}
}
}
//结点类
class Node{
int no;//编号
String name;//姓名
Node next;//指针
public Node(int no,String name){
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}