数据结构--单向链表

链表是区分于数组的一种地址不连续,没有顺序的数据接口,链表中的节点包含数据元素值和指针,指针指向链表的下一个节点。

使用链表无需像数组一样,需预先定义数据大小,也无需同集合需要扩容。但链表的缺点也很明显,链表读取数据需从头依次获取。不支持随机读取。

定义单向链表节点

定义单向链表类,其中有链表使用方法

  • 如何获取链表中间节点
  • 如何判断链表有环以及环的长度

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

public class LinkedNode
{
private static Logger logger = Logger.getLogger(LinkedNode.class);

	public LinkedNode() {
		head = null;
	}
	public Node head;//头节点
	public int size = 1;
	
	//头插法
	public void add(int id) {
		Node node = new Node(id);
		node.next = head;
		head = node;
		size++;
	}
	
	//尾插法
	public void endAdd(int id) {
		Node node = new Node(id);
		//获取链表最后一个节点
		Node endNode = search(size);
		//将新节点指到尾节点
		endNode.next = node;
	}
	//查找链表中的某个位置元素
	public Node search(int key) {
		if(size<key) {
			logger.debug("indexoutofboundsexception");
		}
		
		Node sNode = head;
		for(int i=1;i<key;i++) {
			sNode = sNode.next;
		}
		
		return sNode;
	}
	
	//删除某个位置的元素
	public void del(LinkedNode linked,int key) {
		//首先获取要删除元素的前一个元素
		Node BeforNode = linked.search(key+1);
		//获取要删除的元素
		Node node = linked.search(key);
		//将指针指向下一个元素
		BeforNode.next = node.next;
		//修改长度
		size--;
	}
	
	//删除重复元素
	public void delDulp() {
		//使用Map的key值不重复原则
		Map map = new HashMap();
		//添加head
		map.put(head.data, "value");
		//存储前一个节点
		Node BeforNode = head;
		//当前处理节点
		Node rNode = head;
		//是否存在下一个节点
		while(rNode.next!=null) {
			rNode = rNode.next;
			if(map.get(rNode.data)!=null) {
				logger.debug(rNode.data+"重复");
				//将前一个节点指针指向下一个节点
				BeforNode.next = rNode.next;
				//修改长度
				size--;
			}else {
				logger.debug("处理节点"+rNode.data);
				map.put(rNode.data, "value");
			}
			BeforNode = rNode;
		}
	}
	
	//链表反转
	public LinkedNode reverse(LinkedNode linked) {
		//定义反转后的链表
		LinkedNode reLinkedNode = new LinkedNode();
		reLinkedNode.head = linked.head;
		Node node = linked.head;
		while(node.next!=null) {
			//中间采用头插入法
		}
		return reLinkedNode;
	}
	
	//查找链表的中间节点
	public void searchMiddle() {
		//定义一次查询单节点
		Node firstNode = head;
		//定义一次查询双节点
		Node sendcondNode = head;
		//对于节点数为单数的链表,需判断next是否为空,否则再next会报空指针异常
		while(sendcondNode.next!=null&&sendcondNode.next.next!=null) {
			firstNode = firstNode.next;
			sendcondNode = sendcondNode.next.next;
		}
		//当读取双节点的指针到队尾的时候,单节点指针刚好到链表一半
		logger.debug(firstNode.data);
	}
	
	//判断链表是否有环
	public void isCircleLinked() {
		//定义一个慢节点
		Node slowNode = head;
		//定义一个快节点
		Node fastNode = head;
		//定义环入口节点
		Node circleNode = null;
		//环长度
		int size = 0;
		//当存在尾节点为空证明不存在环,只有存在环,快慢节点进入环后会无限循环
		while(fastNode.next!=null&&fastNode.next.next!=null) {
			slowNode = slowNode.next;
			fastNode = fastNode.next.next;
			if(slowNode==fastNode) {
				//两个节点在环上不同速跑圈,两个节点必然相遇,相遇节点即为环入口
				circleNode = slowNode;
				//再次定义临时节点为环入口节点
				Node cNode = slowNode.next;
				while(cNode!=circleNode) {
					cNode = cNode.next;
					size++;
				}
				//环链表处理结束,加上环入口节点,跳出循环
				size++;
				break;
			}
		}
		if(size>0) {
			logger.debug("此链表有环,环长度为:"+size+",环入口节点值为:"+circleNode.data);
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值