单链表—Single Linked List

一、单链表的存储方式

  • 头指针:指向链表第一个元素的地址值150
  • data域代表此处存储的值,next域指向下一个元素的地址
  • 链表是以节点的方式存储的,而且链表上相邻两个节点的地址不一定相邻,也就是说不一定是连续存放的
  • 当next域为null时,表示链表结束
  • 链表分为有头节点的和无头节点的链表,根据实际需求来定

 

二、向单链表添加元素(增)

需求:定义一组梁山好汉对象,id代表其排位。将其添加到链表中

 

add的思路分析:

  • 找到最后一个节点,把它的next替换为要添加的元素。next为null的节点,即为最后一个节点
  • 通过遍历的方式来找最后一个节点,关键在于定义辅助指针temp
public class LinkedListTest {
    public static void main(String[] args){

        heroNode hero1 = new heroNode(1,"宋江","及时雨");
        heroNode hero2 = new heroNode(2,"卢俊义","玉麒麟");
        heroNode hero3 = new heroNode(3,"吴用","智多星");
        heroNode hero4 = new heroNode(4,"林冲","豹子头");

        SingleLinkedList linklist1 = new SingleLinkedList();
        linklist1.add(hero1);
        linklist1.add(hero2);
        linklist1.add(hero3);
        linklist1.add(hero4);
        linklist1.showLinkedList();
    }
}

class heroNode{
    public int id;//梁山排位
    public String name;
    public String nickname;
    public heroNode next;//next域

    public heroNode(int id, String name, String nickname){
        this.id = id;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "id:"+id+"  "+"name:"+name;
    }
}

class SingleLinkedList{

    //有头节点的链表,头节点只是通过head.next的方式,方便找到链表的第一个元素是谁
    //头节点定以后一般不能改动
    private heroNode head = new heroNode(0,"","");

    //向链表末尾添加元素
    public void add(heroNode hero){

        //定义一个辅助指针
        heroNode temp = head;

        //遍历链表,找到最后一个元素
        while (true){
            if (temp.next == null){
                //此时tempt就指向了最后一个元素
                break;
            }else {
                temp = temp.next;
            }
        }

        temp.next = hero;//添加成功
    }

    //显示链表所有元素
    public void showLinkedList(){
        heroNode temp = head;
        if (head.next == null){
            System.out.println("链表空");
        }
        while (temp.next != null){
            System.out.println(temp.next);
            temp = temp.next;
        }
    }

}

第二种添加方式

——添加时按照id顺序从小到大插入到链表

import java.util.concurrent.TimeoutException;

public class LinkedListTest {
    public static void main(String[] args){

        heroNode hero1 = new heroNode(1,"宋江","及时雨");
        heroNode hero2 = new heroNode(2,"卢俊义","玉麒麟");
        heroNode hero3 = new heroNode(3,"吴用","智多星");
        heroNode hero4 = new heroNode(4,"林冲","豹子头");

        SingleLinkedList linklist1 = new SingleLinkedList();
        linklist1.addByOrder(hero4);
        linklist1.addByOrder(hero2);
        linklist1.addByOrder(hero1);
        linklist1.addByOrder(hero3);
       // linklist1.addByOrder(hero1);//java.lang.RuntimeException: 此好汉已经在链表中
        linklist1.showLinkedList();





    }
}

class heroNode{
    public int id;//梁山排位
    public String name;
    public String nickname;
    public heroNode next;//next域

    public heroNode(int id, String name, String nickname){
        this.id = id;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "id:"+id+"  "+"name:"+name;
    }
}

class SingleLinkedList{

    //有头节点的链表,头节点只是通过head.next的方式,方便找到链表的第一个元素是谁
    //头节点定以后一般不能改动
    private heroNode head = new heroNode(0,"","");
    
