数据结构与算法之循环链表 <三>
2017-03-11 11:57
567 查看
循环链表的介绍
在单向链表和双向链表中,都采用null作为链表的结束,然而,循环链表没有结束标志。
注意 与单向链表不同,循环链表没有next指针为null的点,循环链表在某些情况下非常有用。 比如在进程的循环调度中。
循环链表的创建
3.循环链表的插入
4.循环链表的删除
5.循环链表的其他操作
循环链表的基本操作就此结束
在单向链表和双向链表中,都采用null作为链表的结束,然而,循环链表没有结束标志。
注意 与单向链表不同,循环链表没有next指针为null的点,循环链表在某些情况下非常有用。 比如在进程的循环调度中。
循环链表的创建
public class Node<E> { // 节点对象 对象应该包含储蓄的数据和指向下一个节点对象 // 利用泛型 将储存的数据类型交给使用者来选择,大大提升灵活性 // 储存的数据 private E data; // 下一个节点 private Node<E> next; public E getData() { return data; } public void setData(E data) { this.data = data; } public Node<E> getNext() { return next; } public void setNext(Node<E> next) { this.next = next; } }
3.循环链表的插入
// 在链表表尾增加链表节点 public void add(E obj) { Node<E> node = new Node<>(); node.setData(obj); // 如果链表为空 则首尾节点都指向第一个节点 if (headNode == null) { headNode = node; endNode = node; //循环链表的尾节点指向头结点 endNode.setNext(headNode); } else { // 不为空 将尾节点指向新增节点 endNode.setNext(node); //新增节点指向头节点 node.setNext(headNode); // 尾节点后移 endNode = node; } } // 在指定中间位置增加节点 public void add(int index, E element) { Node<E> node = new Node<>(); node.setData(element); if (headNode == null) { throw new NullPointerException("空链表"); } // 判断位置是否超出界限 else if ((index < 0) || (index > this.size())) { throw new ArrayIndexOutOfBoundsException("超出范围"); } else { // 首节点插入 if (index == 0) { node.setNext(headNode); endNode.setNext(node); headNode = node; } // 尾节点插入 else if (index == this.size()) { endNode.setNext(node); node.setNext(headNode); endNode = node; } // 中间插入 else { Node<E> hnode = headNode; // 将首节点移动到插入节点的前一个节点 for (int i = 1; i <= index - 1; i++) { hnode = hnode.getNext(); } node.setNext(hnode.getNext()); hnode.setNext(node); } } }
4.循环链表的删除
// 移除此列表中指定位置上的元素 public void remove(int index) { if (headNode == null) { throw new NullPointerException("空链表"); } else if ((index < 0) || (index >= this.size())) { throw new ArrayIndexOutOfBoundsException("超出范围"); } else { // 保护头结点 Node<E> hnode = headNode; // 删除首节点 if (index == 0) { //更新首节点 headNode = headNode.getNext(); //更新尾节点 endNode.setNext(headNode); // System.out.println(index + "号:" + hnode.getData().toString() // + "移除成功"); } // 删除尾节点 else if (index == (this.size() - 1)) { while (hnode.getNext() != endNode) { hnode = hnode.getNext(); } hnode.setNext(headNode); // System.out.println(index + "号:" + endNode.getData() + " // 移除成功"); endNode = hnode; } // 删除中间节点 else { for (int i = 1; i < index; i++) { hnode = hnode.getNext(); } // E data = hnode.getNext().getData(); hnode.setNext(hnode.getNext().getNext()); // System.out.println(index + "号:" + data.toString() + " 移除成功"); } } }
5.循环链表的其他操作
// 返回此列表中指定位置上的元素。 public E get(int index) { if (headNode == null) { throw new NullPointerException("空链表"); } else { // 遍历不到尾节点 for (Node<E> node = headNode; node.getNext() != headNode; node = node.getNext()) { if (index == 0) { return node.getData(); } index--; } // 尾节点单独检测 为什么是0因为index多运行了一次 if (index == 0) { return endNode.getData(); } else throw new ArrayIndexOutOfBoundsException("超出范围"); } } // 返回此列表的元素数。 public int size() { //判断是否为空 if (headNode == null) { return 0; } else { Node<E> node = headNode; int count = 0; //循环链表没有节点next为空 while (node.getNext() != headNode) { node = node.getNext(); count++; } return count + 1; } } // 用指定的元素替代此列表中指定位置上的元素。 public E set(int index, E element) { // 删除指定位置的元素 this.remove(index); // 插入指定位置元素 this.add(index, element); return element; }
循环链表的基本操作就此结束
相关文章推荐
- 数据结构与算法之双向链表 <二>
- 数据结构与算法之单向链表 <一>
- 数据结构实例<三>(匹配链表所有元素删除后并返回新的链表)入门
- <六>java数据结构与算法 栈
- 数据结构学习笔记<三>数据结构算法2.2具体实现
- <七>java数据结构与算法 栈 实现单词逆序
- <二>java数据结构与算法 冒泡排序
- 数据结构与算法之图的邻接表与邻接矩阵<十二>
- <三>java数据结构与算法 选择排序
- 数据结构与算法之优先队列<九>
- 数据结构基础算法-循环链表
- 数据结构与算法之基础排序(冒泡/插入/选择)<十>
- linux 内核常用数据结构及算法——list(循环双向链表)
- 数据结构与算法(4)----->链表、二分搜索
- 数据结构与算法之散列(线性/平方/双平方探测法)<八>
- <四>java数据结构与算法 插入排序
- 算法与数据结构之三----循环链表
- 数据结构与算法(C语言)<绪论>
- 数据结构与算法之栈与队列<四>
- 数据结构与算法——链表