搜尋
首頁JavaJava基礎java實作單鍊錶(Linked List)相關
java實作單鍊錶(Linked List)相關Mar 01, 2021 am 09:47 AM
java單鍊錶

java實作單鍊錶(Linked List)相關

免費學習推薦:java基礎教學

「文章目錄

      ##一、單鍊錶介紹
    • 二、單鍊錶的實作
    • 1.單鍊錶的建立(新增)
  • 1.1尾新增
1.2依排名新增

#2.單鍊錶節點的修改

3.單鍊錶節點的刪除4.單鍊錶的完整實作三、單鍊錶面試題

  • 一、單鍊錶介紹
  • 單鍊錶是一個
  • 有序列表,以節點
  • 的方式
鍊式儲存資訊

,但節點java實作單鍊錶(Linked List)相關不一定連續

,每一個節點包含data域和next域。

data域:用來存放資料。

  • next域
    :指向下一個節點。 java實作單鍊錶(Linked List)相關

  • java實作單鍊錶(Linked List)相關
  • 鍊錶分為
帶頭節點的鍊錶

不帶頭節點的鍊錶

單鍊錶(帶頭節點)單鍊錶(不帶頭節點)

##二、單鍊錶的實作

需求:使用有head頭的
單向鍊錶

實作–水滸英雄排行榜管理。 1)完成對英雄的

增刪改查

2)第一種方法在新增英雄時,直接加入到鍊錶的尾部

3)第二種方式在新增英雄時,根據排名將英雄插入到指定位置(如果已有這個排名,則新增失敗,並給予提示)

#1.單鍊錶的建立(新增)

1.1尾加入


java實作單鍊錶(Linked List)相關
尾新增的想法

先建立一個head頭節點,作用就是表示單鍊錶的頭。

然後每增加一個節點,就直接加入到鍊錶的最後。

尾新增即:不考慮編號順序,找到目前鍊錶的最後節點,將最後這個節點的next指向新的節點。

程式碼實作

	// 添加方式1:尾添加
	public void add(HeroNode heroNode) {
		// 因为head头不能动,因此需要一个辅助变量(指针)temp
		HeroNode temp = head;
		while (true) {
			// 如果遍历到链表的最后
			if (temp.next == null) {
				break;
			}
			// temp指针后移
			temp = temp.next;
		}
		// 当退出循环时,temp指向链表的最后
		temp.next = heroNode;
	}

1.2依排名新增

java實作單鍊錶(Linked List)相關依排名新增的想法

先透過輔助變數(temp指標)找到新加入的節點的位置。

新節點.next=temp.next;

temp.next=新的節點;



程式碼實作

	// 添加方式2:根据排名添加
	public void addByOrder(HeroNode heroNode) {
		HeroNode temp = head;// 借助辅助指针
		boolean flag = false;// 添加的编号是否存在
		while (true) {
			if (temp.next == null) {// 遍历到结尾
				break;
			}
			if (temp.next.no > heroNode.no) {// 位置找到,就在temp的后面插入
				break;
			} else if (temp.next.no == heroNode.no) {// 该编号已存在
				flag = true;
				break;
			}
			temp = temp.next;// 后移,遍历当前链表
		}
		if (flag) {
			// 不能添加
			System.out.printf("准备插入的英雄的编号%d已经存在,不能加入\n", heroNode.no);
		} else {
			// 插入到temp的后面
			heroNode.next = temp.next;
			temp.next = heroNode;
		}
	}
2.單鍊錶節點的修改

修改的想法

透過遍歷先找到該節點。

temp.name =newHeroNode.name;temp.nickname=newHeroNode.nickname;

