C++基础语法:链表和数据结构

前言

       "打牢基础,万事不愁" .C++的基础语法的学习

引入

        链表是最基础的数据集合,对标数组.数组是固定长度,随机访问,链表是非固定长度,不能随机访问.数组查找快,插入慢;链表是插入快,查找慢.

        前面推导过"数据结构+算法=数据集合".想建立一个数据集合,就要设计数据结构和他的算法.数据结构和算法是密不可分的.当然已经有优秀的前辈已经设计好了许多种数据结构供程序员选择使用.但学习最好是能知其所以然,

        链表和数组是所有数据结构的底层.比如链栈,链队列,动态数组这些概念,表示其底层是链表或者数组.链表的内容如此少,以至于<C++ Prime Plus> 6th Edition(以下称"本书")都没写.我想学习的目的在于吸收设计者的思想,以及一些固定的解决问题模式.所以对链表内容做个理解.

链表的类表示

        链表有数据域和指针域.数据域是数据集合的对象,指针域是链表本身的指针,他负责把数据链接在一起.以下为链表类示例,

typedef int Data;
class Node{
	Data data;        //数据域
	Node* next;       //指针域
};

        Data是泛指类型,data表示泛型的单个对象,数据域不是固定的,他还可以是指向数组的指针Data*,表示数组作为单个元素组成的集合;或者指向其他结点(头结点)的指针,表示结点组成的集合.结点表示另一个链表.

        指针域next也不是固定的,他还可以有其他指针,但类型必须是Node*,因为这样才可以把数据链接起来.例如加上一个Node* front,指向链表前一个元素,做成双向链表.next或者front只是符号,需要通过算法体现出来.

        所以Node类是一个极简版本的链表.

链表的图示 

       

 结点采用了类包含数据的形式

        前面的帖子C++基础语法:类包含-CSDN博客提到了类包含的用法,当时站在设计模式中的行为模式的角度去解释类包含,即类包含用于纳入已有行为类对象,形成一套解决方案.

        结点是另一种类包含的用法,结点类包含的类对象,建立结点类,作为数据结构的基本元素

链表的算法

        链表要做哪些事?他要建立一个集合,尾部指空;可以插入元素,删除元素,检索元素等,代码如下:

#include<iostream>	
using namespace std;

struct Node {
	//数据可见
	int data;
	Node* next;
};
class LinkList {
	Node* firstNode;					//头结点,表示整个链表
public:
	/*初始化*/
	LinkList() {
		firstNode = new Node();			//建立头结点,数据空
	}
	/*插入int类型元素*/
	void add(int data) {
		Node* link = new Node();		//建立新结点
		link->data = data;				//传入数据
		link->next = firstNode->next;	
		firstNode->next = link;			//和上一行代码一起表示新结点插入头结点后面	
	}
	/*查找数据,返回所在位置*/
	int find(int data) {
		Node* p = firstNode->next;		//从第一个结点(非头结点)找起
		int num = 0;
		while (p) {
			num++;
			if (p->data == data)
				return num;
			p = p->next;
		}
		cout << "没找到数据" << endl;
		return -1;
	}
	/*删除数据所在所有结点*/
	bool erase(int data) {
		Node* p = firstNode;			//新建一个结点指向头结点
		bool success = true;			//声明标志位
		/*下面如果用while(p), 将产生异常, 原因暂不知道*/
		while (p->next) {				//从第一个元素开始遍历链表
			if (p->next->data == data) {//如果找到数据所在前一个结点
				Node* tmp = p->next;	//标识出要删除的结点
				p->next = p->next->next;//前结点的next指向将被删除结点的后面
				delete(tmp);			//删除所在结点
				success = false;		//修改标志位
			}
			p = p->next;				//指针指向下一个结点,把链表找遍,所有结点删除
		}
		if(success==false)
			return true;				//返回true
		cout << "没找到数据:"<<data << endl;	
		return false;					//遍历链表没找到数据,返回false
	}
	/*打印链表数据*/
	int printLinkList() {
	//下面这行如果用Node *p=firstNode;打印出来的是头结点值0
		Node* p = firstNode->next;		//从第一个结点(非头结点)开始打印
		cout << "当前链表内数据如下:" << endl;
		while (p) {
			cout << p->data << endl;
			p = p->next;
		}
		return 0;
	}
};

