}
//辅助指针往下移动
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.idid){
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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!