线性表之双向循环链表

一、循环链表

将单链表的终端结点的指针端由空指针改为指向头结点,就使整个单链表形成了一个环,这种头尾相连的单链表称为单循环链表。

这里写图片描述

单循环链表和单链表的主要差异就在于循环的判断条件上,原来是判断p->next是否为空,现在是判断p->next是否为头结点。除此之外,还有多重链的循环链表——将表中结点链在多个环上。

判断空链表的条件是
head==head->next;
rear==rear->next;

用尾指针end表示的单循环链表对开始结点a1和终端结点an查找时间都是O(1)。而表的操作常常是在表的首尾位置上进行,因此,实用中多采用尾指针表示单循环链表。带尾指针的单循环链表可见下图。
这里写图片描述
注意:判断空链表的条件为rear==rear->next;

二、双向链表

双向链表的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。

这里写图片描述

双向链表插入操作的顺序很重要,向双向链表中插入一个结点:

这里写图片描述

三、java实现双向循环链表

public class Node {
    Object data;
    Node prior, next;

    public Node() {
        this(null);
    }

    public Node(Object data) {
        this.data = data;
        this.prior = null;
        this.next = null;
    }

    public void show() {
        System.out.println("data=" + data);
    }
}
public class DoubleList {
    Node head;// 头结点
    int size;// 链表大小

    public DoubleList() {
        head = new Node();
        head.prior = head;
        head.next = head;
        size = 0;
    }

    public DoubleList(Object[] datas) {
        int n = datas.length;
        head = new Node();
        Node p = head;
        Node p2 = null;
        for (int i = 0; i < n; i++) {
            p2 = new Node(datas[i]);
            p.next = p2;
            p2.prior = p;
            p = p.next;
        }
        p2.next = head;
        head.prior = p2;
        size = n;
    }

    public void add(Object o) {
        Node p, p2;
        if (size == 0)
            p = head;
        else {
            p = getp(size + 1);
        }
        p2 = new Node(o);
        p.next = p2;
        p2.prior = p;
        p2.next = head;
        head.prior = p2;
        size++;
    }

    public void insert(int i, Object o) {
        if (i > size)
            System.out.println("超出链表大小");

        Node p = getp(i);
        Node p2 = new Node(o);
        p2.next = p.next;
        p2.prior = p;
        p.next = p2;
        size++;
    }

    public Node getp(int i) {
        Node p = head;
        if (i > 0 && i <= size + 1) {
            for (int j = 1; j < i; j++) {
                p = p.next;
            }
        }
        return p;
    }

    public Object get(int i) {
        Node p = getp(i);
        return p.next.data;
    }

    public void remove(int i) {
        if (i > 0 && i <= size) {
            Node p = getp(i);
            Node p2 = p.next.next;
            p.next = p2;
            p2.prior = p;
            size--;
        }
    }

    public void set(int i, Object o) {
        Node p = getp(i);
        p.next.data = o;
    }

    public boolean isEmpty() {
        if (size == 0)
            return true;
        else
            return false;
    }

    public int indexof(Object o) {
        Node p = head.next;
        int i = 1;
        while (!p.data.equals(o)) {
            p = p.next;
            i++;
        }
        if (i <= size)
            return i;
        else
            return -1;
    }

    public void showall() {
        Node p = head.next;
        while (p.next != head) {
            p.show();
            p = p.next;
        }
        p.show();
    }

    public int size() {
        return size;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值