测试代码:

//测试代码
int main(void) {
	LinkList* p = new	LinkList();		//建立链表,生成头结点
	p->add(3);
	p->add(4);							//添加元素
	p->add(5);							//添加元素
	p->add(6);							//添加元素
	p->add(4);							//添加元素
	p->printLinkList();
	p->erase(4);						//删除数据4所在所有结点
	cout << "删除结点后链表内数据:" << endl;
	p->printLinkList();
	p->erase(7);						//删除一个链表中没有的元素
	return 0;
}

     ----说明: 用普通class类做的链表,没用template实现,结点固定了数据类型int

        代码的几处说明:

        1>为了方便书写,定义了struct结构的Node,相当于类数据不分私有private和公开public,全部公开,在LinkList类里可以用对象直接访问,省了一些步骤.如果用class定义Node,要在public里定义访问data的getData()方法,才能获得data.

        2>头结点

        在建立链表LiniList时建立了头结点firstNode,没有数据,指针指空.头结点是具体数据.通过头结点可以访问整个链表,所以头结点视为数据集合.在任何需要数据集合的地方,都需要使用头结点.如在erase和printLinkList中,遍历链表,都是声明一个指针,指向firstNode,凡是遍历链表的地方都是这个方法.初始化时就必须生成头结点

        3> 插入和删除

        在描述插入和删除这个地方要注意顺序:

        插入时,先说明插入结点的后一个结点是什么,再说明他在哪一个结点后面 

		link->next = firstNode->next;	//新结点插入头结点
		firstNode->next = link;

         删除时,先标记出结点,然后说明前后结点的关系,因为是单链表,所以只需要说明被删除结点的后一个结点,挂到他前一个结点的next即可(如果是双向链表,还要说明后一个结点的前面是被删除结点的前一个结点),然后用delete删除标识结点.

        删除时有一点小问题,可看出双向链表的优点   ----了解

				Node* tmp = p->next;	//标识出要删除的结点
				p->next = p->next->next;//前结点的next指向将被删除结点的后面
				delete(tmp);			//删除所在结点

        插入和删除在初学时是一个难点,需要多想想. 

        4>头插法

        每插入一个结点,都被放到头结点的后面,先前在头结点后面那个结点被放到新结点的后面.理解了插入,就明白了是怎么做的.

        5>find函数

        代码里定义了find函数,但没有使用他.

        1.链表本身不支持随机访问,找到位置意义不大.----但想要也可以实现数组那样的"[]"下标功能

        2.链表里可以多次出现同一个值,按照find函数定义只能找到最后插入的那个值的位置.所以严格来说这个函数存在bug.如果要找到最后一次出现的某个元素是第几次插入,倒是可以用find.操作步骤:先求出链表里所有元素的个数,再拿来减去find()函数的返回值.

        3.起个抛砖引玉的作用.数据结构是一种逻辑结构,可以由需求定义各种各样的算法,并不局限于增删查等几种.比如还可以写出统计链表元素个数的算法,将链表元素逆序排列,像数组一样的随机访问[]等等(多种多样)

以链表为基础的数据结构

        数据结构是有着某种逻辑结构的数据集合.数据集合的物理层是数组和链表.以链表为物理层的数据结构有链栈,链队列,二叉树等许多.他们有哪些共同特征呢?

        一是有结点类,把将要加入数据结构的数据,放入结点

        二是有头结点.在初始化容器时,把头结点建立起来.

        三是有增删查算法(栈和队列不需要查,可以不定义).四根据需要开发其他算法.

