线性表--

本文介绍了抽象数据类型和线性表的定义,阐述了线性表的顺序存储和链式存储结构。顺序存储用一维数组实现,有优缺点;链式存储涉及链表定义,包括单链表和双向链表,还详细讲解了单链表和双向链表的创建、增、删、查、改等基本操作。

抽象数据类型

  • 抽象数据类型: 带有一组操作的一些对象的集合。例如,表、集合、图以及它们各自的操作一起形成的这些对象都可以被看作是抽象数据类型。

线性表定义

  • 线性表: 零个或多个数据元素的有限序列
  • 线性表的长度: 线性表元素的个数N。当N=0时,称为空表。

线性表的顺序存储

  • 顺序实现: 可用一维数组来实现线性表的顺序存储结构
  • 顺序存储结构的三个属性
    • 存储空间的起始位置: 数组的存储位置就是存储空间的存储位置
    • 线性表的最大存储容量: 数组长度
    • 线性表的当前长度
  • 数组长度和线性表长度的区别
    • 数组长度: 存放线性表的存储空间的长度,存储分配后一般不改变
    • 线性表长度: 线性表中元素个数的长度。随着线性表插入嗯好删除操作,该量要变化。
    • 任意时刻,线性表的长度小于等于数组的长度
  • 线性表顺序存储结构的优缺点
    • 优点: 无须开辟额外的空间;可以快速地存取表中任意位置的元素
    • 缺点: 插入和删除需要移动大量元素;当线性表长度变化较大时,难以确定存储空间的容量

线性表的链式存储

链表定义

  • 链表: 包括两部分,data是存放的数据,next是指向下一个数据的指针
    在这里插入图片描述
    data是实际存储的数据值,next指针存储的是下一个数据的内存地址
  • 头指针与头节点的区别
    • 头指针: 链表指向第一个节点的指针,若链表有头节点,则是指向头节点的指针
    • 头结点: 为了操作方便而设立的,放在第一个元素的结点之前,数据域一般无意义(可存放链表的长度),不存放具体数据。作用就是表示单链表头next

单链表基本操作

创建

思路: 首先创建结点,其后创建链表;每个结点都有自身的数据和next域表示指向下一个结点的内存地址

//1.创建结点;2.创建链表
//一个结点就是一个对象.每个结点包含实际存储的数据和指向下一个结点内存地址的next域
class HeroNode {
	//自身数据
	public int no;
	public String name;
	public String nickname;
	//next指针
	public HeroNode next;

	//构造方法构造结点对象
	public HeroNode(int hNo, String hName, Stirng hNickName) {
		this.no = hNo;
        this.name = hName;
        this.nickname = hNickName;
    }
	
	//重写toStirng方法
   @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '}';
    }
}

//创建单链表
class SingleLinkedList {
	//创建头节点--头节点是不存放任何数据的,为了操作方便而设立的,放在第一个元素之前
	HeroNode head = new HeroNode(0, "", "");
}

  • 添加在链表尾部
    思路: 1、因为头节点不能动,所以用一个辅助指针(变量)指向头节点;2、每添加一个结点就相当于添加到了单链表的尾部(循环遍历找链表尾部)
public void add(HeroNode heroNode) {
	HeroNode temp = head;
	//循环找到尾结点
	while (temp.next != null) {//说明尾结点没有找到
		temp = temp.next;//temp往后面移动继续找
	}
	//循环退出时,说明结点已经找到了,就添加
	temp.next = heroNode;
}
  • 添加在链表任意位置
    思路: 1、循环遍历找到需要插入的结点位置;2、将新节点的next域指向插入结点的前一个结点的next域;3、将插入结点的前一个结点的next域指向新节点。例如,要在结点2和结点4中添加结点3;首先遍历循环找到结点3的位置,然后将结点4的next域指向结点3的next域;再将结点2的next域指向结点3
public void addByOrder(HeroNode newHeroNode) {
	//因为头节点不能动,所以需要辅助指针(变量)指向头节点
	HeroNode temp = head;
	//flag表示所要插入的结点位置是否存在
	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 = temp.next;
	}
	//循环退出时候,说明结点已经找到了。
	if (flag) {
		System.out.println("准备插入的英雄已经存在了");
	} else {
		heroNode.next = temp.next;
		temp.next = heroNode;
	}
}

思路: 1、找到要删除结点的前一个结点的位置;2、将要删除的前一个结点temp的next域指向temp的next域的next域

public void delete(int no) {
	HeroNode temp = head;
	//flag表示是否找到要删除的结点
	boolean flag = false;
	while (true) {
		if (temp.next == null) {//已经到链表最后了
			break;
		}
		if (temp.next.no == no) {//找到了要删除的结点位置
			flag = true;
			break;		
		}
		temp = temp.next;
	}
	if (flag) {
		System.out.println("");
	} else {
		temp.next = temp.next.next;
	}
}

思路: 1、根据no的值修改结点信息