    public void addByOrder(heroNode hero){

        heroNode temp = head;

        /*
        这个while循环是精髓,多理解几遍!
        while循环的作用就是:把辅助指针temp指向的节点A,A后面插入新节点。
         */
        while (true){
            if (temp.next==null){//说明指针已经到链表末尾了,就插在末尾
                break;
            }
            if (hero.id<temp.next.id){//找到位置了,插在temp的后面
                break;
            }
            if (hero.id==temp.next.id){
                throw new RuntimeException("此好汉已经在链表中");
            }
            temp = temp.next;
        }

        hero.next = temp.next;
        temp.next = hero;


    }

    //显示链表所有元素
    public void showLinkedList(){
        heroNode temp = head;
        if (head.next == null){
            System.out.println("链表空");
        }
        while (temp.next != null){
            System.out.println(temp.next);
            temp = temp.next;
        }
    }

}

虽然是无序插入的,但是链表内部是按id顺序排的

 

三、修改链表中的某一个节点信息(改)

需求——根据新定义的一个  HeroNode newHeroNode = new HeroNode(2, "小卢", "玉麒麟~~");   ,修改链表中对应id=2的节点的name和nickname,但是不改变id。



public class LinkedListTest {
    public static void main(String[] args){

        heroNode hero1 = new heroNode(1,"宋江","及时雨");
        heroNode hero2 = new heroNode(2,"卢俊义","玉麒麟");
        heroNode hero3 = new heroNode(3,"吴用","智多星");
        heroNode hero4 = new heroNode(4,"林冲","豹子头");

        SingleLinkedList linklist1 = new SingleLinkedList();
        linklist1.addByOrder(hero4);
        linklist1.addByOrder(hero2);
        linklist1.addByOrder(hero1);
        linklist1.addByOrder(hero3);
       // linklist1.addByOrder(hero1);//java.lang.RuntimeException: 此好汉已经在链表中
        System.out.println("修改前");
        linklist1.showLinkedList();

        System.out.println("修改后");
        linklist1.update(new heroNode(1,"小宋","大傻逼"));
        linklist1.showLinkedList();





    }
}

class heroNode{
    public int id;//梁山排位
    public String name;
    public String nickname;
    public heroNode next;//next域

    public heroNode(int id, String name, String nickname){
        this.id = id;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "id:"+id+"  "+"name:"+name+"  "+"nickname:"+nickname;
    }
}

class SingleLinkedList{

    //有头节点的链表,头节点只是通过head.next的方式,方便找到链表的第一个元素是谁
    //头节点定以后一般不能改动
    private heroNode head = new heroNode(0,"","");

    public void addByOrder(heroNode hero){

        heroNode temp = head;

        /*
        这个while循环是精髓,多理解几遍!
        while循环的作用就是:把辅助指针temp指向的节点A,A后面插入新节点。
         */
        while (true){
            if (temp.next==null){//说明指针已经到链表末尾了,就插在末尾
                break;
            }
            if (hero.id<temp.next.id){//找到位置了,插在temp的后面
                break;
            }
            if (hero.id==temp.next.id){
                throw new RuntimeException("此好汉已经在链表中");
            }
            temp = temp.next;
        }

        hero.next = temp.next;
        temp.next = hero;


    }

    public void update(heroNode hero){

        //先寻找对应id的节点
        heroNode temp = head.next;
        boolean flag = false;
        while(true){
            if (temp==null){//说明到尾部了
                break;
            }
            if (temp.id == hero.id){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag==true){
            temp.name = hero.name;
            temp.nickname = hero.nickname;
        }else {
            System.out.println("链表中没有此好汉!");
        }
    }

    //显示链表所有元素
    public void showLinkedList(){
        heroNode temp = head;
        if (head.next == null){
            System.out.println("链表空");
        }
        while (temp.next != null){
            System.out.println(temp.next);
            temp = temp.next;
        }
    }

}

 

四、删除某个节点

需求——删除指定id的节点

