Loading

数据结构实现之单向循环链表

date: 2018-11-27 10:29:37
updated: 2018-11-27 10:29:37

数据结构实现之单向循环链表

	/**
	 * Copyright (C), 2015-2018, XXX有限公司
	 * FileName: CircleLinkedList
	 * Author:   猫熊小才天
	 * Date:     2018/11/26 17:06
	 * Description: 单向循环链表
	 * History:
	 * <author>          <time>          <version>          <desc>
	 * 作者姓名           修改时间           版本号              描述
	 */
	package main.List;

	/**
	 * 〈一句话功能简述〉<br>
	 * 〈单向循环链表〉
	 * 在循环的时候不能使用如下方法:
	 * Node tmp = head;
	 * while(tmp.next != null){
	 *
	 * }
	 * 会出现死循环,换成
	 * for(int i = 1; i <= getSize(); ++i)
	 * @author 猫熊小才天
	 * @create 2018/11/26
	 * @since 1.0.0
	 */
	public class CircleLinkedList {

	private class Node {
		int data; // 结点中的数据
		Node next = null; // 下一个结点的地址信息

		public Node(int data) {
			this.data = data;
		}

		public Node() {
			super();
		}
	}

	private Node head = null; // 保存头结点
	private Node tail = null; // 保存尾节点
	private int size; // 保存已有的的结点数

	public CircleLinkedList() {
		super();
	}

	/**
	 * 头插法
	 * 
	 * @param data
	 */
	public void headAdd(int data) {
		// 如果链表为空
		if (isEmpty()) {
			head = new Node(data);
			head.next = head;
			tail = head;
		} else {
			Node newNode = new Node(data);
            // 让新结点指向head
			newNode.next = head;
            // 然后让新结点作为head
			head = newNode;
            // 将尾结点指向头结点
			tail.next = head;
		}
		++size;
	}

	/**
	 * 尾插法
	 * 
	 * @param data
	 */
	public void tailAdd(int data) {
		// 如果链表为空
		if (isEmpty()) {
			head = new Node(data);
			head.next = head;
			tail = head;
		}else {
		    Node newNode = new Node(data);
		    // 让尾结点指向新结点
		    tail.next = newNode;
		    // 让新结点指向头结点
		    newNode.next = head;
		    // 将新结点作为尾结点
		    tail = newNode;
        }
        ++size;
	}

    /**
     * 删除第index个结点
     * @param index
     * @return
     */
    public boolean deleteNodeByIndex(int index) {
        boolean res = false;
        if (isEmpty()) {
            System.out.println("单向循环链表为空");
            res = false;
        }
        /**
         * 如果输入的下标超过单向循环链表的范围
         */
        if (index < 1 || index > getSize()) {
            System.out.println("输入下标不在单向循环链表的范围中");
            res = false;
        }else if(index == 1){
            // 删除头结点
            Node tmp = new Node(head.next.data);
            // 让tmp等于head的下一个结点
            tmp.next = head.next.next;
            // 将tmp赋值给head,即相当于删除了原先的head
            head = tmp;
            // 尾结点指向新的头结点
            tail.next = head;
            System.out.println("删除头结点成功");
            res = true;
        }else if(index == getSize()){
            // 删除尾结点
            // 获取倒数第二个结点
            Node tmp = getDataByIndex(getSize() - 1);
            // 让倒数第二个结点指向head
            tmp.next = head;
            // tmp赋值到新的尾结点
            tail = tmp;
            System.out.println("删除尾结点成功");
            res = true;
        }else if(index > 1 && index < getSize()){
            // 删除的是中间任一结点
            // 获取第 index - 1 个结点
            Node prev = getDataByIndex(index - 1);
            // 需要删除的结点即第index-1个结点的next
            Node cur = prev.next;
            prev.next = cur.next;
            System.out.println("删除第" + index + "个结点成功");
            res = true;
        }
        --size;
        return res;
    }

    /**
     * 删除单向循环链表中数据为data的所有结点
     * @param data
     * @return
     */
    public boolean deleteNodeByData(int data) {
        if (isEmpty()) {
            System.out.println("单向循环链表为空");
            return false;
        }
        boolean res = false;
        int count = 0;
        // 先循环将头结点删除,直到头结点中的data≠data
        Node tmp = head;
        for(int i = 1; i <= getSize(); ++i){
            if(tmp.data == data){
                tmp = tmp.next;
                head = tmp;
                tail = head;
                ++count;
                --size; // 需要将size减少!!!
                res = true;
            }else {
                break;
            }
        }
        // 再循环将尾结点删除,直到尾结点中的data≠data
        Node tmp2 = tail;
        for(int i = 1; i <= getSize(); ++i){
            if(tmp.data == data){
                tmp = getDataByIndex(getSize() - 1);
                tmp.next = head;
                tail = tmp;
                ++count;
                --size;
                res = true;
            }else {
                break;
            }
        }

        Node preNode = head;
        Node curNode = head.next;
        for(int i = 1; i <= getSize(); ++i){
            if(curNode.data == data){
                preNode.next = curNode.next;
                ++count;
                --size;
                res = true;
            }
            preNode = curNode;
            curNode = curNode.next;
        }

        if(res == true){
            System.out.println("共删除了" + count + "个结点");
        }else {
            System.out.println("删除失败");
        }
        return res;
    }

    /**
     * 获取index位置下的Node数据
     * @param index
     */
    public Node getDataByIndex(int index){
        if (isEmpty()) {
            System.out.println("单向循环链表为空");
            return null;
        }else if(index < 1 || index > getSize()){
            System.out.println("输入下标不在单向循环链表的范围中");
            return null;
        }else {
            Node res = head;
            for(int i = 1; i <= getSize() && res.next != null; ++i){
                if(i == index){
                    System.out.println("第" + index + "个结点的数据是:" + res.data);
                    return res;
                }
                res = res.next;
            }
            return res;
        }
    }

	/**
	 * 判断链表是否为空
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		return size == 0;
	}

	/**
	 * 返回链表长度
	 * 
	 * @return
	 */
	public int getSize() {
		return size;
	}

	/**
	 * 清空线性表
	 */
	public void clear() {
		// 将头结点和尾结点设为空
		head = null;
		tail = null;
		size = 0;
	}

	/**
	 * 打印单向链表 如果传过来的参数head是list.reHead即为逆向输出
	 * 
	 * @param head
	 */
	public void printCircleLinkedList(Node head) {
		Node tmp = head;
		for(int i = 1; i <= getSize(); ++i){
            System.out.print(tmp.data);
            tmp = tmp.next;
            if (i != getSize()) {
                System.out.print(" -> ");
            }
        }
		System.out.println();
	}

    public static void main(String[] args) {
        CircleLinkedList list = new CircleLinkedList();
        list.tailAdd(5);
        list.tailAdd(2);
        list.tailAdd(4);
        list.tailAdd(1);
        list.tailAdd(5);
        list.tailAdd(3);
        list.tailAdd(5);
        list.printCircleLinkedList(list.head);

        /*list.deleteNodeByIndex(3);
        list.printCircleLinkedList(list.head);*/

        //list.getDataByIndex(6);

        /*list.deleteNodeByData(5);
        list.printCircleLinkedList(list.head);*/
    }
	}

输出结果:

	5 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5
	第2个结点的数据是:2
	删除第3个结点成功
	5 -> 2 -> 1 -> 5 -> 3 -> 5

	5 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5
	删除头结点成功
	2 -> 4 -> 1 -> 5 -> 3 -> 5

	5 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5
	第5个结点的数据是:5
	删除第6个结点成功
	5 -> 2 -> 4 -> 1 -> 5 -> 5

	5 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5
	第4个结点的数据是:1

	5 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5
	共删除了3个结点
	2 -> 4 -> 1 -> 3
posted @ 2020-10-20 17:25  猫熊小才天  阅读(120)  评论(0编辑  收藏  举报