//1.判断链表是否为空;2.不为空则根据no的值修改结点信息
public void update(int no) {
	if (head.next = null) {
		System.out.println("链表为空“);
		return;
	}
	//因为头节点不能动,所以需要辅助指针(变量)指向头节点
	HeroNode temp = head.next;
	//flag表示该结点信息是否需要修改
	boolean flag = false;
	while (true) {
		if (temp == null) {//说明到链表最后了
			break;
		}
		if (temp.next.no = no) {//说明要修改的结点位置已经找到了
			flag = true;
			break;
		}
		//temp往后面移动继续遍历寻找
		temp = temp.next;
	} 
	//退出while循环时,判断flag,flag为真表示需要修改,为假则不需要修改
	if (flag) {
		temp.name = heroNode.name;
		temp.nickname = heroNode.nickname;
	} else {
		System.out.println("结点不需要修改");
	}
}

显示链表

双向链表

遍历

思路: 方式和单链表一样,只是可以向前,也可以向后查找

添加

  • 添加到双向链表最后
    思路: 1.先找到双向链表的最后这个结点,假设为temp;2.temp.next = newHeroNode;3.newHeroNode.pre = temp;
  • 插入到链表任意位置
    思路:在这里插入图片描述
    ①s.pre = p.pre;
    ②.p.pre.next = s;
    ③.s.next = p;
    ④.p.pre = s

修改

思路: 和单链表一样

删除

思路:
在这里插入图片描述

1.先找到需要删除的结点temp;
2.p.pre.next = p.next;
3.p.next.pre = p.pre

在充满仪式感的生活里,一款能传递心意的小工具总能带来意外惊喜。这款基于Java开发的满屏飘字弹幕工具,正是为热爱生活、乐于分享的你而来——它以简洁优雅的视觉效果,将治愈系文字化作灵动弹幕,在屏幕上缓缓流淌,既可以作为送给心仪之人的浪漫彩蛋,也能成为日常自娱自乐、舒缓心情的小确幸。 作为程序员献给crush的心意之作,工具的设计藏满了细节巧思。开发者基于Swing框架构建图形界面,实现了无边框全屏显示效果,搭配毛玻璃质感的弹幕窗口与圆润边角设计,让文字呈现既柔和又不突兀。弹幕内容精选了30条治愈系文案,从“秋天的风很温柔”到“你值得所有温柔”,涵盖生活感悟、自我关怀、浪漫告白等多个维度,每一条都能传递温暖力量;同时支持自定义修改文案库,你可以替换成专属情话、纪念文字或趣味梗,让弹幕更具个性化。 在视觉体验上,工具采用柔和色调生成算法,每一条弹幕都拥有独特的清新配色,搭配半透明渐变效果与平滑的移动动画,既不会遮挡屏幕内容,又能营造出灵动治愈的氛围。开发者还优化了弹幕的生成逻辑,支持自定义窗口大小、移动速度、生成间隔等参数,最多可同时显示60条弹幕,且不会造成电脑卡顿;按下任意按键即可快速关闭程序,操作便捷无负担。 对于Java学习者而言,这款工具更是一份优质的实战参考。源码完整展示了Swing图形界面开发、定时器调度、动画绘制、颜色算法等核心技术,注释清晰、结构简洁,哪怕是初学者也能轻松理解。开发者在AI辅助的基础上,反复调试优化细节,解决了透明度控制、弹幕碰撞、资源占用等多个问题,这份“踩坑实录”也为同类项目开发提供了宝贵经验。 无论是想给喜欢的人制造浪漫惊喜,用满屏文字传递心意;还是想在工作间隙用治愈文案舒缓压力,或是作为Java学习的实战案例参考,这款满屏飘字弹幕工具都能满足你的需求。它没有复杂的操作流程,无需额外配置环境,下载即可运行,用最纯粹的设计传递最真挚的
给定引用内容中未提及全头歌平台上02线性表相关的内容,无法直接从引用里获取这方面资料。不过可依据引用中的线性表知识,推测全头歌平台02线性表可能会涉及的内容。 线性表有逻辑结构和物理结构。逻辑结构方面,线性表属于线性结构,数据元素之间存在一对一的关系;物理结构方面,有顺序存储和链式存储等方式,像数组是顺序存储,指针是链式存储,链式存储又包含单链表、单循环链表、双链表、双循环链表等形式 [^2]。 在线性表的操作上,不同类型链表在插入和删除元素时时间复杂度不同。比如在最后一个元素之后插入元素以及删除第一个元素的操作,单循环链表在插入时和普通单链表一样时间复杂度为O(n),删除第一个元素时因要找尾结点时间复杂度也是O(n);双链表插入操作时间复杂度为O(n),删除第一个元素时间复杂度为O(1);普通链表在最后插入元素时间复杂度为O(n),删除第一个元素时间复杂度为O(1);有尾结点指针的链表插入和删除第一个元素时间复杂度均为O(1) [^1]。 下面给出一个线性表合并函数的示例代码,可能在全头歌平台02线性表相关练习中会用到: ```cpp #include <iostream> #include <vector> // 合并两个有序线性表 void MergeList_L(const std::vector<int>& La, const std::vector<int>& Lb, std::vector<int>& Lc) { int i = 0, j = 0; while (i < La.size() && j < Lb.size()) { if (La[i] <= Lb[j]) { Lc.push_back(La[i]); i++; } else { Lc.push_back(Lb[j]); j++; } } // 将La中剩余元素添加到Lc while (i < La.size()) { Lc.push_back(La[i]); i++; } // 将Lb中剩余元素添加到Lc while (j < Lb.size()) { Lc.push_back(Lb[j]); j++; } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值