  public void delete(int ID){
        heroNode temp1 = head;
        heroNode temp2 = head.next;
        boolean flag = false;
        while (true){
            if (temp2==null){
                System.out.println("链表中没有此好汉");
                break;
            }
            if (temp2.id==ID){
                flag = true;//说明找到了
                break;
            }
            temp1 = temp2;
            temp2 = temp2.next;
        }

        if(flag){
            temp1.next = temp2.next;
        }

    }

思路

  •  定义两个辅助指针—temp1和temp2。一个指向while循环结束后,temp2指向要被删除的节点,temp1始终指向temp2的前一个节点。

  • 然后将temp1和temp2.next连起来,temp2会被垃圾回收机制自动回收

  • flag的作用:让你知道while循环有没有找到对应的节点,如果找到了再进行删除,如果没找到,就不用删了



public class LinkedListTest {
    public static void main(String[] args){

        heroNode hero1 = new heroNode(1,"宋江","及时雨");
        heroNode hero2 = new heroNode(2,"卢俊义","玉麒麟");
        heroNode hero3 = new heroNode(3,"吴用","智多星");
        heroNode hero4 = new heroNode(4,"林冲","豹子头");

        SingleLinkedList linklist1 = new SingleLinkedList();
        linklist1.addByOrder(hero4);
        linklist1.addByOrder(hero2);
        linklist1.addByOrder(hero1);
        linklist1.addByOrder(hero3);
       // linklist1.addByOrder(hero1);//java.lang.RuntimeException: 此好汉已经在链表中
        System.out.println("修改前");
        linklist1.showLinkedList();

        System.out.println("修改后");
        linklist1.update(new heroNode(1,"小宋","大傻逼"));
        linklist1.showLinkedList();

        linklist1.delete(1);
        linklist1.delete(3);
        linklist1.delete(4);
        System.out.println("删除后");
        linklist1.showLinkedList();

    }
}

class heroNode{
    public int id;//梁山排位
    public String name;
    public String nickname;
    public heroNode next;//next域

    public heroNode(int id, String name, String nickname){
        this.id = id;
        this.name = name;
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "id:"+id+"  "+"name:"+name+"  "+"nickname:"+nickname;
    }
}

class SingleLinkedList{

    //有头节点的链表,头节点只是通过head.next的方式,方便找到链表的第一个元素是谁
    //头节点定以后一般不能改动
    private heroNode head = new heroNode(0,"","");

    public void addByOrder(heroNode hero){

        heroNode temp = head;

        /*
        这个while循环是精髓,多理解几遍!
        while循环的作用就是:把辅助指针temp指向的节点A,A后面插入新节点。
         */
        while (true){
            if (temp.next==null){//说明指针已经到链表末尾了,就插在末尾
                break;
            }
            if (hero.id<temp.next.id){//找到位置了,插在temp的后面
                break;
            }
            if (hero.id==temp.next.id){
                throw new RuntimeException("此好汉已经在链表中");
            }
            temp = temp.next;
        }

        hero.next = temp.next;
        temp.next = hero;


    }

    public void update(heroNode hero){

        //先寻找对应id的节点
        heroNode temp = head.next;
        boolean flag = false;
        while(true){
            if (temp==null){//说明到尾部了
                break;
            }
            if (temp.id == hero.id){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag==true){
            temp.name = hero.name;
            temp.nickname = hero.nickname;
        }else {
            System.out.println("链表中没有此好汉!");
        }
    }

    public void delete(int ID){
        heroNode temp1 = head;
        heroNode temp2 = head.next;
        boolean flag = false;
        while (true){
            if (temp2==null){
                System.out.println("链表中没有此好汉");
                break;
            }
            if (temp2.id==ID){
                flag = true;//说明找到了
                break;
            }
            temp1 = temp2;
            temp2 = temp2.next;
        }

        if(flag){
            temp1.next = temp2.next;
        }



    }

    //显示链表所有元素
    public void showLinkedList(){
        heroNode temp = head;
        if (head.next == null){
            System.out.println("链表空");
        }
        while (temp.next != null){
            System.out.println(temp.next);
            temp = temp.next;
        }
    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值