package com.wrx.study.singlelist;
/**
* @auther Len901
* @time 2022-10-08-22:59
*/
//单链表的相关操作
public class SingleLinkedList {
public static void main(String[] args) {
//头插法
System.out.println("头插法输出结果:");
SingleLinkedListDemo singleLinkedListDemo1 = new SingleLinkedListDemo();
singleLinkedListDemo1.addFirst(10);
singleLinkedListDemo1.addFirst(20);
singleLinkedListDemo1.addFirst(30);
singleLinkedListDemo1.addFirst(40);
singleLinkedListDemo1.addFirst(50);
//输出一把
singleLinkedListDemo1.list();
//尾差法
System.out.println("尾插法输出结果:");
//任意位置插入
System.out.println("插入数据前:");
SingleLinkedListDemo singleLinkedListDemo = new SingleLinkedListDemo();
singleLinkedListDemo.addLast(10);
singleLinkedListDemo.addLast(20);
singleLinkedListDemo.addLast(30);
singleLinkedListDemo.addLast(40);
singleLinkedListDemo.addLast(50);
//输出一把
singleLinkedListDemo.list();
System.out.println("插入数据后:");
singleLinkedListDemo.addIndex(3,88);
//输出一把
singleLinkedListDemo.list();
//求单链表的长度
System.out.println("单链表的长度为"+singleLinkedListDemo.length());
//单链表的查找操作
if (singleLinkedListDemo.search(30)){
System.out.println("存在这个数");
}else {
System.out.println("不存在这个数");
}
if (singleLinkedListDemo.search(70)){
System.out.println("存在这个数");
}else {
System.out.println("不存在这个数");
}
//单链表的删除操作
singleLinkedListDemo.delete(30);
//输出一把
System.out.println("删除后的单链表:");
singleLinkedListDemo.list();
singleLinkedListDemo.delete(77);
//修改节点的信息
singleLinkedListDemo.update(4,77);
//输出一把
System.out.println("输出修改后的单链表:");
singleLinkedListDemo.list();
//清空单链表以防内存泄漏
try{
singleLinkedListDemo.clear();
//输出一把
singleLinkedListDemo.list();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
class Node{
public int value;//存储节点的值
public Node next;//用来存储下一个节点的地址
//构造方法
public Node(int value) {
this.value = value;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
'}';
}
}
//定义单链表来管理我们的数据
class SingleLinkedListDemo{
//先初始化一个头节点,头节点不能动,不存放具体数据
private Node head=new Node(0);
//添加节点到单链表
//每次对链表的访问都需要通过一个辅助变量temp从头节点开始,
//通过循环依次访问,在循环中对一个节点中的数据进行操作后,都需要有temp = temp.next,这样才能遍历链表
//向单链表中增加元素
//法一:头插法
public void addFirst(int value){
Node node = new Node(value);
// 如果是第一次插入,直接到头节点
if (head==null){
head=node;
}else{//不是第一次插入
node.next=head;// 插入的节点指向头节点
head=node;// 更新头节点
}
}
//法二:尾插法
/*
尾插法需要先找到链表中的最后一个结点,之后直接将新建结点放到链表最后面即可.
首先Node temp = head,让其遍历单链表,找到最后一个结点,之后直接temp.next = node即完成了单链表的尾插法.
*/
public void addLast(int value){
Node node = new Node(value);
// 如果是第一次插入,直接到头节点
if(head == null){
head = node;
}else {
Node temp=head;
// 找尾巴
while (temp.next!=null){
temp=temp.next;
}
// 退出上面的循环,temp所执行的位置就是尾节点
temp.next=node;
}
}
//任意位置插入
/**
* @param index:插入的下标
* @param value:要插入的数据
* @return true
*/
public boolean addIndex(int index,int value){
Node node = new Node(value);
Node temp = searchIndex(index);
//如果链表为空,直接插入到头节点
if (temp==null){
node.next=head;
head=node;
}else{//链表不为空,插入到cur的位置处
node.next = temp.next; // 将node链接到temp的下一个节点
temp.next = node; // 再将temp链接到node
}
return true;
}
//找到下标为index-1位置的节点
private Node searchIndex(int index){
if (index == 0) {
return null;
}
int count = 0;
Node cur = head;
while (cur.next != null && count < index-1) {
cur = cur.next;
count++;
}
return cur;
}
//遍历并打印单链表
public void list(){
//判断链表是否为空
if (head.next==null){
System.out.println("该单链表为空");
}
//因为头节点不能动,因此我们需要一个辅助变量来遍历
Node temp=head;
while (true){
//判断链表是否到最后
if(temp==null){
break;
}
//输出节点信息
System.out.println(temp);
//temp向后移
temp=temp.next;
}
}
//求单链表的长度
//通过遍历单链表的方式获取单链表的长度(不算上头节点)
public int length(){
int length=0;
Node temp=head.next;
while (temp!=null){
length++;
temp=temp.next;
}
return length;
}
//单链表的查找操作
//有则返回true,无则false
public boolean search(int value){
Node temp=head;
while (true){
if (temp.next.value==value){
return true;
}else {
temp=temp.next;
if (temp.next==null){
return false;
}
}
}
}
//单链表的删除操作
/*从单链表中删除一个节点的思路:
1、我们先找到需要删除的这个节点的前一个节点,并用temp指向这个节点
2、temp.next=temp.next.next
3、被删除的节点,将不会有其他引用指向,会被垃圾回收机制回收
*/
//head不能动,因此我们需要一个temp辅助节点找到待删除结点的前一个节点
public void delete(int value){
Node temp=head;
boolean flag=false;//表示是否找到删除的结点
while (true){
if(temp.next==null){//表示已经到了链表的最后
break;
}
if(temp.next.value==value){
//找到了待删除节点的前一个节点temp
flag=true;
break;
}
temp=temp.next;//temp向后移,继续遍历
}
//判断flag
if(flag){//找到
temp.next=temp.next.next;
}else{
System.out.println("要删除的"+value+"节点不存在");
}
}
//修改节点的信息
public void update(int num,int value){
//判断是否为空
if(head.next==null){
throw new RuntimeException("链表为空,无法进行修改");
}
if (num<0){
throw new RuntimeException("操作位置不合法");
}
//找到需要修改的节点
//定义一个辅助变量
Node temp=head;
int index=0;
while (index!=num){
temp=temp.next;
index++;
}
temp.value=value;
}
//清空单链表以防内存泄漏
public void clear(){
head=null;
}
}
Java数据结构与算法之单链表的相关操作的小练习
最新推荐文章于 2024-09-05 10:39:00 发布