数据结构实现之单向循环链表 发表于 2018-11-27 | 分类于 Algorithm , CircleLinkedList | | 阅读次数: 数据结构实现之单向循环链表123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298/** * 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);*/ }} 输出结果: 12345678910111213141516171819205 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5第2个结点的数据是:2删除第3个结点成功5 -> 2 -> 1 -> 5 -> 3 -> 55 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5删除头结点成功2 -> 4 -> 1 -> 5 -> 3 -> 55 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5第5个结点的数据是:5删除第6个结点成功5 -> 2 -> 4 -> 1 -> 5 -> 55 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5第4个结点的数据是:15 -> 2 -> 4 -> 1 -> 5 -> 3 -> 5共删除了3个结点2 -> 4 -> 1 -> 3