数据结构--双向链表 双端链表

双端链表

 对于单项链表,我们如果想在尾部添加一个节点,那么必须从头部一直遍历到尾部,找到尾节点,然后在尾节点后面插入一个节点。这样操作很麻烦,如果我们在设计链表的时候多个对尾节点的引用,那么会简单很多。

1、什么时双端链表:

链表中保持这对最后一个连点引用的链表

 

2、从头部插入

要对链表进行判断,如果为空则设置尾节点为新添加的节点

 

3、从尾部进行插入

如果链表为空,则直接设置头节点为新添加的节点,否则设置尾节点的后一个节点为新添加的节点

 

4、从头部删除

判断节点是否有下个节点,如果没有则设置节点为null

/**
 * @Auther: liuhaidong
 * Data: 2019/10/11 0011、12:07
 * Description:
 * @version: 1.0
 */
public class DoublePointLinkedList {
    private Node head;
    //头节点
    private Node tail;
    //尾节点
    private int size;
    //节点的个数
    public DoublePointLinkedList() {
        size = 0;
        head = null;
        tail = null;
    }

    //表头新增节点
    public void addHead(int data){
        Node node = new Node(data);
        if (size == 0) {
            //如果链表为空,那么头节点和尾节点都是该新增节点
            head = node;
            tail = node;
            size++;
        } else {
            node.next = head;
            head = node;
            size++;
        }
    }

    //链表尾新增节点
    public void addTail(int data) {
        Node node = new Node(data);
        if (size == 0) {
            //如果链表为空,那么头节点和尾节点都是该新增节点
            head = node;
            tail = node;
            size++;
        } else {
            tail.next = node;
            tail = node;
            size++;
        }
    }

    //删除头部节点,成功返回true,失败返回false
    public boolean deleteHead() {
        if (size == 0) {
            //当前链表节点数为0
            return false;
        }
        if (head.next == null) {
            //当前链表节点数为1
            head = null;
            tail = null;
        } else {
            head = head.next;
        }
        size--;
        return true;
    }
    /**
     * @Author liuhaidong
     * @Description 显示出所有的节点信息(已测试)
     * @param
     * @Date 10:55 2019/10/11 0011
     */
    public void displayNode(){
        if(size > 0){
            Node node = head;
            int tempSize = size;
            if(tempSize == 1){
                //当前链表只有一个节点
                System.out.println("["+node.data+"]");
                return;
            }
            while(tempSize>0){
                if(node.equals(head)){
                    System.out.print("["+node.data+"->");
                }else if(node.next == null){
                    System.out.print(node.data+"]");
                }else {
                    System.out.print(node.data + "->");
                }
                node = node.next;
                tempSize--;
            }
        }
    }
    /**
     * @Author liuhaidong
     * @Description 判断链表是否为空(已测试)
     * @param
     * @Date 10:27 2019/10/11 0011
     */
    public boolean isEmpty(){
        return (size == 0);
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}

用双端链表实现队列

/**
 * @Auther: liuhaidong
 * Data: 2019/10/11 0011、12:31
 * Description:
 * @version: 1.0
 */
public class MyQueue {
    private DoublePointLinkedList dp;
    /** Initialize your data structure here. */
    public MyQueue() {
        dp = new DoublePointLinkedList();
    }

    /** Push element x to the back of queue. */
    public void push(int data) {
        dp.addTail(data);
        dp.setSize(dp.getSize()+1);
    }

    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        dp.deleteHead();
        //队尾元素
        dp.setSize(dp.getSize()-1);
        return dp.findNde(dp.getSize()).data;
    }

    /** Get the front element. */
    public int peek() {
        return dp.findNde(dp.getSize()).data;
    }

    /** Returns whether the queue is empty. */
    public boolean empty() {

        return dp.isEmpty();
    }
}

双向链表

我们知道单向链表只能从一个方向遍历,那么双向链表它可以从两个方向遍历。

/**
 * @Auther: liuhaidong
 * Data: 2019/10/11 0011、21:12
 * Description:
 * @version: 1.0
 */
public class TwoWayLinkedList {
    private NodeTwo head;
    //表示链表头
    private NodeTwo tail;
    //表示链表尾
    private int size;
    // 表示链表的节点个数
    public TwoWayLinkedList() {
        size = 0;
        head = null;
        tail = null;
    }

