数据结构——线性表与链表

news/2024/11/8 17:52:14 标签: 数据结构, c++, 算法

看了一下其他链接,真正的循序表应该支持随机索引的,也就是new的时候就将内存分配好。

这里是像链表一样申请了,当做链表看吧

参考链接:数据结构算法——顺序表和链表的优缺点(区别、特点)详解_顺序表和链表的优缺点(区别、特点)详解-CSDN博客

代码

#include<iostream>
#include<cmath>
using namespace std;
// 具体的元素 ,这里以书本为例 
struct element {
	element * next;
	int index; // 书本编号 
	int value;	// 价格 
	string name; // 书本名称 
};
// 代表序列整体信息 
struct sequence{
	element * next; // 指向下一个序列的指针
	int size; // 当前元素树木个数
	int maxIndex; // 最大编号 
	int sum; 
	// 寻找最后一个元素指針 
	element* findLast() {
		element* it = this->next;
		while(it->next) {
			it = it->next;
//			cout<<"寻找下一个"<<endl;
		}
		return it;	
	} 
	// 最后一个值 
	int last() {
		element* it = this->findLast();
		return it->value;
	}
	// 第一个值 
	int front() {
		element* it = this->next->next;
		return it->value;
	}
	// 向顺序表添加末尾一个元素 
	void push(int price,string name ) {
		element* newEle = new element();
//		cout<<"断点1"<<endl; 
		newEle->index = this->maxIndex;
		newEle->value = price;
		newEle->name = name;
//		cout<<"断点2"<<endl; 
		// 将新节点加入最后 
		element* last = this->findLast();
		last->next = newEle;
//		cout<<"断点3"<<endl; 
		// 更新数据
		this->size ++; 
		this->maxIndex ++; // 确保每本书的Id不一样 
		this->sum += newEle->value;
	} 
	// 向顺序表删除第一个元素 ,返回被删除的值 ,假设一切操作合理 
	int pop() {
//		cout<<"断点4"<<endl; 
		element* ele = this->next->next;
		this->next->next = ele->next;
//		cout<<"断点5"<<endl; 
		// 更新数据 
		this->size --;
		this->sum -= ele->value;
		return ele->value;
	}
	// 打印順序表状态
	void printSate()  {
		cout<<"序列长度:"<<this->size<<endl;
		cout<<"序列总和:"<<this->sum<<endl;
	}
	// 清空
	void reset() {
		// 后续加上回收 
		this->next = new element();
		this->size = 0;
		this->sum = 0;
	} 
	// 获取第x个元素,如果超出则显示最后一个元素 
	int getElement(int num) {
		int len = min(num,this->size); 
		element* it = this->next;
		for(int i=0 ;i<len;i++) {
			it = it->next;
		}
		return it->value;
	} 
	// 按照name字段查找 返回index 
	int findByName(string name){
		element* it = this->next;
		while(it->next) {
			it = it->next;
			if(it->name == name) {
				return it->index;
			} 
		}
		return -1;// 没找到 
	}
	// 遍历元素 打印书本价格 
	void printELementsValue() {
		element* it = this->next;
		while(it->next) {
			it = it->next;
			cout<<it->value<<" ";
		}
		cout<<endl;
	} 
	// 遍历元素 打印书本名称 
	void printELementsName() {
		element* it = this->next;
		while(it->next) {
			it = it->next;
			cout<<it->name<<" ";
		}
		cout<<endl;
	} 
}; 
// 思考:
// 1.无效的操作如何阻止,比如在没有元素时的pop和front和last操作? 
// 2. 如何将指针->引用,使用属性.引用 代替? 

// 初始化一个空顺序表
sequence* initSequence() {
	sequence* a = new sequence();
    a->size = 0;
    a->sum = 0;
    a->maxIndex = 0; 
    a->next = new element(); // 确认必须会有一个element 
    return a;
}


// 测试样例 1 (Accept)只有push 
void test1(sequence *seq);
// 测试样例 2 (Accept)push + pop
void test2(sequence *seq);
// 测试样例 3 (Accept)push + reset
void test3(sequence *seq);
// 测试样例 4 (Accept)push + pop + front + last
void test4(sequence *seq);
// 测试样例 5 (Accept)push + pop + printELementsValue + printELementsName
void test5(sequence *seq);

signed main() {
	cout<<"断点start"<<endl; 
    sequence* seq = initSequence(); 
	test1(seq);
	test2(seq);
	test3(seq);
	test4(seq);
	test5(seq);
	
	cout<<"断点end"<<endl; 
    return 0;
}

