数据结构(4)-线性表(循环链表)

概念:将单链表终端节点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单循环链表,简称循环链表;
循环链表和单链表的区别:尾结点的指针不指向null,而是指向head头结点。

/*
 * 循环链表
 * 将单链表终端节点的指针由空指针改为指向头结点,
 * 就使整个单链表形成一个环,这种首尾相接的单链表称为单循环链表,简称循环链表
 */
public class MyCircularLinkedList {

    public static void main(String[] args) {
        CircularLinkedList<String> list2 = new CircularLinkedList<String>();
        list2.addHead("aaa");
        list2.add("bbb");
        list2.addByIndex(2, "ccc");
        System.out.println(list2.getElement(5));
        System.out.println(list2.toString());
        System.out.println(list2.length());
        System.out.println(list2.setElement(2, "ddd"));
        System.out.println(list2.toString());
        System.out.println(list2.remove(1));
        System.out.println(list2.toString());
        System.out.println(list2.removeAll());
        System.out.println(list2.toString());

    }

}

class CircularNode<T> {
    private T data;// 将循环链表设置为私有的,外界只能通过get和set进行访问
    private CircularNode next;

    // 构造方法
    CircularNode(T data, CircularNode next) {
        this.data = data;
        this.next = next;
    }

    // 调用重载的构造方法
    CircularNode(T data) {
        this(data, null);
    }

    CircularNode() {
        this(null, null);
    }

    // 提供get和set方法
    public T getData() {
        return this.data;
    }

    public CircularNode getNext() {
        return this.next;
    }

    public void setData(T data) {
        this.data = data;
    }

    public void setNext(CircularNode next) {
        this.next = next;
    }

    // 重写toString方法
    public String toString() {
        return getData().toString();
    }
}

class CircularLinkedList<T> {
    public CircularNode<T> head, tail;// 头和尾

    CircularLinkedList() {
        this(null);// 调用重载的构造方法
    }

    // 建表 如果参数为空则建空表;若参数不为空,则建一张有头有尾的结点,尾结点的指针指向头结点
    CircularLinkedList(T data) {
        if (data == null) {
            head = new CircularNode<T>(data, null);// 创建头结点,数据为data 指针为空
            tail = head;// 尾结点和头结点相同
            tail.setNext(head);// 尾结点的指针域指向头结点,使首尾形成环
        } else {
            head = new CircularNode<T>();
            tail = new CircularNode<T>(data, head);
            head.setNext(tail);// 等价于 head.next = tail;
        }
    }

    // 清空链表 头=尾 this=null
    public void clear() {
        removeAll();
        head.setNext(tail);
        tail.setNext(head);
        head = tail;
    }

    // 删除循环表中所有的数据元素
    public boolean removeAll() {
        // 将指针都释放 便于垃圾回收
        if (isEmpty())
            return false;
        CircularNode<T> tempNext = head.getNext();
        while (tempNext != head) {
            tempNext = tempNext.getNext();
            head.setNext(tempNext);

        }
        return true;

    }

    // 如果头=尾 返回true;否则返回false;
    public boolean isEmpty() {
        return tail == head;
    }

    // 获取链表当前元素的个数
    public int length() {
        int len = 0;
        CircularNode<T> temp = head;
        while (temp.getNext() != head) {
            len++;
            temp = temp.getNext();
        }
        return len;
    }

    // 获取index处的数据元素
    public T getElement(int index) {
        if (index < 0)
            return null;
        CircularNode<T> temp = head;
        int j = 0;
        while (j < index && temp.getNext() != head) {
            j++;
            temp = temp.getNext();
        }
        // 如果 index大于链表的长度 则返回最后一个元素的data
        return temp.getData();
    }

    // 将参数链表添加到当前链表的后面
    public boolean add(CircularLinkedList<T> list) {
        tail.setNext(list.head.getNext());
        list.tail.setNext(head);
        list.head.setNext(null);
        list.head = null;
        return true;
    }

    // 尾添
    public boolean add(T element) {
        if (element == null)
            return false;
        if (isEmpty()) {
            noElement(element);
        } else {
            CircularNode<T> temp = new CircularNode<T>(element, head);// 创建一个结点
            tail.setNext(temp);// 指向头结点head
            tail = temp;
        }
        return true;

    }

    // 若循环表中没有元素
    public void noElement(T element) {
        CircularNode<T> temp = new CircularNode<T>(element, head);
        head.setNext(temp);
        tail = temp;
    }

    // 头添
    public boolean addHead(T element) {
        if (element == null)
            return false;
        if (isEmpty()) {
            noElement(element);
        } else {
            CircularNode<T> temp = new CircularNode<T>(element, head.getNext());// 指针指向指定添加元素的下一个元素
            head.setNext(temp);
        }
        return true;
    }

    // 任意位置添加
    public boolean addByIndex(int index, T element) {
        if (element == null)
            return false;
        if (index <= 0)
            addHead(element);
        else if (index >= length()) {
            add(element);
        } else if (index > 0 && index < length()) {
            int j = 0;
            CircularNode<T> temp = head;
            CircularNode<T> tempNext = temp.getNext();
            while (j < index && tempNext != head) {
                j++;
                temp = tempNext;
                tempNext = tempNext.getNext();
            }
            CircularNode<T> node = new CircularNode<T>(element, tempNext);
            temp.setNext(node);
        }
        return true;
    }

    // 删除头元素
    public T removeHead() {
        if (isEmpty())
            return null;
        CircularNode<T> temp = head.getNext();
        head.setNext(temp.getNext());
        return temp.getData();
    }

    // 删除任意位置的元素
    public T remove(int index) {
        if (isEmpty())
            return null;
        T element = null;
        if (index <= 0)
            removeHead();
        if (index > length())
            index = length();
        if (index > 0) {
            int j = 1;
            CircularNode<T> temp = head;
            CircularNode<T> tempNext = head.getNext();
            while (j < index && tempNext != head) {
                temp = tempNext;
                tempNext = tempNext.getNext();
                j++;
            }
            element = tempNext.getData();
            temp.setNext(tempNext.getNext());
        }
        return element;
    }

    // 删除表中的第一条element数据
    public T remove(T element) {
        T data = null;
        if (isEmpty())
            return null;
        if (element == null)
            return null;
        CircularNode<T> temp = head;
        CircularNode<T> tempNext = head.getNext();
        while (!(tempNext.getData().equals(element))
                && tempNext.getNext() != head) {
            temp = tempNext;
            tempNext = tempNext.getNext();
        }
        data = tempNext.getData();
        temp.setNext(tempNext.getNext());
        return data;
    }

    // 修改任意位置上的元素,并将其原值返回
    public T setElement(int index, T element) {

        if (isEmpty())
            return null;
        if (element == null)
            return null;
        if (index <= 0)// 若索引值小于等于0 则 修改第一个位置
            index = 1;
        if (index > length())// 若索引值大于 index 修改最后一个元素
            index = length();
        CircularNode<T> temp = head.getNext();
        T data = null;
        int j = 1;
        while (j < index) {
            j++;
            temp = temp.getNext();
        }
        data = temp.getData();
        temp.setData(element);
        return data;
    }

    // 重写父类toString方法
    @Override
    public String toString() {
        if (isEmpty())
            return "[ ]";
        StringBuffer sb = new StringBuffer();
        sb.append("[ ");
        int L = length();
        for (int i = 1; i <= L; i++) {
            sb.append(getElement(i) + " ");
        }
        sb.append("]");
        return sb.toString();
    }
}

本文参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值