单链表的原理及实现,你肯定会吗?

前言

数据结构是计算机存储、组织数据的方式。若是不会数据结构,那么就不可能写出好的代码,所以。数据结构是咱们学习编程不可或缺的一部分!链表是数据结构中的一种,可是链表又分为单向链表,双向链表,循环链表,本篇文章主要是聊聊链表中的单向链表。算法

单向链表(single-linked list)概述

一个单链表的节点(Node)分为两部分,第一个部分(data)保存或者显示关于节点的信息,另外一个部分储存下一个节点的地址,最后一个节点的储存地址部分指向空值。编程

单向表只可向一个方向便利,通常查找一个节点的时候须要从第一个节点开始每次访问下一个节点,一直访问到须要的位置。而插入一个节点,对于单向链表,咱们只提供在链表头插入,只须要将当前的节点设置为头节点,next指向源头节点便可。删除一个节点,咱们将该节点的上一个的next指向下一个节点
单链表的原理及实现,你肯定会吗?数据结构

算法分析:

链表中元素的增长(须要按照编号的顺序添加):

  1. 首先找到新添加的节点的位置, 是经过辅助变量(指针), 经过遍从来搞定
  2. (新的节点)heroNode.next = temp.next
  3. 将temp.next = heroNode.next(新的节点)

单链表的原理及实现,你肯定会吗?

链表中元素的删除(须要按照编号进行删除):

  1. 咱们先找到须要删除的这个节点的前一个节点 temp
  2. temp.next.no = herNode.next(temp.next.next)
  3. 被删除的节点,将不会有其它引用指向,会被垃圾回收机制回收
    单链表的原理及实现,你肯定会吗?

    链表中元素的修改(须要按照编号进行删除):

    一、按照no找到要修改的编号
    二、temp.name=newHeroNode.name;
    三、temp.nickName=newHeroNode.nickName;ide

    注意事项:

    在建立、修改、删除中所建立的辅助变量temp都是必须的,由于head的值是不能变化的,一旦head发生变化,整个链表就会报错。学习

    代码实现:

public class SingleLinkedListDemo {

    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 singleLinkedList = new SingleLinkedList();
        //singleLinkedList.add(hero1);
        //singleLinkedList.add(hero2);
        //singleLinkedList.add(hero3);
        //singleLinkedList.add(hero4);
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero2);
        singleLinkedList.addByOrder(hero3);
        singleLinkedList.addByOrder(hero3);
        System.out.println("修改前:");
        singleLinkedList.list();
        HeroNode newHeroNode =new HeroNode(2, "小卢", "小麒麟");
        singleLinkedList.update(newHeroNode);
        System.out.println("修改后:");
        singleLinkedList.list();
        singleLinkedList.delete(hero3);
        System.out.println("删除后:");
        singleLinkedList.list();
    }

}
class SingleLinkedList{
    //先初始化一个头结点,头结点不要动,不存放具体数据
    private HeroNode head = new HeroNode(0, "", "");
    public void add(HeroNode heroNode) {
        HeroNode temp = head;//定义一个辅助变量来存放head,由于head是不可变的
        //遍历链表,找到最后
        while(true) {
            if(temp.next==null) {
                break;//找到链表的最后一个以后。break
            }
            //若是没有找到,就将temp后移,当退除循环时,temp指向链表的最后
            temp = temp.next;
        }
        //temp指向新的节点
        temp.next = heroNode;
    }
    public void addByOrder(HeroNode heroNode) {
        HeroNode temp = head;
        //由于时单链表,所以咱们要找的temp是位于插入节点前一个位置的不然插入不了
        boolean flag = false;//flag标志添加的编号是否存在,默认为false
        while(true) {
            if(temp.next==null)//temp已经再链表的最后,break
                break;
            if(temp.next.no>heroNode.no)//与添加位置的后一位no进行比较,位置已找到
                break;
            else if(temp.next.no==heroNode.no){//说明但愿添加的heroNode的编号已经存在
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag == true) {
            System.out.printf("准备插入的这个英雄的编号%d已经存在,不能加入",heroNode.no);
            System.out.println();
        }
        else {
            //插入到链表中
            heroNode.next=temp.next;
            temp.next=heroNode;
        }
    }
    //修改节点的信息,no不能更改
    public void update(HeroNode newHeroNode) {
        if(head.next==null) {
            System.out.println("LinkedList为空");
            return;
        }
        HeroNode temp = head;
        boolean flag = false;
        while(true) {
            if(temp.next==null)//已经遍历完链表
                break;
            if(temp.no==newHeroNode.no)
            {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag == true) {
            temp.name=newHeroNode.name;
            temp.nickName=newHeroNode.nickName;
        }
        else {
            System.out.printf("没有找到编号等于%d的节点",newHeroNode.no);
        }

    }
    public void delete(HeroNode heroNode) {
        if(head.next==null) {
            System.out.println("该链表为空,没法删除");
            return;
        }
        HeroNode temp = head;
        boolean flag = false;
        while(true) {
            if(temp.next==null)
                break;
            if(temp.next.no==heroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag == true) {
            temp.next=heroNode.next;
        }
        else {
            System.out.printf("要删除的no为%d的节点不存在",heroNode.no);
        }
    }
    //显示链表(遍历)
    public void list() {
        //先判断链表是否为空
        if(head.next==null) {
            return;
        }
        //由于头节点不能动,所以须要一个辅助变量
        HeroNode temp = head.next;
        while(true) {
            if(temp==null) {
                break;
            }
            System.out.println(temp.toString());
            temp = temp.next;//后移
        }
    }
}
//定义一个HeroNode,每一个HeroNode表明一个结点
class HeroNode {
    public int no;
    public String name;
    public String nickName;
    public HeroNode next;//指向下一个结点

    public HeroNode(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }
    @Override
    public String toString() {
        return "HeroNode [no=" + no + ", name=" + name + ", nickName=" + nickName + "]";
    }

}
相关文章
相关标签/搜索