Java数据结构与算法笔记——有序链表和双向链表

有序列表

有序列表简介

在有序链表中,数据是按照关键值有序排列的。一般在大多数需要使用有序数组的场合也可以使用有序链表。
与有序数组相比,有序链表的优点:插入的速度快(因为元素不需要移动);链表可以有效的使用内存,而数组只能局限于一个固定的大小中。

插入:先判断大小,然后在正确的位置插入
删除:删除头结点
查找:需要遍历

java实现

package link;

public class OrderLinkedListTest {
    public static void main(String[] args) {
        OrderLinkedList order = new OrderLinkedList();
        order.insert(10);
        order.insert(8);
        order.insert(11);

        order.display();
        System.out.println(order.deleteHead());
        order.display();

    }
}

class OrderLinkedList{
    private Node head;
    private int size;

    //构造方法
    public OrderLinkedList(){
        head = null;
        size = 0;
    }

    //有序链表插入操作
    public void insert(int data){
        Node newNode = new Node(data);
        Node previous = null;
        Node current = head;
        while (current!=null && data>current.data){
            previous = current;
            current = current.next;
        }

        if(previous == null){
            //要插入的值比所有值都小
            head = newNode;
            head.next = current;
        }else{
            newNode.next = current;
            previous.next = newNode;
        }
        size ++;
    }

    //判断链表是不是空链表
    public boolean isEmpty(){
        return size==0;
    }

    //链表删除头结点,默认链表中是有节点的
    public int deleteHead(){
        int obj = head.data;
        head = head.next;
        size --;
        return obj;
    }

    //遍历输出所有node信息
    public void display(){
        if (size>0){
            //不是空的
            Node current = head;
            int tmpSize = size;
            if (tmpSize == 1){
                System.out.println("[" + head.data + "]");
                return; // 结束掉方法
            }
            while (tmpSize>0){
                if (current == head){
                    System.out.print("[" + current.data + "->");
                }else if(current.next == null){
                    //最后一个节点
                    System.out.print(current.data + "]");
                }else {
                    System.out.print(current.data + "->");
                }
                tmpSize --;
                current = current.next;
            }
            System.out.println();//输出一个换行符
        }else {
            //空列表
            System.out.println("[]");
        }
    }

    //定义一个私有类
    private class Node{
        private int data; //封装在节点里的数据
        private Node next; //指针,指向下一个节点

        //构造方法
        public Node(int data){
            this.data = data;

        }

        @Override
        public String toString() {
            return "Node [data=" + data + ", next=" + next + "]";
        }
    }
}

有序链表实现无序数组排序

冒泡排序,选择排序和插入排序方法时间复杂度都是O(N^2)

利用有序链表实现无序数组的排序肯定比以上三种方法效率高,但是需要开辟差不多两倍的空间,因为数组和链表必须在内存中同时存在。

package link;

import com.sun.org.apache.xpath.internal.objects.XString;

import java.util.Arrays;

public class OrderLinkedListTest {
    public static void main(String[] args) {
        // 生成随机数组
        int[] list = new int[10];
        for (int i=0;i<10;i++){
            list[i] = (int)(Math.random()*100);
        }
        System.out.println(Arrays.toString(list));

        //排序
        OrderLinkedList order = new OrderLinkedList();
        for(int i:list){
            order.insert(i);
        }
        while (!order.isEmpty()){
            System.out.print(Integer.toString(order.deleteHead()) + ' ');
        }


    }
}

class OrderLinkedList{
    private Node head;
    private int size;

    //构造方法
    public OrderLinkedList(){
        head = null;
        size = 0;
    }

    //有序链表插入操作
    public void insert(int data){
        Node newNode = new Node(data);
        Node previous = null;
        Node current = head;
        while (current!=null && data>current.data){
            previous = current;
            current = current.next;
        }

        if(previous == null){
            //要插入的值比所有值都小
            head = newNode;
            head.next = current;
        }else{
            newNode.next = current;
            previous.next = newNode;
        }
        size ++;
    }

    //判断链表是不是空链表
    public boolean isEmpty(){
        return size==0;
    }

    //链表删除头结点,默认链表中是有节点的
    public int deleteHead(){
        int obj = head.data;
        head = head.next;
        size --;
        return obj;
    }

    //遍历输出所有node信息
    public void display(){
        if (size>0){
            //不是空的
            Node current = head;
            int tmpSize = size;
            if (tmpSize == 1){
                System.out.println("[" + head.data + "]");
                return; // 结束掉方法
            }
            while (tmpSize>0){
                if (current == head){
                    System.out.print("[" + current.data + "->");
                }else if(current.next == null){
                    //最后一个节点
                    System.out.print(current.data + "]");
                }else {
                    System.out.print(current.data + "->");
                }
                tmpSize --;
                current = current.next;
            }
            System.out.println();//输出一个换行符
        }else {
            //空列表
            System.out.println("[]");
        }
    }

    //定义一个私有类
    private class Node{
        private int data; //封装在节点里的数据
        private Node next; //指针,指向下一个节点

        //构造方法
        public Node(int data){
            this.data = data;

        }