程式碼實作
<pre class='brush:php;toolbar:false;'> // 修改节点信息,根据节点的no属性修改其他信息 public void update(HeroNode newHeroNode) { // 空链表无法修改节点信息 if (head.next == null) { System.out.println(&quot;链表为空~&quot;); return; } // 根据no排名找到需要修改的节点 HeroNode temp = head.next; boolean flag = false;// flag表示是否找到需要修改的节点 while (true) { if (temp == null) { // 遍历到结尾 break; } if (temp.no == newHeroNode.no) { // 找到 flag = true; break; } temp = temp.next;// 后移 } if (flag) { temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; } else { System.out.printf(&quot;没有找到编号为%d的节点,不能修改\n&quot;, newHeroNode.no); } }</pre>
3.單鍊錶節點的刪除
java實作單鍊錶(Linked List)相關#刪除的想法

找到需要刪除的節點的前一個節點。

temp.next=temp.next.next

被刪除的節點,將不會有其它引用指向,會被垃圾回收機制回收。
java實作單鍊錶(Linked List)相關

程式碼實作

	public void delete(int no) {
		HeroNode temp = head;
		boolean flag = false;// 是否找到待删除节点
		while (true) {
			if (temp.next == null) {
				// 遍历到结尾
				break;
			}
			if (temp.next.no == no) {
				// 找到了待删除节点的前一个节点
				flag = true;
				break;
			}
			temp = temp.next;// 后移
		}
		if (flag) {
			// 可以删除
			temp.next = temp.next.next;
		} else {
			System.out.printf("要删除的%d节点不存在\n", no);
		}
	}

#4.單鍊錶的完整實作java實作單鍊錶(Linked List)相關

package com.gql.linkedlist;/**
 * 单链表
 * 
 * @guoqianliang
 *
 */public class SingleLinkedListDemo {
	public static void main(String[] args) {
		// 创建节点
		HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
		HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
		HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
		HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
		// 创建单向链表
		SingleLinkedList singleLinkedList = new SingleLinkedList();
		// 加入
		singleLinkedList.addByOrder(hero1);
		singleLinkedList.addByOrder(hero4);
		singleLinkedList.addByOrder(hero3);
		singleLinkedList.addByOrder(hero2);

		singleLinkedList.list();

		// 测试修改节点
		HeroNode newHeroNode = new HeroNode(2, "小卢", "玉麒麟~");
		singleLinkedList.update(newHeroNode);
		System.out.println("修改后的链表情况:");
		singleLinkedList.list();

		// 删除一个节点
		singleLinkedList.delete(1);
		singleLinkedList.delete(2);
		singleLinkedList.delete(3);
		singleLinkedList.delete(4);
		System.out.println("删除后的链表情况:");
		singleLinkedList.list();

	}}//定义SingleLinkedList,管理英雄class SingleLinkedList {
	// 初始化头结点,不存放具体数据
	private HeroNode head = new HeroNode(0, "", "");

	// 添加方式1:尾添加
	// 思路:
	// 1.找到当前链表的最后节点
	// 2.将这个最后的节点的next指向新的节点
	public void add(HeroNode heroNode) {
		// 因为head头不能动,因此需要一个辅助变量(指针)temp
		HeroNode temp = head;
		while (true) {
			// 如果遍历到链表的最后
			if (temp.next == null) {
				break;
			}
			// temp指针后移
			temp = temp.next;
		}
		// 当退出循环时,temp指向链表的最后
		temp.next = heroNode;
	}

	// 添加方式2:根据排名添加
	public void addByOrder(HeroNode heroNode) {
		HeroNode temp = head;// 借助辅助指针
		boolean flag = false;// 添加的编号是否存在
		while (true) {
			if (temp.next == null) {// 遍历到结尾
				break;
			}
			if (temp.next.no > heroNode.no) {// 位置找到,就在temp的后面插入
				break;
			} else if (temp.next.no == heroNode.no) {// 该编号已存在
				flag = true;
				break;
			}
			temp = temp.next;// 后移,遍历当前链表
		}
		if (flag) {
			// 不能添加
			System.out.printf("准备插入的英雄的编号%d已经存在,不能加入\n", heroNode.no);
		} else {
			// 插入到temp的后面
			heroNode.next = temp.next;
			temp.next = heroNode;
		}
	}

	// 修改节点信息,根据节点的no属性修改其他信息
	public void update(HeroNode newHeroNode) {
		// 空链表无法修改节点信息
		if (head.next == null) {
			System.out.println("链表为空~");
			return;
		}
		// 根据no排名找到需要修改的节点
		HeroNode temp = head.next;
		boolean flag = false;// flag表示是否找到需要修改的节点
		while (true) {
			if (temp == null) {
				// 遍历到结尾
				break;
			}
			if (temp.no == newHeroNode.no) {
				// 找到
				flag = true;
				break;
			}
			temp = temp.next;// 后移
		}
		if (flag) {
			temp.name = newHeroNode.name;
			temp.nickname = newHeroNode.nickname;
		} else {
			System.out.printf("没有找到编号为%d的节点,不能修改\n", newHeroNode.no);
		}
	}

	// 删除节点
	// 思路:
	// 1.找到需要删除节点的前一个节点
	// 2.temp.next=temp.next.next
	// 3.被删除的节点将会被垃圾回收机制回收
	public void delete(int no) {
		HeroNode temp = head;
		boolean flag = false;// 是否找到待删除节点
		while (true) {
			if (temp.next == null) {
				// 遍历到结尾
				break;
			}
			if (temp.next.no == no) {
				// 找到了待删除节点的前一个节点
				flag = true;
				break;
			}
			temp = temp.next;// 后移
		}
		if (flag) {
			// 可以删除
			temp.next = temp.next.next;
		} else {
			System.out.printf("要删除的%d节点不存在\n", no);
		}

	}

	// 显示链表[遍历]
	public void list() {
		// 空链表直接返回
		if (head.next == null) {
			System.out.println("链表为空");
			return;
		}
		// 仍然使用辅助变量(指针),进行循环
		HeroNode temp = head.next;
		while (true) {
			if (temp == null) {
				break;
			}
			System.out.println(temp);
			// 将temp后移
			temp = temp.next;
		}

	}}//定义HeroNode,每一个HeroNode就是一个节点class HeroNode {
	public int no;// 排名
	public String name;
	public String nickname;// 昵称
	public HeroNode next;// 指向下一个节点

	// 构造器
	public HeroNode() {
		super();
	}

	public HeroNode(int no, String name, String nickname) {
		super();
		this.no = no;
		this.name = name;
		this.nickname = nickname;
	}

	// 重写toString
	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
	}}

