顺序表:https://blog.csdn.net/qq_40301026/article/details/86760317
单链表:https://blog.csdn.net/qq_40301026/article/details/86768703
双向链表:https://blog.csdn.net/qq_40301026/article/details/86773133
循环链表其实就是在单链表的基础上,将最后一个结点的next指向了一个结点。其他的也没有什么变化。
这就是一个循环链表:
话不多说,开始写循环链表(没有带头结点)。
一、是它的结点的定义,和单链表一样。
package cn.liu.cyclelist;
public class Node {
private Object data;
private Node next;
//初始化
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node() {
this.data = null;
this.next = null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
二、初始化一个循环链表。
代码另附,主要理解思想。
第一次时没有结点,要新建一个。
第二个,第三个。。。。。。。。
package cn.liu.cyclelist;
public class CycleList {
private Node tail = null;//尾指针,永远指向链表的尾部
private int size = 0;//记录结点个数
//新建一个循环链表,采用尾插法
public void initlist(int o) {//o是结点个数
detection1(o);//检测o是不是合格
for(int i = 0; i < o ;i++) {
Node newnode = new Node();//新建一个结点
if(tail == null) {//没有结点,即i==0时。要结点next指向自己
tail =newnode;
tail.setNext(newnode);
}else {
newnode.setNext(tail.getNext());//newnode的next指向了尾指针tail的next(首结点)
tail.setNext(newnode); //将尾结点的next指向nextnode
tail = newnode; //再将尾指针指向newnode
}
size++;
}
}
三、在某个位置增加一个结点。
规定第一个结点认为是位置1,最后一个结点位置为size,往最后一个结点后面插入的位置认为是size+1
分为了四种情况:
1.链表不存在。
2.在第一个结点处增加。
3.在最后一个结点处增加。
4.其他结点。
public void addsomewhere(int o,Object obj) {
detection2(o);//检测索引是否合格
Node newnode = new Node(obj);
Node temp = tail;
if(size==0) {//链表不存在
tail = newnode;
tail.setNext(newnode);
}else {//链表存在
if(o==1) {
newnode.setNext(tail.getNext());
tail.setNext(newnode);
}else if(o==size+1) {
newnode.setNext(tail.getNext());
tail.setNext(newnode);
tail = newnode;
}else {//和普通的插入没有什么区别
temp = tail.getNext();//指向第一个结点
for(int i=2;i<o;i++) {
temp = temp.getNext();
}
newnode.setNext(temp.getNext());
temp.setNext(newnode);
}
}
size++;
}
四、删除某一个结点。
1.删除第一个结点。
2.删除最后一个结点。
3.删除其他结点。
public void delete(int o) {
detection3(o);
Node temp = tail;
if(o==1) {//删除第一个结点
temp = tail.getNext();
tail.setNext(temp.getNext());
temp.setNext(null);
}else{//删除最后一个结点
for(int i=1;i<o;i++) {
temp = temp.getNext();//移动到了被删除结点的前一个结点
}
if(o==size) {//最后一个结点
temp.setNext(tail.getNext());
tail.setNext(null);
tail = temp;
}else {
/*
temp.setNext(temp.getNext().getNext());
temp.getNext().setNext(null);//改变了temp.getNext()了,被删结点已找不到。
*/
Node m = temp.getNext();
temp.setNext(m.getNext());
m.setNext(null);
}
}
size--;
}
五、其他的比较简单不再啰嗦。
附源代码:
package cn.liu.cyclelist;
public class Node {
private Object data;
private Node next;
//初始化
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node() {
this.data = null;
this.next = null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
package cn.liu.cyclelist;
public class CycleList {
private Node tail = null;//尾指针,永远指向链表的尾部!!!!!!!!!!!
private int size = 0;//记录结点个数
//新建一个循环链表,采用尾插法
public void initlist(int o) {//o是结点个数
detection1(o);//检测o是不是合格
for(int i = 0; i < o ;i++) {
Node newnode = new Node();//新建一个结点
if(tail == null) {//没有结点,即i==0时。要结点next指向自己
tail =newnode;
tail.setNext(newnode);
}else {
newnode.setNext(tail.getNext());//newnode的next指向了尾指针tail的next(首结点)
tail.setNext(newnode); //将尾结点的next指向nextnode
tail = newnode; //再将尾指针指向newnode
}
size++;
}
}
//在某个位置增加节点
//第一个结点认为是位置1,最后一个结点位置为size,往最后一个结点后面插入的位置认为是size+1
public void addsomewhere(int o,Object obj) {
detection2(o);//检测索引是否合格
Node newnode = new Node(obj);
Node temp = tail;
if(size==0) {//链表不存在
tail = newnode;
tail.setNext(newnode);
}else {//链表存在
if(o==1) {
newnode.setNext(tail.getNext());
tail.setNext(newnode);
}else if(o==size+1) {
newnode.setNext(tail.getNext());
tail.setNext(newnode);
tail = newnode;
}else {//和普通的插入没有什么区别
temp = tail.getNext();//指向第一个结点
for(int i=2;i<o;i++) {
temp = temp.getNext();
}
newnode.setNext(temp.getNext());
temp.setNext(newnode);
}
}
size++;
}
//在链首增加一个结点
public void addhead(Object obj) {
addsomewhere(1,obj);
}
//在链尾增加一个结点
public void addtail(Object obj) {
addsomewhere(size+1,obj);
}
//返回链表长度
public Object length() {
return size;
}
//返回指定结点的data
public Object getCycleList(int o) {
return seekNode(o).getData();
}
//删除某个结点
public void delete(int o) {
detection3(o);
Node temp = tail;
if(o==1) {//删除第一个结点
temp = tail.getNext();
tail.setNext(temp.getNext());
temp.setNext(null);
}else{//删除最后一个结点
for(int i=1;i<o;i++) {
temp = temp.getNext();//移动到了被删除结点的前一个结点
}
if(o==size) {//最后一个结点
temp.setNext(tail.getNext());
tail.setNext(null);
tail = temp;
}else {
/*
temp.setNext(temp.getNext().getNext());
//temp.getNext().setNext(null);temp.getNext()被改变,被删结点找不到了。
*/
Node m = temp.getNext();
temp.setNext(m.getNext());
m.setNext(null);
}
}
size--;
}
//修改某个结点的值
public void amend(int o,Object obj) {
detection3(o);
seekNode(o).setData(obj);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
Node temp = tail;
for(int i=0;i<size;i++) {
temp= temp.getNext();//指向下一个结点
sb.append(temp.getData() + "-->");//取到当前节点的data
}
sb.delete(sb.length()-2, sb.length());//删除倒数第三个到倒数第二个字符
sb.setCharAt(sb.length()-1, '}');
return sb.toString();
}
private Node seekNode(int o) {
detection3(o);
Node temp = tail;
for(int i =0;i<o;i++) {
temp = temp.getNext();
}
return temp;
}
private void detection1(int i) {
if(i<=0) {
throw new RuntimeException("索引越界异常:"+i);
}
}
private void detection2(int i) {
if(i<=0 || i>size+1) {
throw new RuntimeException("索引越界异常:"+i);
}
}
private void detection3(int i) {
if(i<=0 || i>size) {
throw new RuntimeException("索引越界异常:"+i);
}
}
}