线性表——循环链表(java)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40301026/article/details/87027387

顺序表: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);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40301026/article/details/87027387
今日推荐