    //在链表头增加节点
    public void addHead(int value) {
        NodeTwo newNode = new NodeTwo(value);
        if (size == 0) {
            head = newNode;
            tail = newNode;
            size++;
        } else {
            head.prev = newNode;//把新的结点给原来头的前面
            newNode.next = head;//旧的头结点为新的后面
            head = newNode;//新的为新的结点
            size++;
        }
    }

    //在链表尾增加节点
    public void addTail(int value){
        NodeTwo newNode = new NodeTwo(value);
        if (size == 0) {
            head = newNode;
            tail = newNode;
            size++;
        } else {
            newNode.prev = tail;//原来的尾结点为新加的前面结点
            tail.next = newNode;//新的结点为尾结点的下一个
            tail = newNode;//新的结点为尾结点
            size++;
        }
    }

    //删除表头 并且返回
    public NodeTwo deleteHead(){
        NodeTwo tmp = head;
        if(size != 0){
            head = head.next;
            head.prev = null;
            size--;
        }
        return tmp;
    }
    //删除链表尾
    public NodeTwo deleteTail(){
        NodeTwo temp = tail;
        if(size != 0){
            tail = tail.prev;
            tail.next = null;
            size--;
        }
        return temp;
    }

    //获得链表的节点个数
    public int getSize() {
        return size;
    }

    //判断链表是否为空
    public boolean isEmpty() {
        return (size == 0);
    }
    /**
     * @Author liuhaidong
     * @Description 显示出所有的节点信息(已测试)
     * @param
     * @Date 10:55 2019/10/11 0011
     */
    public void displayNode(){
        if(size > 0){
            NodeTwo node = head;
            int tempSize = size;
            if(tempSize == 1){
                //当前链表只有一个节点
                System.out.println("["+node.data+"]");
                return;
            }
            while(tempSize>0){
                if(node.equals(head)){
                    System.out.print("["+node.data+"->");
                }else if(node.next == null){
                    System.out.print(node.data+"]");
                }else {
                    System.out.print(node.data + "->");
                }
                node = node.next;
                tempSize--;
            }
        }
    }
}
/**
 * @Auther: liuhaidong
 * Data: 2019/10/11 0011、21:13
 * Description:
 * @version: 1.0
 */
public class NodeTwo {
    public int data;
    public NodeTwo next;
    public NodeTwo prev;
    public NodeTwo(int data) {
        this.data = data;
    }
}

全部评论

相关推荐

点赞 收藏 评论
分享
正在热议
# 牛客帮帮团来啦!有问必答 #
1151650次浏览 17149人参与
# 通信和硬件还有转码的必要吗 #
11203次浏览 101人参与
# OPPO开奖 #
19202次浏览 267人参与
# 和牛牛一起刷题打卡 #
18978次浏览 1635人参与
# 实习与准备秋招该如何平衡 #
203386次浏览 3627人参与
# 大厂无回复,继续等待还是奔赴小厂 #
4972次浏览 30人参与
# 不去互联网可以去金融科技 #
20388次浏览 255人参与
# 通信硬件薪资爆料 #
265915次浏览 2484人参与
# 国企是理工四大天坑的最好选择吗 #
2223次浏览 34人参与
# 互联网公司评价 #
97688次浏览 1280人参与
# 简历无回复,你会继续海投还是优化再投? #
25037次浏览 354人参与
# 0offer是寒冬太冷还是我太菜 #
454868次浏览 5124人参与
# 国企和大厂硬件兄弟怎么选? #
53903次浏览 1012人参与
# 参加过提前批的机械人,你们还参加秋招么 #
14644次浏览 349人参与
# 硬件人的简历怎么写 #
82286次浏览 852人参与
# 面试被问第一学历差时该怎么回答 #
19398次浏览 213人参与
# 你见过最离谱的招聘要求是什么? #
28097次浏览 248人参与
# 学历对求职的影响 #
161239次浏览 1804人参与
# 你收到了团子的OC了吗 #
538722次浏览 6386人参与
# 你已经投递多少份简历了 #
344226次浏览 4963人参与
# 实习生应该准时下班吗 #
96977次浏览 722人参与
# 听劝,我这个简历该怎么改? #
63524次浏览 622人参与
牛客网
牛客企业服务