【大厂算法系列】链表实战篇,基于链表编码实现课程信息管理系统

        }
        //辅助指针往下移动
        cur=cur.next;
    }
    cur.next=node;
    node.pre=cur;
    length++;

}

##### 双向链表实战删除与修改课程


* 双向链表删除节点思路分析


![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qgVWeZZZ-1679329108757)(picture/image-20221027161343270.png)]](https://img-blog.csdnimg.cn/e0148e9d399c4f7bb8edb7167dac84a7.png)


* 双向链表修改课程信息(同单链表类似)



//删除课程 根据课程的id
public void delCourse(int id){
//定义辅助变量
CourseNode2 cur=head.next;
if(curnull){
return;
}
//记录是否找到课程
boolean flag=false;
while (cur!=null){
if(cur.id
id){
flag=true;
break;
}
//一直遍历
cur=cur.next;
}
if(flag){
//删除节点
// data1 next->data3
cur.pre.next=cur.next;
//data3 pre->data1
if(cur.next!=null){
cur.next.pre=cur.pre;
}
length–;
}else {
System.out.printf(“要删除的节点%d没有找到”,id);
}
}


* **对单链表与双链表的相关操作进行时间复杂度分析**
* 删除节点时


	+ 单链表删除节点的时候,需要找到前驱节点,也就是通过遍历的方式得到。单链表的增删操作复杂度是O(n).
	+ 双向链表删除节点的时候,因为是双向的,直接通过pre就可以得到前驱节点,不用进行遍历,时间复杂度是O(1)
	+ 如果只知道要删除的双链表节点的序号,那一样要遍历,时间复杂度是O(n)
* 插入节点时


	+ 单链表与双链表的插入都要找到前驱节点,需要遍历找到的话时间复杂度就是O(n),给了前驱节点复杂度就是O(1)
* 查找节点时


	+ 查找时,时间复杂度均为O(n)
* 总体代码
* 单链表:



public class SingleLinkeDemo {
public static void main(String[] args) {
CourseLinke courseLinke = new CourseLinke();
CourseNode node1 = new CourseNode(1, “数据结构与算法”);
CourseNode node2 = new CourseNode(2, “数据结构与算法”);
CourseNode node3 = new CourseNode(3, “数据结构与算法”);
CourseNode node4 = new CourseNode(4, “数据结构与算法”);
CourseNode node5 = new CourseNode(5, “数据结构与算法”);
courseLinke.addCourse(node1);
courseLinke.addCourse(node2);
courseLinke.addCourse(node3);
courseLinke.addCourse(node4);
courseLinke.showCourse();
// System.out.println(" ==== “);
// courseLinke.delCourse(1);
// System.out.println(“删除课程id=1的课程后”);
// courseLinke.showCourse();
// System.out.println(“修改信息后”);
// courseLinke.update(node4);
// courseLinke.showCourse();
courseLinke.addNodeIndex(3,node5);
System.out.println(” ==== “);
System.out.println(“倒数第1门课程的信息是:”+courseLinke.getLastCourse(1));
courseLinke.showCourse();
}
}
//链表类 管理课程
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++;

}
//指定位置插入 index=2,即在第二个元素之前插入
public void addNodeIndex(int index,CourseNode node){
    //辅助指针
    CourseNode cur=head;
    //判断参数是否合法
    if(index>length || index<0) return;
    for(int i=1;i<index;i++){
        cur=cur.next;
    }
    System.out.println("当前cur"+cur);
    CourseNode temp=cur.next;
    cur.next=node;
    node.next=temp;
}
//修改课程信息
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("没有找到要修改的课程");
    }
}
//删除课程 根据课程的id
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 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;
    }
}
//获取倒数第K个节点 1.获取到链表长度 2.遍历链表直到(链表长度-K+1) return node
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("参数错误");
    }
    System.out.println("链表长度:"+length);
    for(int i=0;i<length-k+1;i++){
        cur=cur.next;
    }
    return cur;
}
//获取链表长度
public int getLength(){
    return length;
}

}
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 +
            '}';
}

}


**双链表**



public class DoubleLinkeDemo {
public static void main(String[] args) {
DoubleLinke doubleLinke = new DoubleLinke();
CourseNode2 node1 = new CourseNode2(1, “数据结构与算法课程1”);
CourseNode2 node2 = new CourseNode2(2, “数据结构与算法课程1”);
CourseNode2 node3 = new CourseNode2(3, “数据结构与算法课程1”);
CourseNode2 node4 = new CourseNode2(3, “数据结构与算法课程5”);
doubleLinke.addCourse(node1);
doubleLinke.addCourse(node2);
doubleLinke.addCourse(node3);
doubleLinke.delCourse(1);
doubleLinke.update(node4);
doubleLinke.showCourse();
}
}

//链表类 管理课程
class DoubleLinke{
//头节点 初始化
public CourseNode2 head=new CourseNode2(0,“”);
//链表有效元素个数
private int length=0;
//添加课程
public void addCourse(CourseNode2 node){
//辅助的指针
CourseNode2 cur=head;
//不断的遍历链表 找到最后一个节点
while (true){
//找到了
if(cur.next==null){
break;
}
//辅助指针往下移动
cur=cur.next;
}
cur.next=node;
node.pre=cur;
length++;

}
//修改课程信息
public void update(CourseNode2 node){
    CourseNode2 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("没有找到要修改的课程");
    }
}
//删除课程 根据课程的id
public void delCourse(int id){
    //定义辅助变量
    CourseNode2 cur=head.next;
    if(cur==null){
        return;
    }
    //记录是否找到课程
    boolean flag=false;
    while (cur!=null){
        if(cur.id==id){
            flag=true;
            break;
        }
        //一直遍历
        cur=cur.next;
    }
    if(flag){
        //删除节点
        // data1 next->data3
        cur.pre.next=cur.next;
        //data3 pre->data1
        if(cur.next!=null){
            cur.next.pre=cur.pre;
        }
        length--;
    }else {
        System.out.printf("要删除的节点%d没有找到",id);
    }
}
//遍历输出课程
public void showCourse(){
    //定义辅助的指针
    CourseNode2 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;
    }
}
//获取倒数第K个节点 1.获取到链表长度 2.遍历链表直到(链表长度-K) return node
public CourseNode2 getLastCourse(int k){
    CourseNode2 cur=head;
    if(cur.next==null){
        System.out.println("链表空 不可以返回");
        return null;
    }
    int length=getLength();
    for(int i=0;i<length-k;i++){
        cur=cur.next;
    }
    return cur;
}
//获取链表长度
public int getLength(){
    return length;
}

}

class CourseNode2{
public int id;
public String courseName;
public CourseNode2 next;
//前驱节点
public CourseNode2 pre;
public CourseNode2(int id,String courseName){
this.id=id;
this.courseName=courseName;
}
// 这两个方法都会尝试在它们的邻居上调用toString(),包括你开始时使用的Node。这是一个无限递归。
// 要避免这种情况,请不要在节点的toString()方法中包含相邻节点的字符串表示。
@Override
public String toString() {

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值