void test1(sequence *seq) {
	seq->push(1,"Alice");
	seq->push(2,"Bob");
	seq->push(3,"安徒生");
	seq->push(2,"Alice");
	seq->push(7,"格林语言");
	seq->push(5,"中华上下五千年");
	seq->printSate();
}

void test2(sequence *seq) {
	seq->push(3,"钢铁是怎样炼成的");
	seq->push(2,"A");
	seq->push(1,"B");
	seq->push(5,"V");
	seq->push(7,"D");
	seq->printSate();
	seq->pop();
	seq->pop();
	seq->printSate();
}
void test3(sequence *seq) {
	test1(seq);
	seq->reset();
	seq->printSate();
}
void test4(sequence *seq){
	test2(seq);
	cout<<seq->front()<<endl;
	cout<<seq->last()<<endl;
}
void test5(sequence *seq){
	test1(seq);
	test2(seq);
	seq->printELementsValue();
	seq->printELementsName();
}

这里的想法是,线性表是一个独立的个体,但是它又由多个元素组成

于是将线性表设计成单独的结构体,此外的元素对象单独再设计另一个结构体

// 具体的元素 ,这里以书本为例 
struct element {
	element * next;
	int index; // 书本编号 
	int value;	// 价格 
	string name; // 书本名称 
};
// 代表序列整体信息 
struct sequence{
	element * next; // 指向下一个序列的指针
	int size; // 当前元素树木个数
	int maxIndex; // 最大编号 
	int sum; 
}

我们创建好结构体之后,使用 new()就可以创建一个该对象。

为了能够检测到sequence对象是否为空,我们会再第一个元素设置一个空的元素对象,当做虚拟头结点,放在初始化的时候

// 初始化一个空顺序表
sequence* initSequence() {
	sequence* a = new sequence();
    a->size = 0;
    a->sum = 0;
    a->maxIndex = 0; 
    a->next = new element(); // 确认必须会有一个element 
    return a;
}

在结构体下面写一些函数,使用this指代当时实例化的对象,其再运行时确定具体值,用来引用自身属性。

// 寻找最后一个元素指針 
	element* findLast() {
		element* it = this->next;
		while(it->next) {
			it = it->next;
//			cout<<"寻找下一个"<<endl;
		}
		return it;	
	} 
	// 最后一个值 
	int last() {
		element* it = this->findLast();
		return it->value;
	}
	// 第一个值 
	int front() {
		element* it = this->next->next;
		return it->value;
	}
	// 向顺序表添加末尾一个元素 
	void push(int price,string name ) {
		element* newEle = new element();
//		cout<<"断点1"<<endl; 
		newEle->index = this->maxIndex;
		newEle->value = price;
		newEle->name = name;
//		cout<<"断点2"<<endl; 
		// 将新节点加入最后 
		element* last = this->findLast();
		last->next = newEle;
//		cout<<"断点3"<<endl; 
		// 更新数据
		this->size ++; 
		this->maxIndex ++; // 确保每本书的Id不一样 
		this->sum += newEle->value;
	} 
	// 向顺序表删除第一个元素 ,返回被删除的值 ,假设一切操作合理 
	int pop() {
//		cout<<"断点4"<<endl; 
		element* ele = this->next->next;
		this->next->next = ele->next;
//		cout<<"断点5"<<endl; 
		// 更新数据 
		this->size --;
		this->sum -= ele->value;
		return ele->value;
	}
	// 打印順序表状态
	void printSate()  {
		cout<<"序列长度:"<<this->size<<endl;
		cout<<"序列总和:"<<this->sum<<endl;
	}
	// 清空
	void reset() {
		// 后续加上回收 
		this->next = new element();
		this->size = 0;
		this->sum = 0;
	} 
	// 获取第x个元素,如果超出则显示最后一个元素 
	int getElement(int num) {
		int len = min(num,this->size); 
		element* it = this->next;
		for(int i=0 ;i<len;i++) {
			it = it->next;
		}
		return it->value;
	} 
	// 按照name字段查找 返回index 
	int findByName(string name){
		element* it = this->next;
		while(it->next) {
			it = it->next;
			if(it->name == name) {
				return it->index;
			} 
		}
		return -1;// 没找到 
	}
	// 遍历元素 打印书本价格 
	void printELementsValue() {
		element* it = this->next;
		while(it->next) {
			it = it->next;
			cout<<it->value<<" ";
		}
		cout<<endl;
	} 
	// 遍历元素 打印书本名称 
	void printELementsName() {
		element* it = this->next;
		while(it->next) {
			it = it->next;
			cout<<it->name<<" ";
		}
		cout<<endl;
	} 