        @Override
        public String toString() {
            return "Node [data=" + data + ", next=" + next + "]";
        }
    }
}

双向链表

双向链表简介

双向链表可以从两个方向遍历。

在双端列表基础上,给每个节点添加了一个previous指针,指向前一个节点。

java实现双向链表

package link;

public class DoubleWayLinkedListTest {
    public static void main(String[] args) {
        DoubleWayLinkedList doubleWayLinkedList = new DoubleWayLinkedList();
        doubleWayLinkedList.addHead(1);
        doubleWayLinkedList.addHead(2);
        doubleWayLinkedList.addHead(3);
        doubleWayLinkedList.addTail(4);
        doubleWayLinkedList.addTail(5);
        doubleWayLinkedList.addTail(6);

        doubleWayLinkedList.display();

        System.out.println(doubleWayLinkedList.delete(1));
        doubleWayLinkedList.display();

        System.out.println(doubleWayLinkedList.deleteHead());
        doubleWayLinkedList.display();

        while (!doubleWayLinkedList.isEmpty()){
            System.out.println(doubleWayLinkedList.deleteTail());
        }

//        System.out.println(doubleLinkedList.deleteTail());
//        doubleLinkedList.display();
    }
}

class DoubleWayLinkedList{
    private int size; //链表的节点数
    private Node head; // head是头结点的指针,引入了一个新类型,node
    private Node tail; //指向尾结点的指针

    //构造方法
    public DoubleWayLinkedList(){
        size = 0;
        head = null;
        tail = null;
    }

    //向链表中添加节点(添加到头部)
    public Object addHead(Object data){
        Node newNode = new Node(data);
        if(size == 0){
            //空链表
            head = newNode;
            tail = newNode;
            newNode.prev = null;
            newNode.next = null;
        }else {
            //非空链表
            newNode.next = head;
            newNode.prev = null;
            head.prev = newNode;
            head = newNode;
        }
        size ++;
        return newNode;
    }

    //添加尾结点
    public Object addTail(Object data){
        Node newNode = new Node(data);
        if(size == 0) {
            //空链表
            head = newNode;
            tail = newNode;
            newNode.prev = null;
            newNode.next = null;
        }else {
            tail.next = newNode;
            newNode.prev = tail;
            newNode.next = null;
            tail = newNode;
        }
        size ++;
        return newNode;
    }

    //链表删除头结点
    public Object deleteHead(){
        Object obj = null;
        if(size == 0){
            //空链表
            return obj;
        }else if(size == 1){
            //链表中只有一个节点
            obj = head.data;
            head = null;
            tail = null;

        }else{
            obj = head.data;
            head =head.next;
            head.prev = null;
        }
        size --;
        return obj;
    }

    //删除尾部节点
    public Object deleteTail(){
        Object obj = null;
        if(size == 0){
            //空链表
            return obj;
        }else if(size == 1) {
            //链表中只有一个节点
            obj = tail.data;
            head = null;
            tail = null;
        }else {
            obj = tail.data;
            tail = tail.prev;
            tail.next = null;
        }
        size --;
        return obj;
    }

    //判断链表是不是空链表
    public boolean isEmpty(){
        return size==0;
    }

    //删除指定节点,删除成功返回true,失败返回false
    public boolean delete(Object value){
        if(isEmpty()){
            //空表
            return false;
        }

        //不是空表
        Node current = head;
        Node previous = head;//上一个变量
        while (!value.equals(current.data)){
            if (current.next == null){
                //已经扫描到了尾结点,且没找到数据
                return false;
            }else{
                //还没到尾结点
                previous = current;
                current = current.next;
            }
        }
        // 循环终止了,还会继续执行下面的语句,证明已经找到了要找的节点
        //删除找到的节点
        if(size == 1){
            head = null;
            tail = null;
        }else if(current == head){
            //头部节点
            head = head.next;
            head.prev = null;
        }else if(current == tail){
            //尾部节点
            previous.next = null;
            tail = previous;
        }else {
            previous.next = current.next;
            current.next.prev = previous;
        }
        size --;
        return true;
    }

    //遍历输出所有node信息
    public void display(){
        if (size>0){
            //不是空的
            Node current = head;
            int tmpSize = size;
            if (tmpSize == 1){
                System.out.println("[" + head.data + "]");
                return; // 结束掉方法
            }
            while (tmpSize>0){
                if (current == head){
                    System.out.print("[" + current.data + "->");
                }else if(current.next == null){
                    //最后一个节点
                    System.out.print(current.data + "]");
                }else {
                    System.out.print(current.data + "->");
                }
                tmpSize --;
                current = current.next;
            }
            System.out.println();//输出一个换行符
        }else {
            //空列表
            System.out.println("[]");
        }
    }

    //获取节点个数
    public int getSize(){
        return size;
    }

    //定义一个私有类
    private class Node{
        private Object data; //封装在节点里的数据
        private Node next; //指针,指向下一个节点
        private Node prev; //指针,指向上一个节点

        //构造方法
        public Node(Object data){
            this.data = data;
        }

        @Override
        public String toString() {
            return "Node [data=" + data + ", next=" + next + ", prev=" + prev + "]";
        }
    }

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值