链表的概念及功能实现

一、链表之单向链表

前面我们使用顺序储存结构实现的顺序表,虽然查询的时候很快,但在进行元素的增加或者删除的时候:比较麻烦,需要你去移动大量的元素把数据删除或者增加。

链表里的数据是以结点方式来表示的,每一个结点的组成是由:数据+指针来组成的。

一个结点的结构是这样的:

单向链表 :

  • 单链表是一种链式储存结构,在物理储存单元不连续,非顺序
  • 由多个结点组成的,每一个结点都是有一个数据域+指针域组成,数据域是用来存储数据元素的,指针用来指向后面的节点。
  • 链表分成带头结点的链表跟不带头结点的链表。
  • 单链表的头节点里不储存数据,它的指针指向真正存储有数据的第一个链表节点。

带头结点的单链表:

 该链表储存地址:

单链表的具体实现,首先需要定义一个类表示每个结点的信息(假设每个结点都是课程的信息):

class CourseNode{
    public int id;
    public String courseName;
    public CourseNode next;

    public CourseNode(int id, String courseName) {
        this.id = id;
        this.courseName = courseName;
    }

    @Override
    public String toString() {
        return "CourseNode{" +
                "id=" + id +
                ", courseName='" + courseName + '\'' +
                ", next=" + next +
                '}';
    }
}

 然后定义单链表类:

class CourseLinke{
    //初始化头节点
   public CourseNode head = new CourseNode(0,"");
   //链表有效元素个数
    private int length=0;
}

添加课程的方法:

public void addCourse(CourseNode node){
        //辅助的指针
        CourseNode cur = head;
        //遍历链表,找到最后一个节点
        while (true){
            if(cur.next==null){
                break;
            }
            cur=cur.next;
        }
        cur.next=node;
        length++;
    }

遍历课程的方法:

public void showCourse(){
        //定义辅助的指针
        CourseNode cur = head;
        if(cur.next==null){
            System.out.println("链表为空,不能输出");
            return;
        }
        while (true){
            if(cur.next==null){
                System.out.println("课程输出完成");
                return;
            }
            System.out.println(cur.next);
            cur=cur.next;
        }
    }

 删除课程的方法:

public void delCourse(int id){
        //定义辅助的指针
        CourseNode cur = head;
        if(cur.next == null){
            return;
        }
        //记录是否找到课程
        boolean flag = false;
        while (cur.next!=null){
            if(cur.next.id==id){
                flag=true;
                break;
            }
            //一直遍历
            cur=cur.next;
        }
        if(flag){
            //删除节点
            cur.next=cur.next.next;
            length--;
        }else {
            System.out.printf("要删除的节点%d没有找到",id);
        }
    }

修改课程的方法:

public void update(CourseNode node){
        CourseNode cur = head;
        boolean flag = false;
        while (cur.next!=null){
            if(cur.next.id==node.id){
                flag=true;
                break;
            }
            cur = cur.next;
        }
        if(flag){
            cur.next.id=node.id;
            cur.next.courseName=node.courseName;
        }else {
            System.out.println("没有找到要修改的课程");
        }
    }

接下来我们要实现查找倒数第K个课程,首先我们要先得到链表的长度:

public int getLength(){
        return length;
    }

查找倒数第K个课程:

//1、求解链表的长度   2、遍历到链表长度-K+1
    public CourseNode getLastCourse(int k){
        CourseNode cur = head;
        if(cur.next==null){
            System.out.println("链表为空");
            return null;
        }
        int length = getLength();
        if(k==0||k>length){
            throw new IllegalArgumentException("参数不合法");
        }
        for (int i=0;i<length-k+1;i++){
            cur=cur.next;
        }
        return cur;
    }

二、链表之双向链表

双向链表拥有两个指针域,一个指向后继的节点,另一个指向前驱结点。

链表的头结点的数据域是不存储数据的,所以,头结点的前驱指针域为null,它的后继指针域指的是第一个真正有数据存储的结点。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值