小结

        本贴没有用template泛型定义,适用面窄.用模板来做可以提高通用性,内部类可以方便实现更多功能,在后续数据结构中,用模板实现.

         数据结构是编程比较难的部分,考验逻辑思维能力.编写的代码也容易出bug,要反复调试,考验耐心.但也比较有趣,可以自己提需求自己实现(连最基本的链表都有很多"玩法"),同时也是比较有价值的部分.虽然有很多成熟代码可以用,但是代码要多写手熟

        

        

       

         

         

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/792230.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python-找客户软件

软件功能 请求代码&#xff1a; 填充表格&#xff1a; 可以search全国各个区县的所有企业信息&#xff0c;过滤手机号、查看是否续存/在业状态。方便找客户。 支持定-制-其他引-留-阮*件&#xff08;XHSS&#xff0c;DYY&#xff0c;KS&#xff0c;Bi-li*Bi-li&#xff09; V*…

嵌入式转行2个星期,一些真心话建议~

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 嵌入式转行2个星期&…

【计算机方向】中科院三区,国人发文占比>50%,录用容易,认可度不低~

今天小编带来计算机领域SCI快刊的解读&#xff01; 如有相关领域作者有意投稿&#xff0c;可作为重点关注&#xff01; 期刊解析 01 期刊信息 出版商&#xff1a;Springer Singapore ISSN&#xff1a;1672-6529 E-ISSN&#xff1a;2543-2141 期刊官方网站: https://www.sprin…

市面上值得入手的骨传导耳机怎么选?一次给你搞定全方位的选购攻略

随着骨传导耳机市场的日益发展&#xff0c;有很多人使用了一些不合适的骨传导耳机导致听力损伤等问题&#xff0c;这些问题也引起很多人日益关注的。原因大致就是&#xff0c;市面上出现了大量由非专业品牌贴牌和有网红生产的骨传导耳机产品&#xff0c;他们的核心技术的研发和…

CSDN回顾与前行:我的创作纪念日——2048天的技术成长与感悟

CSDN回顾与前行&#xff1a;我的创作纪念日——2048天的技术成长与感悟 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 前言 时光荏苒&#xff0c;岁月如梭。转眼间&#xff0c;从我在CSDN上写下第一篇技术博客《2-6 带头结点的链式表操作…

寻找并可视化交互

「AI秘籍」系列课程&#xff1a; 人工智能应用数学基础 人工智能Python基础 人工智能基础核心知识 人工智能BI核心知识 人工智能CV核心知识 使用特征重要性、弗里德曼 H 统计量和 ICE 图分析相互作用 本文中的代码需要安装 R 语言包 药物的副作用可能取决于你的性别。吸入…

解决浏览器 CORS跨域问题

跨域问题其实就是不同源请求导致 解决跨域问题时&#xff0c;Chrome 插件 requestly 解决 1、Chrome 应用商店 &#xff1a;chrome://extensions/ 搜索 requestly 插件。并添加到扩展程序 2、打开扩展程序&#xff0c;为当前接口设置请求头 在response Header 中设置 Acce…

samba共享windows和ubuntu的文件

通过Samba服务器实现Windows与Ubuntu之间的文件共享是一个常见的需求&#xff0c;下面是实现这一目标的详细步骤&#xff1a; 一、Ubuntu开启Samba服务器 安装Samba&#xff1a; 打开终端&#xff0c;使用以下命令安装Samba服务&#xff1a; sudo apt update sudo apt install…

辐射神经场算法——Instant-NGP / Mipi-NeRF 360 / 3D Gaussian Splatting

辐射神经场算法——Instant-NGP / Mipi-NeRF 360 / 3D Gaussian Splatting 1. Instant-NGP1. MultiResolution Hash Encoding1.2 Accelerated Ray Marching1.3 实验结果 2. Mip-NeRF 3602.1 场景参数化2.2 在线蒸馏2.3 失真正则化2.4 实验结果 3. 3D Gaussian Splatting3.1 Dif…

Monaco 使用 DefinitionProvider

DefinitionProvider 可以弹出方法定义&#xff0c;效果如下&#xff0c;按住 command 鼠标左键&#xff0c;弹出方法说明。 点击时 Monaco Editor 会调用注册函数&#xff0c;注册函数返回文件地址和需要显示的位置&#xff0c;实现代码如下 return monaco.languages.register…

