JAVA数据结构之链表的学习

链表的定义:

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

链表包含的什么:

每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

链表的种类:单向链表,双向链表,环形链表

最普通的单向链表学习:

  • 单向链表是链表结构中的最基础类型,就是由一个数据域和指向下一个的节点的指针域组成
  • 我们先来看看java中如何定义一个链表节点(LinkedNode):
//声明一个节点类
class LinkedNode{
	private int data;//节点的数据域,存放数据的
	private LinkedNode nextNode;//指向下一个的节点的指针域组成
	public int getData() {
		return data;
	}
	public void setData(int data) {
		this.data = data;
	}
	public LinkedNode getNextNode() {
		return nextNode;
	}
	public void setNextNode(LinkedNode nextNode) {
		this.nextNode = nextNode;
	}
	public LinkedNode(int data, LinkedNode nextNode) {
		super();
		this.data = data;
		this.nextNode = nextNode;
	}
	public LinkedNode() {
		super();
	}
	@Override
	public String toString() {
		return "ListNode [data=" + data + ", nextNode=" + nextNode + "]";
	}	
}
  • OK,上面已经定义好了一个节点,但这个不能实现链表的结构,因为这只是一个一个的节点,我们需要使用另外一个类来实现链表的创建,但节点是必不可少的,总结的就是当我们创建很多节点对象通过这个链表类的方法(add)把他们构建成数据结构之链表.
  • 那么链表结构中有什么?需要一个头节点headNode,因为链表就是从头节点开始寻找数据.
  • 接下来我们写链表的实现类(Linked):
//创建链表实现类
class Linked{
	private LinkedNode headNode=new LinkedNode();
	
	//传入链表节点,添加到头节点后面
	public void add(LinkedNode node) {
		//1.首先判断头节点下有没有节点,也就是是否是第一个节点的添加
		if (headNode.getNextNode()==null) {
			//2.如果是首次添加节点,那么就让头节点指向这个节点
			headNode.setNextNode(node);
		}else {
			LinkedNode temp=null;//3.声明一个中间节点对象当做指针
			temp=headNode.getNextNode();//4.从头节点开始遍历
			while (temp.getNextNode()!=null) {//5.如果当前节点的下一个节点为null,说明该节点已经是尾节点了
				temp=temp.getNextNode();
			}
			//6.让尾节点的nextNode指向新添加的节点
			temp.setNextNode(node);
		}
	}
	//打印节点信息
	public void forEachPrint() {
		LinkedNode temp=null;
		temp=headNode.getNextNode();
		while (temp!=null) {
			System.out.println(temp.getData());
			temp=temp.getNextNode();
		}
	}
}
  • 到这一步我们就完成了链表的最简单功能,添加和打印,接下来我们测试一下:
public static void main(String[] args) {
		LinkedNode node1=new LinkedNode();
		LinkedNode node2=new LinkedNode();
		LinkedNode node3=new LinkedNode();
		LinkedNode node4=new LinkedNode();
		node1.setData(1);
		node2.setData(2);
		node3.setData(3);
		node4.setData(4);
		Linked linked=new Linked();
		linked.add(node1);
		linked.add(node2);
		linked.add(node3);
		linked.add(node4);
		linked.forEachPrint();
	}
//结果是 1,2,3,4
  • 我们已经实现了添加,那怎么删除呢?删除节点的思想很简单:如果为尾节点,那么让其前一个节点的nextNode为null,如果是中间节点,则让其前一个节点指向其后一个节点就完成了删除操作,代码实现:
//节点的删除,根据索引
	public void deleteNode(LinkedNode node) {
		LinkedNode temp=null;
		temp=headNode.getNextNode();
		if (temp==null) {
			System.out.println("链表为空");
		}
		//如果删除的是头节点,则让头指针指向下一个节点
		if (temp.getData()==node.getData()) {
			headNode.setNextNode(temp.getNextNode());
			return ;
		}
		while (temp!=null) {
			//如果是尾节点,则直接让其前一个节点指向null
			if (temp.getNextNode().getData()==node.getData()&&temp.getNextNode()==null) {
				temp.setNextNode(null);
				 return ;
			}
			//如果是中间节点,则让其前一个节点指向目标节点的下一个节点
			if (temp.getNextNode().getData()==node.getData()&&temp.getNextNode()!=null) {
					temp.setNextNode(temp.getNextNode().getNextNode());
					return ;
			}
			temp=temp.getNextNode();
		}
	}
  • 链表的翻转输出:给定一个链表,反向输出其结果,代码如下:
//链表的翻转
	public void reverseLinked() {
		if(headNode==null) {
			System.out.println("链表为空");
		}
		LinkedNode reverseHeadNode=null;
		LinkedNode tempNode=headNode;
		Stack<LinkedNodeNode> stack=new Stack<LinkedNodeNode>();
		int i=0;
		while (tempNode!=null) {
			stack.push(tempNode);
			i+=1;
			tempNode=tempNode.nextNode;
		}
		Node node=headNode=null;
		for (int j = 0; j < i; j++) {
			add(stack.pop().data);
		}
	}

双向链表学习:

  • 结构如下:
class LinkedNode{
	private Integer data;//数据域
	private LinkedNode leftNode;//该节点左边的节点
	private LinkedNode rightNode;//该节点右边的节点
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值