Java实现双向非循环链表和一些简单函数

双向链表和单链表的区别在于他多了一个pre域保存上一个节点的位置,这样可以在任意位置就能找到所有节点,比较方便
双向非循环链表的图解

完整代码

class Node2 {
    public int data;
    public Node2 next;
    public Node2 pre;
    public Node2(int data) {
        this.data = data;
        this.next = null;
        this.pre = null;
    }
}
public class MyDoubleList {
    public Node2 head;
    public Node2 feet;
    public MyDoubleList() {
        this.head = null;
        this.feet = null;
    }
    public void addFirst(int data) {
        Node2 node = new Node2(data);
        if(this.head==null) {
            this.feet = node;
            this.head = node;
            return;
        }
        node.next = this.head;
        this.head.pre = node;
        this.head = node;
    }
    public void addLast(int data) {
        Node2 node = new Node2(data);
        if(this.head==null) {
            this.feet = node;
            this.head = node;
            return;
        }
        feet.next = node;
        node.pre = feet;
        feet = node;
    }
    public void addIndex(int index,int data){//按指定位置插入
        Node2 node = new Node2(data);
        Node2 cur = this.head;
        if (index<0 || index>size()) {
            throw new RuntimeException("下标不合法");
        }
        if (index==0) {
            addFirst(data);
            return;
        }
        if (index==size()) {
            addLast(data);
            return;
        }
        for (int i = 0;i<index;i++) {
            cur = cur.next;
        }
        node.next = cur;
        node.pre = cur.pre;
        cur.pre = node;
        node.pre.next = node;
    }
    public void changeBefore(int key,int data) {//修改正数第key个元素
        Node2 prev = this.head;
        if (key<1 || key > size()) {
            throw new RuntimeException("key越界");
        }
        if(key==1) {
            this.head.data = data;
        }
        else {
            int cot = 1;
            while(cot!=key) {
                prev = prev.next;
                cot++;
            }
            prev.data = data;
            return;
        }
    }
    public void addOrder(int data) {//按找data域大小插入
        Node2 node = new Node2(data);
        if (this.head==null) {
            this.head = node;
            this.feet = node;
            return;
        }
        if (data<this.head.data) {
            node.next = this.head;
            this.head.pre = node;
            this.head = node;
            return;
        }else {
            Node2 prev = this.head;
            while(prev.next!=null) {
                prev = prev.next;
            }
            if (data>prev.data) {
                prev.next = node;
                node.pre = prev;
                return;
            }
            while(data<prev.data) {
                prev = prev.pre;
            }
            node.next = prev.next;
            node.pre = prev;
            prev.next = node;
            node.pre.next = node;
        }
    }
    public void displayForward() {//从前打印
        Node2 cur = this.head;
        while (cur!=null) {
            System.out.print(cur.data+" ");
            cur = cur.next;
        }
    }
    public void displayBackward() {
        Node2 cur = this.feet;
        while(cur!=null) {
            System.out.print(cur.data+" ");
            cur = cur.pre;
        }
    }
    public int size() {
        int cot = 1;
        Node2 count = this.head;
        while (count.next!=null) {
            count = count.next;
            cot++;
        }
        return cot;
    }
public void remove(int key){
    Node2 cur = this.head;
    while (cur != null) {
        if(cur.data == key) {
            //当前cur是不是头结点
            if(cur == this.head) {
                this.head = this.head.next;
                this.head.pre = null;
            }else {
                cur.pre.next = cur.next;
                if (cur.next!=null){
                    cur.next.pre = cur.pre;
                }
                else {
                    this.feet = cur.pre;
                }
            }
            return ;
        }else {
            cur = cur.next;
        }
    }
}
    public void removeAllKey(int key) {//删除所有key元素
        Node2 cur = this.head;
        while (cur != null) {
            if(cur.data == key) {
                //当前cur是不是头结点
                if(cur == this.head) {
                    this.head = this.head.next;
                    this.head.pre = null;
                }else {
                    cur.pre.next = cur.next;
                    if (cur.next!=null){
                        cur.next.pre = cur.pre;
                    }
                    else {
                        this.feet = cur.pre;
                    }
                }

            }
            cur = cur.next;
        }
    }
    public void clear() {//清空链表
        this.head = null;
        this.feet = null;
    }
}

以下是Java实现带头双向循环链表的完整源码,供参考: ``` public class DoublyCircularLinkedList<T> { private Node<T> head; // 头节点 // 节点类 private static class Node<T> { T data; Node<T> prev; Node<T> next; Node(T data) { this.data = data; this.prev = null; this.next = null; } } // 构造函数 public DoublyCircularLinkedList() { head = new Node<>(null); head.prev = head; head.next = head; } // 在链表末尾添加元素 public void add(T data) { Node<T> node = new Node<>(data); node.prev = head.prev; node.next = head; head.prev.next = node; head.prev = node; } // 在指定位置插入元素 public void insert(int index, T data) { Node<T> node = new Node<>(data); Node<T> p = head.next; int i = 0; while (p != head && i < index) { p = p.next; i++; } if (p == head || i > index) { throw new IndexOutOfBoundsException(); } node.prev = p.prev; node.next = p; p.prev.next = node; p.prev = node; } // 删除指定位置的元素 public void remove(int index) { Node<T> p = head.next; int i = 0; while (p != head && i < index) { p = p.next; i++; } if (p == head || i > index) { throw new IndexOutOfBoundsException(); } p.prev.next = p.next; p.next.prev = p.prev; p.prev = null; p.next = null; } // 获取指定位置的元素 public T get(int index) { Node<T> p = head.next; int i = 0; while (p != head && i < index) { p = p.next; i++; } if (p == head || i > index) { throw new IndexOutOfBoundsException(); } return p.data; } // 获取链表长度 public int size() { Node<T> p = head.next; int size = 0; while (p != head) { size++; p = p.next; } return size; } } ``` 该代码实现了带头双向循环链表数据结构,支持在链表末尾添加元素、在指定位置插入元素、删除指定位置的元素、获取指定位置的元素、获取链表长度等操作。在算法实现中,通过一个Node类来表示链表中的节点,包含数据域、前驱指针和后继指针。同时,链表的头节点也是一个Node对象,通过头节点来连接链表的首尾,形成双向循环链表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值