单链表的应用实例(增删改查)

        单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

带头结点的单链表和不带头结点的单链表
一、两者区别:

1、不带头结点的单链表对于第一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常在单链表的开始结点之前附设一个头结点。

2、带头结点的单链表,初始时一定返回的是指向头结点的地址,所以一定要用二维指针,否则将导致内存访问失败或异常。

3、带头结点与不带头结点初始化、插入、删除、输出操作都不样,在遍历输出链表数据时,带头结点的判断条件是while(head->next!=NULL),而不带头结点是while(head!=NULL),虽然头指针可以在初始时设定,但是如1所述,对于特殊情况如只有一个节点会出现问题。

 下面就是手写带头结点的单链表代码

定义存储的数据类型

这里定义一个英雄,相当于节点,节点中指向下一个节点,英雄中存在下一个英雄。

class HeroNode {

	public int no;
	public String name;
	public String nickname;
	public HeroNode next;

	// 构造器
	public HeroNode(int no, String name, String nickname) {
		this.no = no;
		this.name = name;
		this.nickname = nickname;
	}

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

}

然后手写链表的实现

首先是添加方法  尾部添加和有序添加

// 定义一个SingleLinkedList管理英雄人物
class SingleLinkedList {

	// 先初始化一个头结点 头结点不要动
	private HeroNode head = new HeroNode(0, "", "");

	// 添加方法 添加到链表的最后
	// 不考虑编号的顺序时,找到当前链表中下一个next为null的英雄则为最后一个英雄
	// 将最后英雄的next指向新节点
	public void add(HeroNode heroNode) {
		// head节点不能动,因此我们需要一个辅助变量
		// temp相当于指针,遍历每个变量
		HeroNode temp = head;
		while (true) {
			// 什么时候说明链表到最后了就结束
			if (temp.next == null) {
				break;
			}
			// 如果不是最后一个就后移
			temp = temp.next;
		} // 只有temp指向最后一个的时候 才会退出循环
			// 让最后一个元素的下一个指向新添加的元素结束
		temp.next = heroNode;
	}

	// 第二种方式添加 根据序号添加
	// 如果排名存在则显示添加失败,并给出提示
	public void addByOrder(HeroNode heroNode) {
		// head节点不能动,因此我们需要一个辅助变量
		// 因为单链表 因此我们找的temp是添加位置的前一个节点 否则插入不了
		HeroNode temp = head;
		boolean flag = false;
		// 标志添加的节点编号是否存在,默认为false
		// break会跳出循环
		while (true) {
			if (temp.next == null) {
				// 说明temp已经在链表的最后
				break;
			}
			// 下一个节点的序号是否比需要添加的节点大
			if (temp.next.no > heroNode.no) {
				break;
			} else if (temp.next.no == heroNode.no) {
				flag = true;// 说明编号存在
				break;
			}
			// 往后找出当前节点的下一个节点比需要添加的节点大的节点
			temp = temp.next;
		}
		// 判断flag的值 如果为true 证明编号存在了
		if (flag) {
			System.out.println("编号存在,不能加入");
		} else {
			heroNode.next = temp.next;
			temp.next = heroNode;
		}

	}

循环遍历链表的方法

	// 显示链表[遍历]
	public void list() {
		// 通过辅助变量 遍历链表
		HeroNode temp = head;
		while (true) {
			// 头结点不能动 辅助变量来遍历
			// 判断链表到最后结束
			if (temp.next == null) {
				break;
			}
			System.out.println(temp.next);
			temp = temp.next;
		}

	}

修改链表中数据的方法

	// 根据heroNode的no节点来修改
	public void update(HeroNode heroNode) {
		// 判断链表是否是空的
		if (head.next == null) {
			System.out.println("链表是空的");
			return;
		}
		// 找到需要修改的节点,根据no找
		// 定义辅助变量查找
		HeroNode temp = head;
		boolean flag = false;
		while (true) {
			if (temp.no == heroNode.no) {
				//找到了
				flag = true;
				break;
			}
			if (temp.next == null) {
				// 链表遍历结束
				break;
			}
			
			temp = temp.next;
		}
		//找到了就修改
		if(flag) {
			temp.name=heroNode.name;
			temp.nickname=heroNode.nickname;
		}else {
			//flag仍然等于false 表示没有找到这个节点
			System.out.println("没有找到编号等于这个的节点"+heroNode.no);
		}

	}

删除链表中数据的方法

//删除节点 找到需要删除的节点的前一个节点
	//被删除的节点没有任何引用  会被垃圾回收机制回收
	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.println("没有找到待删除的节点");
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LeeGaKi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值