测试样例使用方法进行模拟,传入具体的顺序表的实例对象,即可进行添加操作

void test1(sequence *seq) {
	seq->push(1,"Alice");
	seq->push(2,"Bob");
	seq->push(3,"安徒生");
	seq->push(2,"Alice");
	seq->push(7,"格林语言");
	seq->push(5,"中华上下五千年");
	seq->printSate();
}

void test2(sequence *seq) {
	seq->push(3,"钢铁是怎样炼成的");
	seq->push(2,"A");
	seq->push(1,"B");
	seq->push(5,"V");
	seq->push(7,"D");
	seq->printSate();
	seq->pop();
	seq->pop();
	seq->printSate();
}
void test3(sequence *seq) {
	test1(seq);
	seq->reset();
	seq->printSate();
}
void test4(sequence *seq){
	test2(seq);
	cout<<seq->front()<<endl;
	cout<<seq->last()<<endl;
}
void test5(sequence *seq){
	test1(seq);
	test2(seq);
	seq->printELementsValue();
	seq->printELementsName();
}


http://www.niftyadmin.cn/n/5744246.html

相关文章

qt QHttpMultiPart详解

1. 概述 QHttpMultiPart是Qt框架中用于处理HTTP多部分请求的类。它类似于RFC 2046中描述的MIME multipart消息&#xff0c;允许在单个HTTP请求中包含多个数据部分&#xff0c;如文件、文本等。这种多部分请求在上传文件或发送带有附件的邮件等场景中非常有用。QHttpMultiPart类…

机器学习中的两种主要思路:数据驱动与模型驱动

在机器学习的研究和应用中&#xff0c;如何从数据中提取有价值的信息并做出准确预测&#xff0c;是推动该领域发展的核心问题之一。在这个过程中&#xff0c;机器学习方法主要依赖于两种主要的思路&#xff1a;数据驱动与模型驱动。这两种思路在不同的应用场景中发挥着至关重要…

边缘计算的基本概念与实践

在物联网&#xff08;IoT&#xff09;领域&#xff0c;边缘计算正逐渐成为一种重要的技术趋势。随着设备数量的激增和数据量的不断增加&#xff0c;传统的集中式云计算模式已经难以满足实时性、数据安全性和带宽效率的需求。边缘计算通过将计算资源下沉到网络边缘&#xff0c;靠…

雷士护眼大路灯好不好?书客、月影、雷士测评深度解析!

雷士护眼大路灯好不好&#xff1f;一款护眼灯能够提供柔和舒适均匀的光线&#xff0c;能有效减轻在不良环境下长时间用眼的疲劳干涩感&#xff0c;但是现在市面上的护眼大路灯五花八门的&#xff0c;质量也是参差不齐&#xff0c;根本不知道怎么挑&#xff0c;并且有一部分人使…

如何对接低价折扣相对稳定电影票渠道?

对接低价折扣电影票渠道需要经过一系列步骤&#xff0c;以确保能够为用户提供优惠且可靠的购票体验。以下是一个基本的对接流程&#xff1a; 1.市场调研&#xff1a; 调研市场上的电影票销售渠道&#xff0c;了解主要的电影票批发商和分销商。分析竞争对手的折扣电影票服务&a…

【ARM Linux 系统稳定性分析入门及渐进 1.4 -- Crash 工具调用】

文章目录 Crash 工具的调用在实时系统上运行 crash自动查找内核对象文件内核构建要求Crash 工具的调用输出成功调用示例Crash 工具的调用 在使用 crash 工具分析转储文件时,至少需要两个参数: 内核对象文件名:通常称为内核 namelist。在最初从内核源代码构建时,其名称是 v…

ArcGIS 地理信息系统 任意文件读取漏洞复现

0x01 产品简介 ArcGIS是由美国Esri公司研发的地理信息系统(GIS)软件,它整合了数据库、软件工程、人工智能、网络技术、云计算等主流的IT技术,旨在为用户提供一套完整的、开放的企业级GIS解决方案,它包含了一套带有用户界面组件的Windows桌面应用。可以实现从简单到复杂的…

ONLYOFFICE:数字化办公的创新解决方案与高效协作平台

目录 前言—— 关于 ONLYOFFICE 桌面编辑器 1.首页介绍 2.电子表格 功能介绍 适用场景 3.ONLYOFFICE 在线Word功能 4.ONLYOFFICE 在线PPT功能 5.共同办公室 6.探索其他 总结 前言—— 在数字化办公的时代&#xff0c;传统的办公软件常常让人感到束缚与低效。而 ONLY…