数据结构学习之循环单链表

循环单链表即将普通的单链表结成一个环,与单链表相比,循环单链表主要有以下两点差异:

1、链表初始化时需要将头指针指向自己,形成一个环。

2、遍历时不再判断下一节点不为空,而是判断下一节点不是头结点。

节点类的实现与单链表相同

//节点类
public class Node<T> {
	//数据域	
	public T data;
	//指针域
	public Node<T> next;
	
	public Node() {
		
	}
	
   public Node(T data) {
		this.data=data;
	}
   
   public Node(T data, Node<T> next) {
       this.data = data;
       this.next = next;
   }
}

链表实现类的初始化不一样,添加了 this.head.next = this.head; 代码串,即将头指针指向自己,形成一个环

//循环单链表
public class LinkList<T> {
	// 头指针
	Node<Object> head;
	// 结点个数
	int size;

	/**
	 * 初始化一个空链表
	 */
	public LinkList() {
		this.head = new Node<Object>();
		this.size = 0;
		this.head.next = this.head;
	}
}

下面针对增删改查等基本操作进行代码实现

1、insert(Object obj) 在链表中插入元素


	/**
	 * 在链表中插入元素
	 */

	public void insert(Object obj) {
		// 实例化一个节点
		Node<Object> node = new Node<>(obj, head);
		// 第一次插入元素
		if (head.next == head) {
			head.next = node;
		} else {

			Node<Object> tmp = head;
			while (tmp.next != head) {
				tmp = tmp.next;
			}
			// 新插入的最后一个节点指向第一个节点
			tmp.next = node;
		}
		// 每插入一个元素,节点个数+1
		size++;
	}

2、 traverse(String str) 对链表进行遍历,tmp.next != head即第二点差异

	/**
	 * 遍历链表
	 *
	 */
	public void traverse(String str) {
		Node<Object> tmp = head;
		System.out.println(str+":");
		// 从head开始遍历
		while (tmp.next != head) {
			System.out.print(tmp.next.data + " ");
			tmp = tmp.next;
		}
		System.out.println();
	}

3、 size()获取节点个数

	/**
	 * 获取链表节点个数
	 */
	public int size() {

		return this.size;
	}

4、delete(int index) 删除链表中某个index节点的元素

	/**
	 * 删除链表中某个index节点的元素
	 */
	public void delete(int index) {
		// 范围校验
		if (index > this.size-1 || index<0) {
			throw new IndexOutOfBoundsException();
		}
		Node<Object> temp = head;
		Node<Object> cur = head;
		// 先让temp指针走size-index步
		for (int i = size - index; i > 0; i--) {
			temp = temp.next;
		}
		// 现在第二个指针开始走,等到第一个走完第二个指针所处的位置就是要删除的元素
		while (temp.next != head) {
			temp = temp.next;
			cur = cur.next;
		}
		cur.next = cur.next.next;
		size--;
	}

5、deleteObj(Object obj)  删除链表中指定的元素

	/**
	 * 删除链表中指定的元素
	 */
	public void deleteObj(Object obj) {
		// 范围校验
		if (obj == null) {
			throw new IllegalArgumentException();
		}
		Node<Object> temp = head;
		while (temp.next != head) {
			if (temp.next.data.equals(obj)) {
				temp.next = temp.next.next;
				size--;
				return;
			}
			temp = temp.next;
		}
	}

6、get(int index) 获取链表中指定节点的元素

	/**
	 * 获取链表中指定节点的元素
	 */
	public Node<Object> get(int index) {
		// 范围校验
		if (index < 0 || index > this.size-1) {
			throw new IndexOutOfBoundsException();
		}
		Node<Object> tmp = head;
		// 从head开始遍历,直到找到链表中最后一个节点
		while (index >= 0) {
			tmp = tmp.next;
			index--;
		}
		return tmp;
	}

7、isEmpty() 判空

	/**
	 * 判空
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		if (size == 0) {
			return true;
		}
		return false;
	}

8、update(int index, Object obj) 修改节点元素

	/**
	 * 修改节点元素
	 */
	public void update(int index, Object obj) {
		// 范围校验
		if (index > this.size-1  || index<0) {
			throw new IndexOutOfBoundsException();
		}
		this.get(index).data = obj;
	}

9、isExist(Object obj) 判断是否存在某元素

	/**
	 * 判断是否存在某元素
	 */
	public boolean isExist(Object obj) {
		// 范围校验
		if (obj == null) {
			throw new IllegalArgumentException();
		}
		Node<Object> temp = head;
		while (temp.next != head) {
			if (temp.next.data.equals(obj)) {
				return true;
			}
			temp=temp.next;
		}
		return false;
	}

以下是上面代码的测试方法

	public static void main(String[] args) {
		// 插入元素测试
		LinkList<Object> linkList = new LinkList<>();
		linkList.insert("1");
		linkList.insert("3");
		linkList.insert("5");
		linkList.insert("7");
		linkList.insert("9");
		linkList.traverse("遍历");
		
		Node<Object> node=linkList.get(3);
		System.out.println("获取链表中指定节点的元素:"+node.data);
		
		int size=linkList.size();
		System.out.println("获取链表中节点个数:"+size);
		
		boolean bol=linkList.isEmpty();
		System.out.println("判空:"+bol);
		
		linkList.update(2,"55");
		linkList.traverse("修改指定下标元素");
		
		boolean isExsit=linkList.isExist("1");
		System.out.println("判断是否存在某元素:"+isExsit);
		
		boolean isExsit2=linkList.isExist("2");
		System.out.println("判断是否存在某元素:"+isExsit2);
		
		linkList.deleteObj("55");
		linkList.traverse("删除指定元素");
		
		linkList.delete(3);
		linkList.traverse("删除指定下标元素");

	}

执行结果如下:

遍历:
1 3 5 7 9 
获取链表中指定节点的元素:7
获取链表中节点个数:5
判空:false
修改指定下标元素:
1 3 55 7 9 
判断是否存在某元素:true
判断是否存在某元素:false
删除指定元素:
1 3 7 9 
删除指定下标元素:
1 3 7

以上所有代码均可直接运行,源码地址:https://download.csdn.net/download/xuewenyong/11110545

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值