数据结构(四)之循环链表

循环链表

循环链表:是另一种形式的链式存储结构.他的特点是表中最后一个节点的指针域指向头节点,整个链表形成一个环.由此,从表中任一节点出发均可找到表中其他的节点,如下图所示为单链表的循环链表.类似的,还可以有多重链的循环链表.
在这里插入图片描述循环链表的操作和线性链表基本一致,差别仅在于算法中的循环条件不是尾节点的next为null,而是他们是否等于头指针.但有的时候,若在循环链表中设立尾结点,而不设头节点,可使某些操作简化。例如要将两个线性表合并成一个线性表时,仅需将一个表的尾和另一个表头相连,如下图所示,这个操作只需改变指针即可,运算时间为O(1),合并后如下图所示.

在这里插入图片描述
注意这里为循环链表 所以在输出的时候 就的判断什么时候跳出循环?
当尾节点 的next 域 指向头节点的时候;

合并 循环链表

package main.com.cs.test;

import main.com.cs.link.LinkList;

public class CycleLinkList<T> {

	private Node<T> head; //链表的头节点
	private Node<T> tail; //链表的尾节点

	/**
	 * 构造一个空链表
	 */
	public CycleLinkList() {
		head = tail = null;    
	}

	/**
	 * 链表内部的节点类
	 */
	private static class Node<T> {  
		T data;//节点的数据
		Node<T> next;//该节点的指向下一个节点的指针
		
		Node(T data) { 
		    this.data = data;  
		    this.next = null;   
		}  
  
	}  
	
	public void addHead(T point) {//为空链表增加头结点    
		this.head = new Node<T>(point);  
		if(tail == null) {  
		    tail = head;  
		}  
	}  
	
	public void addTail(T point){//为链表增加尾节点  
	    tail = new Node<T>(point);  
	    head.next = tail;  
	}  
	
	public void insert(T point) {
		if (this.head == null) {
			addHead(point);
			
		} else if (this.tail == this.head) {
			addTail(point);
			
		} else {
	    	Node<T> preNext = head.next;  
//			@SuppressWarnings({ "unchecked", "rawtypes" })
			Node<T> newNode = new Node(point);  
	        preNext = head.next;  
	        this.head.next = newNode;  
	        newNode.next = preNext;  
		}
	     
	}  
	
	public void printLinkList() {    //打印链表
		Node<T> curr = this.head;  
		if (isEmpty()) {
			try {
				throw new Exception("linklist is empty");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		while(curr != null){  
			System.out.print(curr.data+" ");

			//判断如果 尾节点的 next 指向 头节点 那么就跳出循环
			if (curr.next == head){
				return;
			}
			curr = curr.next;

		}  	
	}  
	
	public void delete(T data){//删除某一节点
		Node<T> curr = head, prev = null;
		boolean suc = false;//是否删除成功标志
		while (curr != null) {
			if (curr.data.equals(data)) {
				//判断是什么节点
				if (curr == head) {   //如果删除的是头节点
					System.out.println('\n'+"delete head node");
					head = curr.next;
					suc = true;
					return;
				}
				if (curr == tail) { //如果删除的是尾节点
					System.out.println('\n'+"delete tail node");
					tail = prev;
					prev.next = null;
					suc = true;
					return;
				} else {//如果删除的是中间节点(即非头节点或非尾节点)
					System.out.println('\n'+"delete center node");
					prev.next = curr.next;
					suc = true;
					return;
				}
			}
 
			prev = curr;
			curr = curr.next;	
		}
		
		if(suc == false) {
			System.out.println('\n'+"没有这个数据");
		}	
	
	}
	
	public boolean isEmpty(){//判断链表是否为空
		return this.head == null || this.tail == null;
    } 


    //合并两个单链表
    public CycleLinkList<T> list(CycleLinkList<T> c1, CycleLinkList<T> c2){

        this.head = c1.head;
        this.tail = c2.tail;
        c1.tail.next = c2.head;
        tail.next = c1.head;
		return c1;
	}




    public static void main(String[] args) {

		CycleLinkList<Integer> mylist = new CycleLinkList<Integer>();//构造一个空链表
		mylist.insert(5);  
		mylist.insert(6);  
		mylist.insert(7);  
		mylist.insert(3);

		CycleLinkList<Integer> mylist1 = new CycleLinkList<Integer>();//构造一个空链表
		mylist1.insert(21);
		mylist1.insert(31);
		mylist1.insert(41);
		mylist1.insert(51);

		System.out.println("mylist:");
		mylist.printLinkList();
		System.out.println();
		System.out.println("mylist1:");
		mylist1.printLinkList();

		System.out.println();
		System.out.println("mylist2:");

		CycleLinkList<Integer> mylist2 = new CycleLinkList<Integer>();
		mylist2.list(mylist,mylist1);
		mylist2.printLinkList();

	}
  
} 

结果:
在这里插入图片描述

发布了69 篇原创文章 · 获赞 6 · 访问量 2502

猜你喜欢

转载自blog.csdn.net/qq_40539437/article/details/104000341
今日推荐