運行結果

三、單鏈表面試題

###### 上面四個面試題,答案都放在下面的程式碼中###
package com.gql.LinkedList;import java.util.Stack;/**
 * 模拟单链表
 * 
 * @author Hudie
 * @Email:guoqianliang@foxmail.com
 * @date 2020年7月16日下午6:47:42
 */public class SingleLinkedListDemo {
	public static void main(String[] args) {
		// 创建节点
		HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
		HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
		HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
		HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
		// 创建单向链表
		SingleLinkedList singleLinkedList = new SingleLinkedList();
		// 加入
		singleLinkedList.addByOrder(hero1);
		singleLinkedList.addByOrder(hero4);
		singleLinkedList.addByOrder(hero3);
		singleLinkedList.addByOrder(hero2);

		singleLinkedList.list();

		// 测试修改节点
		HeroNode newHeroNode = new HeroNode(2, "小卢", "玉麒麟~");
		singleLinkedList.update(newHeroNode);
		System.out.println("修改后的链表情况:");
		singleLinkedList.list();

		// 删除一个节点
		singleLinkedList.delete(4);
		System.out.println("删除后的链表情况:");
		singleLinkedList.list();
		
		//练习4:反向打印单链表
		System.out.println("反向打印单链表:");
		reversePrint(singleLinkedList.getHead());
		//练习3:反转单链表
		reversalList(singleLinkedList.getHead());
		System.out.println("反转过后的单链表为:");
		singleLinkedList.list();
		
		// 练习1:获取单链表节点个数
		System.out.println("单链表的有效个数为:");
		System.out.println(getLength(singleLinkedList.getHead()));
		
		int index = 2;
		//练习2:获取单链表倒数第index给节点
		System.out.println("倒数第"+ index +"个节点为:");
		System.out.println(getLastKNode(singleLinkedList.getHead(),index));
	}

	/**
	 * @Description: 获取单链表节点个数 思路: while循环 + 遍历指针
	 */
	public static int getLength(HeroNode head) {
		if (head.next == null) {
			return 0;
		}
		int length = 0;
		// 辅助指针
		HeroNode p = head.next;
		while (p != null) {
			length++;
			p = p.next;
		}
		return length;
	}

	/**
	 * @Description: 
	 * 查找单链表中倒数第index个节点 index:表示倒数第index给节点 
	 * 思路:
	 * 1.首先获取链表的长度length,可直接调用getLength
	 * 2.然后从链表第一个开始遍历,遍历(length-index)个 
	 * 3.找不到返回null
	 */
	public static HeroNode getLastKNode(HeroNode head, int index) {
		if (head.next == null) {
			return null;
		}
		int length = getLength(head);
		if (index <= 0 || index > length) {
			return null;
		}
		HeroNode p = head.next;
		for(int i = 0;i < length-index;i++){
			p = p.next;
		}
		return p;
	}
	
	/**
	 * @Description: 
	 * 反转单链表[带头节点]
	 * 思路:
	 * 1.先定义一个节点reversalHead = new HeroNode(0,"","");
	 * 2.遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reversalHead的最前端
	 * 3.原来的链表的head.next = reversalHead;
	 */
	public static void reversalList(HeroNode head){
		//链表为空或只有一个节点,无需反转,直接返回
		if(head.next == null || head.next.next == null){
			return;
		}
		//辅助指针p
		HeroNode p = head.next;
		HeroNode next = null;//指向辅助指针p的下一个位置
		HeroNode reversalHead = new HeroNode(0,"","");
		//遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reversalHead的最前端
		while(p != null){
			next = p.next;
			p.next = reversalHead.next;
			reversalHead.next = p;
			p = next;
		}
		head.next = reversalHead.next;
	}
	/**
	 * @Description: 
	 * 反向打印单链表[带头节点]
	 * 思路1:单链表反转后打印(不建议,因为破坏了单链表的结构)
	 * 思路2:使用栈结构,利用栈先进后出的特点
	 */
	public static void reversePrint(HeroNode head){
		if(head.next == null){
			return;
		}
		Stack stack = new Stack();
		HeroNode p = head.next;
		while(p != null){
			stack.push(p);
			p = p.next;
		}
		//将栈中的节点进行打印
		while(stack.size() > 0){
			System.out.println(stack.pop());
		}
	}}// 定义SingleLinkedList,管理英雄,即链表的增删改查class SingleLinkedList {
	// 初始化头结点,不存放具体数据
	private HeroNode head = new HeroNode(0, "", "");

	// 添加方式1:尾添加
	// 思路:
	// 1.找到当前链表的最后节点
	// 2.将这个最后的节点的next指向新的节点
	public void add(HeroNode heroNode) {
		// 因为head头不能动,因此需要一个辅助变量(指针)temp
		HeroNode temp = head;
		while (true) {
			// 如果遍历到链表的最后
			if (temp.next == null) {
				break;
			}
			// temp指针后移
			temp = temp.next;
		}
		// 当退出循环时,temp指向链表的最后
		temp.next = heroNode;
	}

	public HeroNode getHead() {
		return head;
	}

	// 添加方式2:根据排名添加
	public void addByOrder(HeroNode heroNode) {
		HeroNode temp = head;// 借助辅助指针
		boolean flag = false;// 添加的编号是否存在
		while (true) {
			if (temp.next == null) {// 遍历到结尾
				break;
			}
			if (temp.next.no > heroNode.no) {// 位置找到,就在temp的后面插入
				break;
			} else if (temp.next.no == heroNode.no) {// 该编号已存在
				flag = true;
				break;
			}
			temp = temp.next;// 后移,遍历当前链表
		}
		if (flag) {
			// 不能添加
			System.out.printf("准备插入的英雄的编号%d已经存在,不能加入\n", heroNode.no);
		} else {
			// 插入到temp的后面
			heroNode.next = temp.next;
			temp.next = heroNode;
		}
	}

	// 修改节点信息,根据节点的no属性修改其他信息
	public void update(HeroNode newHeroNode) {
		// 空链表无法修改节点信息
		if (head.next == null) {
			System.out.println("链表为空~");
			return;
		}
		// 根据no排名找到需要修改的节点
		HeroNode temp = head.next;
		boolean flag = false;// flag表示是否找到需要修改的节点
		while (true) {
			if (temp == null) {
				// 遍历到结尾
				break;
			}
			if (temp.no == newHeroNode.no) {
				// 找到
				flag = true;
				break;
			}
			temp = temp.next;// 后移
		}
		if (flag) {
			temp.name = newHeroNode.name;
			temp.nickname = newHeroNode.nickname;
		} else {
			System.out.printf("没有找到编号为%d的节点,不能修改\n", newHeroNode.no);
		}
	}

	// 删除节点
	// 思路:
	// 1.找到需要删除节点的前一个节点
	// 2.temp.next=temp.next.next
	// 3.被删除的节点将会被垃圾回收机制回收
	public void delete(int no) {
		HeroNode temp = head;
		boolean flag = false;// 是否找到待删除节点
		while (true) {
			if (temp.next == null) {
				// 遍历到结尾
				break;
			}
			if (temp.next.no == no) {
				// 找到了待删除节点的前一个节点
				flag = true;
				break;
			}
			temp = temp.next;// 后移
		}
		if (flag) {
			// 可以删除
			temp.next = temp.next.next;
		} else {
			System.out.printf("要删除的%d节点不存在\n", no);
		}

	}

	// 显示链表[遍历]
	public void list() {
		// 空链表直接返回
		if (head.next == null) {
			System.out.println("链表为空");
			return;
		}
		// 仍然使用辅助变量(指针),进行循环
		HeroNode temp = head.next;
		while (true) {
			if (temp == null) {
				break;
			}
			System.out.println(temp);
			// 将temp后移
			temp = temp.next;
		}

	}}// 定义HeroNode,每一个HeroNode就是一个节点class HeroNode {
	public int no;// 排名
	public String name;
	public String nickname;// 昵称
	public HeroNode next;// 指向下一个节点

	// 构造器
	public HeroNode() {
		super();
	}

	public HeroNode(int no, String name, String nickname) {
		super();
		this.no = no;
		this.name = name;
		this.nickname = nickname;
	}

	// 重写toString
	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
	}}
#########相關學習推薦:##########java基礎############

以上是java實作單鍊錶(Linked List)相關的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
带你搞懂Java结构化数据处理开源库SPL带你搞懂Java结构化数据处理开源库SPLMay 24, 2022 pm 01:34 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

Java集合框架之PriorityQueue优先级队列Java集合框架之PriorityQueue优先级队列Jun 09, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

完全掌握Java锁(图文解析)完全掌握Java锁(图文解析)Jun 14, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

一起聊聊Java多线程之线程安全问题一起聊聊Java多线程之线程安全问题Apr 21, 2022 pm 06:17 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

详细解析Java的this和super关键字详细解析Java的this和super关键字Apr 30, 2022 am 09:00 AM

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

Java基础归纳之枚举Java基础归纳之枚举May 26, 2022 am 11:50 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

java中封装是什么java中封装是什么May 16, 2019 pm 06:08 PM

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。

归纳整理JAVA装饰器模式(实例详解)归纳整理JAVA装饰器模式(实例详解)May 05, 2022 pm 06:48 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于设计模式的相关问题,主要将装饰器模式的相关内容,指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式,希望对大家有帮助。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境