自主研发接口测试框架

测试任务&#xff1a;将以前完成的所有的脚本统一改写为unitest框架方式 1、需求原型 1.1 框架目录结构 V1.0&#xff1a;一般的设计思路分为配置层、脚本层、数据层、结果层&#xff0c;如下图所示 V 2.0&#xff1a;加入驱动层testdriver 1.2 框架各层需要完成的工作 1、配…

Swiper轮播图实现

如上图&#xff0c;列表左右滚动轮播&#xff0c;用户鼠标移动到轮播区域&#xff0c;动画停止&#xff0c;鼠标移开轮播继续。 此例子实现技术框架是用的ReactCSS。 主要用的是css的transform和transition来实现左右切换动画效果。 React代码&#xff1a; import React, { us…

WEB-INF 泄露-RoarCTF-2019-EasyJava(BUUCTF)

题目页面 点开help 这里存在文件下载漏洞&#xff0c;参数选择POST传参&#xff08;使用HackBar插件&#xff09; 查看文件内容 下载存有web信息的XML文件&#xff0c;这里补充一点知识点 WEB-INF主要包含一下文件或目录&#xff1a; /WEB-INF/web.xml&#xff1a;Web应用程序…

关于思维和智能体模型的思考(1)

思维的本质&#xff1a;它的能力似乎源自于那些智能体之间复杂的交错关联 --马文 明斯基 最近阅读美国马文 明斯基写的书《心智社会》&#xff0c;觉得忽然开朗。他对人类思维&#xff0c;智能&#xff0c;智能体等概念做了十分优雅的解读。 个人觉得&#xff0c;他利…

【银河麒麟高级服务器操作系统】数据中心系统异常卡死分析处理建议

了解银河麒麟操作系统更多全新产品&#xff0c;请点击访问&#xff1a;https://product.kylinos.cn 1.服务器环境以及配置 【机型】浪潮NF5280M5 处理器&#xff1a; Intel 内存&#xff1a; 1T 【内核版本】 4.19.90-24.4.v2101.ky10.x86_64 【OS镜像版本】 银河麒麟…

element UI时间组件两种使用方式

加油&#xff0c;新时代打工&#xff01; 组件官网&#xff1a;https://element.eleme.cn/#/zh-CN/component/date-picker 先上效果图&#xff0c;如下&#xff1a; 第一种实现方式 <div class"app-container"><el-formref"submitForm":model&q…

滑动窗口,最长子序列最好的选择 -> O(N)

最近在学校上短学期课程&#xff0c;做程序设计题&#xff0c;一下子回忆起了大一学数据结构与算法的日子&#xff01; 这十天我会记录一些做题的心得&#xff0c;今天带来的是对于最长子序列长度题型的解题框架&#xff1a;滑动窗口 本质就是双指针算法&#xff1a; 通过le…

VSCode神仙插件——通义灵码 (AI编程助手)

1、安装&登录插件 安装时,右下角会有弹窗,让你登录该软件 同意登录后,会跳转浏览器页面 VSCode右下角出现如下图标即登录成功 2、使用 (1)点击左侧栏中的如下图标,打开通义灵码,可以进行智能问答 (2) 选中代码,右键 但是,上述所有的操作会在左侧问答栏中提供答案,并无法直…

2024最适合小白的Midjourney教程,值得收藏!

一、Midjourney 的提示词 1、提示可以包括一个或多个图像 URL、多个文本短语以及一个或多个参数 1&#xff09;Image Prompts&#xff08;图像提示&#xff09;&#xff1a;可以将图像 URL 添加到提示中以影响最终结果的样式和内容。图像 URL 始终出现在提示的前面。文件应以.…

索引(数据库重点!!!)

1.介绍 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构。 2.索引结构 BTree索引&#xff1a;最常见的索引类型Hash索引&#xff1a;哈希表实现R-tree&#xff08;空间索引&#xff09;Full-text&#xff08;全文索引&#xff09; B-Tree&#xff08;…