数据结构读书笔记---链表

一、概述

线性表是由成为元素的数据项组成的一种有限且有序的序列。链表结构图

二、顺序表在这里插入图片描述

在这里插入图片描述

三、单链表

//链结点的封装类
public class Link {
    
    public int age;
    public String name;
    public Link next;  //指向该链结点的下一个链结点
    
    //构造方法
    public Link(int age,String name){
        this.age = age;
        this.name = name;
    }
    
    //打印该链结点的信息
    public void displayLink(){
        System.out.println("name:"+name+",age:"+age);
    }
}

//链表的封装类
public class LinkList {
    
    private Link first;  //指向链表中的第一个链结点
    
    public LinkList(){
        first = null;
    }
    
    //插入到链表的前端
    public void insertFirst(Link link){
        link.next = first;
        first = link;
    }
    
    //删除第一个链结点,返回删除的链结点引用
    public Link deleteFirst() throws Exception{
        if(isEmpty()){
            throw new Exception("链表为空!不能进行删除操作");
        }
        Link temp = first;
        first = first.next;
        return temp;
    }
    
    //打印出所有的链表元素
    public void displayList(){
        Link cur = first;
        while(cur != null){  //循环打印每个链结点
            cur.displayLink();
            cur = cur.next;
        }
    }
    
    //删除属性为指定值的链结点
    public Link delete(int key){
        Link link = null;
        Link cur = first;
        Link next = first.next;
        Link previous = null;
        while(cur != null){
            if(cur.age == key){  //找到了要删除的链结点
                link = cur;
                //如果当前链结点的前驱为null,证明当其为链表的第一个链结点
                //删除该链结点后需要对first属性重新赋值
                if(previous == null){  
                    this.first = next;
                }else{
                //删除操作,即将前驱的next指针指向当前链结点的next
                //链表中将去当前链结点这一环
                    previous.next = next;
                }
                break;
            }else if(cur.next == null){  
            //当前链结点不是目标且下一个链结点为null,证明没有要删除的链结点
                break;
            }
            
            //当前链结点不是要删除的目标,则向后继续寻找
            next = next.next;
            cur = cur.next;
            previous = cur;
        }
        
        return link;
    }
    
    //查找属性为指定值的链结点
    public Link find(int key){
        Link link = null;
        Link cur = first;
        Link next = null;
        Link previous = null;
        while(cur != null){
            if(cur.age == key){
                link = cur;
                break;
            }else if(cur.next == null){ 
            //当前链结点不是要找的目标且下一个链结点为null,则证明没有找到目标
                break;
            }
            
            //当前链结点不是要找的目标且存在下一个链结点,则向后继续寻找
            next = next.next;
            cur = cur.next;
            previous = cur;
        }
        
        return link;
    }
    
    //判空
    public boolean isEmpty(){
        return (first == null);
    }
    
}

三、双链表

//链结点的封装类
public class Link {
    
    public int age;
    public String name;
    public Link next;  //指向下一个链结点
    public Link previous;  //指向前一个链结点
    
    //构造方法
    public Link(int age,String name){
        this.age = age;
        this.name = name;
    }
    
    //打印该链结点的信息
    public void displayLink(){
        System.out.println("name:"+name+",age:"+age);
    }
}

//双向链表的封装类
public class DoublelyLinkList {
    
    private Link first;  //指向链表中的第一个链结点
    private Link last;   //指向链表中的最后一个链结点
    
    public DoublelyLinkList(){
        first = null;
        last = null;
    }
    
    //插入到链表的前端
    public void insertFirst(Link link){
        if(isEmpty()){  //如果为空链表,则插入的第一个链结点既是表头也是表尾
            last = link;
        }else{  //如果不是空链表,则将链表的first指针指向该链结点
            first.previous = link;
        }
        link.next = first;
        first = link;
    }
    
    //插入到链表的末端
    public void insertLast(Link link){
        if(isEmpty()){  //如果为空链表,则插入的第一个链结点既是表头也是表尾
            first = link;
        }else{
            last.next = link;
            link.previous = last;
        }
        last = link;
    }
    
    //删除第一个链结点,返回删除的链结点引用
    public Link deleteFirst() throws Exception{
        if(isEmpty()){
            throw new Exception("链表为空!不能进行删除操作");
        }
        Link temp = first;
        if(first.next == null){
            last = null;  //如果只有一个链结点,则删除后会影响到last指针
        }else{  //如果至少有两个链结点,则将第二个链结点的previous设为null
            first.next.previous = null;
        }
        first = first.next;
        return temp;
    }
    
    //删除最后一个链结点,返回删除的链结点引用
    public Link deleteLast() throws Exception{
        if(isEmpty()){
            throw new Exception("链表为空!不能进行删除操作");
        }
        Link temp = last;
        if(last.previous == null){
            first = null;  //如果只有一个链结点,则删除后会影响到first指针
        }else{  //如果至少有两个链结点,则将倒数第二个链结点的next设为null
            last.previous.next = null;
        }
        last = last.previous;
        return temp;
    }
    
    //查找属性为指定值的链结点
    public Link find(int key){
        Link cur = first;
        while(cur != null && cur.age != key ){
            if(cur.next == null){
                return null;  //当前链结点不是要找的目标且已到达表尾
            }
            cur = cur.next;
        }
        
        return cur;
    }
    
    //在指定链结点之后插入,操作成功返回true,操作失败返回false
    public boolean insertAfter(Link link){
        Link target = find(link.age);
        boolean flag = true;
        if(target == null){  //没找到插入的参照链结点
            flag = false;
        }else{  //找到了插入的参照链结点
            if(target.next == null){ //参照链结点为表尾
                insertLast(link);
            }else { //该链表至少有两个链结点
                target.next.previous = link;
                link.next = target.next;
                //必须执行完上面两步,才能执行下面这两步
                //上面两步处理了link和它下一个链结点的关系
                //下面两步处理了link和它上一个链结点的关系
                target.next = link;
                link.previous = target;
            }
        }
            
        return flag;
    }
    
    //打印出所有的链表元素
    public void displayList(){
        Link cur = first;
        while(cur != null){  //循环打印每个链结点
            cur.displayLink();
            cur = cur.next;
        }
    }
    
    //判空
    public boolean isEmpty(){
        return (first == null);
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值