数据结构与算法(双向链表)

//链结点的封装类
class Link2 {

    public int age;
    public Link2 next;  //指向下一个链结点
    public Link2 previous;  //指向前一个链结点

    //构造方法
    public Link2(int age){
        this.age = age;
    }

    //打印该链结点的信息
    public void displayLink(){
        System.out.println("age:"+age);
    }
}
//双向链表的封装类
public class DoublelyLinkList {

    public static void main(String[] args) {
        DoublelyLinkList doublelyLinkList = new DoublelyLinkList();
        doublelyLinkList.insertFirst(new Link2(1));
        doublelyLinkList.insertFirst(new Link2(2));
        doublelyLinkList.insertFirst(new Link2(3));
    }

    private Link2 first;  //指向链表中的第一个链结点
    private Link2 last;   //指向链表中的最后一个链结点

    public DoublelyLinkList(){
        first = null;
        last = null;
    }

    //插入到链表的前端
    public void insertFirst(Link2 link){
        /**
         * link赋值给last以及first,则通过last或first其中的一个以及前后结点的指针域都可以改变
         * link所指的地址内存的值。
         * 当首次插入的时候,first与last都指向link1
         * 当插入第二个的时候,将link2到first前结点指针域中
         */
        if(isEmpty()){  //如果为空链表,则插入的第一个链结点既是表头也是表尾
            last = link;
        }else{  //如果不是空链表,则将链表的first指针指向该链结点
            first.previous = link;
        }
        link.next = first;
        /**
         * 这一步改变了first变量的指向的地址,与last不同,所以last不会改变,但如果last中的previous或是next
         *指向的地址与link的地址相同,则会发生相应的改变
         */
        first = link;
    }

    //插入到链表的末端
    public void insertLast(Link2 link){
        if(isEmpty()){  //如果为空链表,则插入的第一个链结点既是表头也是表尾
            first = link;
        }else{
            last.next = link;
            link.previous = last;
        }
        last = link;
    }

    //删除第一个链结点,返回删除的链结点引用
    public Link2 deleteFirst() throws Exception{
        if(isEmpty()){
            throw new Exception("链表为空!不能进行删除操作");
        }
        Link2 temp = first;
        if(first.next == null){
            last = null;  //如果只有一个链结点,则删除后会影响到last指针
        }else{  //如果至少有两个链结点,则将第二个链结点的previous设为null
            first.next.previous = null;
        }
        first = first.next;
        return temp;
    }

    //删除最后一个链结点,返回删除的链结点引用
    public Link2 deleteLast() throws Exception{
        if(isEmpty()){
            throw new Exception("链表为空!不能进行删除操作");
        }
        Link2 temp = last;
        if(last.previous == null){
            first = null;  //如果只有一个链结点,则删除后会影响到first指针
        }else{  //如果至少有两个链结点,则将倒数第二个链结点的next设为null
            last.previous.next = null;
        }
        last = last.previous;
        return temp;
    }

    //查找属性为指定值的链结点
    public Link2 find(int key){
        Link2 cur = first;
        while(cur != null &&cur.age != key ){
            if(cur.next == null){
                return null;  //当前链结点不是要找的目标且已到达表尾
            }
            cur = cur.next;
        }

        return cur;
    }

    //在指定链结点之后插入,操作成功返回true,操作失败返回false
    public boolean insertAfter2(int age,Link2 link){
        Link2 target = find(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;
                //必须执行完上面两步,才能执行下面这两步
                target.next = link;
                link.previous =target;
            }
        }
        return flag;
    }

    //打印出所有的链表元素
    public void displayList(){
        Link2 cur = first;
        while(cur != null){  //循环打印每个链结点
            cur.displayLink();
            cur = cur.next;
        }
    }

    //判空
    public boolean isEmpty(){
        return (first == null);
    }

}

在首位插入元素的内存结构:
插入
在尾部插入元素的内存结构:
尾部插入
解释InsertAfter方法中第104行上下语句的位置为什么不能互换。
假设位置互换:

 //在指定链结点之后插入,操作成功返回true,操作失败返回false
    public boolean insertAfter2(int age,Link2 link){
        Link2 target = find(age);
        boolean flag = true;
        if(target == null){  //没找到插入的参照链结点
            flag = false;
        }else{  //找到了插入的参照链结点
            if(target.next == null){ //参照链结点为表尾
                insertLast(link);
            }else { //该链表至少有两个链结点
            	//假设语句的执行顺序变动
				target.next = link;
                link.previous =target;
                
                target.next.previous= link;
                link.next =target.next;
            }
        }
        return flag;
    }

第一步

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值