数据结构课程——第一次作业

news2024/12/27 16:27:57

T1:Gram_ham实现凸包算法:

(1)思路:

 

(2)代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<stack>

using namespace std;
//备注:这里把 顶点 用 一棵树tree 来形象化的表示,没啥别的意思。。。

//函数声明:
vector<vector<int>> outerTrees(vector<vector<int>> &trees); // 返回 一个二维数组,就是最终的凸包节点次序
int cross(const vector<int> & p, const vector<int> & q, const vector<int> & r);//计算 极角
int distance(const vector<int> & p, const vector<int> & q); //计算2点之间的距离平方



int main()
{
	//只需要求一个 凸包
	//处理输入:
	int T;
	cout << "请输入需要测试的 次数: " << endl;
	cin >> T; //测试次数
	while (T--)
	{
		cout << "请输入节点个数 :" << endl;
		int n; // 有n个 顶点
		cin >> n;
		vector<vector<int>> trees(n, vector<int>(2, 0));
		for (int i = 0; i < n; i++)
		{
			cout << "请输入第" << i+1 << "个坐标: ";
			cin >> trees[i][0] >> trees[i][1];  //得到坐标点(x,y)
		}

		//(1)计算凸包的 调用 outerTreees函数,得到一个二维数组,其中存储了 凸包的节点次序的二维数组
		vector<vector<int>> vec = outerTrees(trees);
		//(2)输出凸包的顶点次序:
		int size = vec.size();
		cout << "这个凸包的 顶点坐标 次序如下: " << endl;
		for (int i = 0; i <= size - 1; i++)
		{
			cout << "(" << vec[i][0] << "," << vec[i][1] << ")" << " ";
		}
		cout << endl;
	}
	return 0;
}

vector<vector<int>> outerTrees(vector<vector<int>> &trees) {
	int n = trees.size();
	if (n < 4) {
		return trees;
	}
	int bottom = 0;
	//找到 y 最小的点 bottom
	for (int i = 0; i < n; i++) {
		if (trees[i][1] < trees[bottom][1]) {
			bottom = i;
		}
	}
	swap(trees[bottom], trees[0]);
	//以 bottom 原点,按照极坐标的角度大小进行排序 
	sort(trees.begin() + 1, trees.end(), [&](const vector<int> & a, const vector<int> & b) {
		int diff = cross(trees[0], a, b);
		if (diff == 0) {
			return distance(trees[0], a) < distance(trees[0], b);
		}
		else {
			return diff > 0;
		}
	});
	//对于凸包最后且在同一条直线的元素按照距离从大到小进行排序 
	int r = n - 1;
	while (r >= 0 && cross(trees[0], trees[n - 1], trees[r]) == 0) {
		r--;
	}
	for (int l = r + 1, h = n - 1; l < h; l++, h--) {
		swap(trees[l], trees[h]);
	}
	stack<int> st;
	st.emplace(0);
	st.emplace(1);
	for (int i = 2; i < n; i++) {
		int top = st.top();
		st.pop();
		//如果当前元素与栈顶的两个元素构成的向量顺时针旋转,则弹出栈顶元素 
		while (!st.empty() && cross(trees[st.top()], trees[top], trees[i]) < 0) {
			top = st.top();
			st.pop();
		}
		st.emplace(top);
		st.emplace(i);
	}

	vector<vector<int>> res;
	while (!st.empty()) {
		res.emplace_back(trees[st.top()]);
		st.pop();
	}
	return res;
}

int cross(const vector<int> & p, const vector<int> & q, const vector<int> & r) {
	return (q[0] - p[0]) * (r[1] - q[1]) - (q[1] - p[1]) * (r[0] - q[0]);
}

int distance(const vector<int> & p, const vector<int> & q) {
	return (p[0] - q[0]) * (p[0] - q[0]) + (p[1] - q[1]) * (p[1] - q[1]);
}

T2:利用递归 —— 实现 输出杨辉三角的 第i行的 所有 元素:

(1)思路:

<1>递归之处:第i行的第j个元素 = 第i-1行的第j-1个元素 + 第i-1行的第j个元素

<2>所有的递归,都会有出口,比如这里:第1行 或者 第i行的第1列 或者 第i行的最后一列 这些元素的值就是 "1",不能再相深层递归了

(2)代码:

#include<iostream>
using namespace std;
//利用 递归 实现输出 杨辉三角的 第i行数据

int data_i_j(int i, int j) //作用:递归 返回 第i行 ,第j列的 元素
{
	//(0)出口:
	if (i == 1 || j == 1 || j == i) //第1行 或者 第i行的第1列 或者 第i行的最后一列
	{
		return 1;
	}
	//(1)向上面一层递归:
	return data_i_j(i - 1, j - 1) + data_i_j(i - 1, j);
}

int main()
{
	int T;
	cout << "请输入需要测试的 次数 :" << endl;
	cin >> T;
	while (T--)
	{
		cout << "请输入 第几行 : " << endl;
		int i;
		cin >> i;
		//输出 第i行的 所有 杨辉三角 元素:
		for (int j = 1; j <= i; j++)
		{
			cout << data_i_j(i, j) << " ";
		}
		cout << endl;
	}

	return 0;
}

T3:利用双向链表存储 学生的信息:

(1)思路:

<1>结构体NODE: 数据 + pre指针 + next指针

      结构体LIST:       Head指针 + Tail指针 + size节点个数(不包含head 和 tail)

<2>可以在 结构体外面写 一个函数给 LIST进行初始化, 也可以 就在里面写一个 构造函数,效果是一样的,这是必须的,因为:

第一:初始的2个指针如果不开辟空间,就是NULL指针,用了就报错

第二:双向链表初始结构就是 head 和 tail的相互指向,需要初始设置这一步

<3>至于 添加 和 删除 节点: 无非就是 修改指针域 罢了

(2)代码:

#include<iostream>
#include<string>
using namespace std;

//实现双端环形链表 结构
//环形结构比较 容易实现 , 只要保证 第一个节点 最后一个节点相互指向就可以了

int MaxNum = 1000; //最大容量

//节点数据结构
typedef struct node
{
	int Id;   //学号
	string name; //姓名
	struct node* Pre;//上一节点
	struct node* Next;//下一节点
}NODE, *PNODE;

//双向链表数结构
typedef struct List
{
	NODE* pHead;//链表头指针
	NODE* pTail;//链表尾指针
	int size; //当前节点的 数量
	//默认构造函数:
	List()
	{
		this->size = 0;
		//防止使用空指针:在堆上创建2个指针给head和tail比较好
		pHead = new NODE;
		pTail = new NODE;
		//初始的循环双向链表结构
		pHead->Next = pTail;
		pHead->Pre = pTail; //这个不动
		pTail->Pre = pHead;
		pTail->Next = pHead; //这个不动
	}
}LIST;

//定义2个函数:
int newStudent(List &L, int stu_id, string stu_name)
{
	//(0)检查是否达到人数的上限:
	if (L.size == MaxNum)
	{
		return L.size; //不能添加了。。。
	}
	//(1)创建一个 新的node*节点,具有id数据,并且 加入到L队列的末尾
	NODE* new_node = new NODE;
	new_node->Id = stu_id;
	new_node->name = stu_name;
	//--以下更新4个指针域:
	new_node->Next = L.pTail;
	new_node->Pre = L.pTail->Pre;
	L.pTail->Pre->Next = new_node;//成功insert一个节点
	//更新 pTail的pre指针
	L.pTail->Pre = new_node; //这4步的指针修改次序不能乱!!!
	//更新size 并且返回
	L.size++;
	return L.size;
}
int delStudent(List& L, int stu_id)
{
	//从前向后遍历 —— 找到具有 这个 id的 节点,然后 删除节点
	//如果没有找到,就不用任何操作:
	NODE* tmp = L.pHead->Next;
	while (tmp != L.pTail)
	{
		if (tmp->Id == stu_id)
		{
			//删除当前节点,只要修改 前一个节点的next 和 后一个节点的pre就行
			tmp->Pre->Next = tmp->Next;
			tmp->Next->Pre = tmp->Pre;
			//--
			L.size--;
			delete tmp;
			break;
		}
		//--
		tmp = tmp->Next;
	}
	return L.size;
}

int main()
{
	List stuList;
	int cnt = 0;
	//(1)循环测试 : 添加1-10号学生
	for (int i = 1; i <= 10; i++)
	{
		char ch = 'a' + i;
		string str = "Xi_model_";
		str = str + ch;
		cnt = newStudent(stuList, i , str);
	}
	cout << "当前学生人数 :" << cnt << endl;
	//(2)删除2,3号学生
	cnt = delStudent(stuList, 2);
	cnt = delStudent(stuList, 3);
	cout << "当前学生人数 :" << cnt << endl;
	//(3)遍历stuList
	NODE* tmp = stuList.pHead->Next;
	while (tmp != stuList.pTail)
	{
		cout << tmp->Id << " " << tmp->name << endl;;
		tmp = tmp->Next;
	}
	cout << endl;
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

存储网络架构——DAS、NAS、SAN、分布式组网架构

目录 DAS直连式存储 NAS网络附加存储 SAN存储 存储区域网络 分布式存储组网 DAS直连式存储 DAS遇到的挑战 NAS网络附加存储 向主机提供文件服务&#xff1b;文件系统由存储设备维护&#xff0c;用户访问文件系统&#xff0c;不直接访问底层存储 拥有所有主机上文件与底层存储空…

图像复原与重建

文章目录 一、实验目的二、实验内容1. 噪声图像及其直方图。2. 空间噪声滤波器。3. 逆滤波。 一、实验目的 了解一些常用随机噪声的生成方法。掌握根据指定退化函数对图像进行退化的方法。掌握当模糊图像只存在噪声时的几种滤波复原方法。掌握当模糊图像同时存在线性退化和噪声…

OpenCV C++案例实战三十一《动态时钟》

OpenCV C案例实战三十一《动态时钟》 前言一、绘制表盘二、绘制刻线三、获取系统时间四、结果展示五、源码总结 前言 本案例将使用OpenCV C实现动态时钟效果。原理也很简单&#xff0c;主要分为绘制表盘、以及获取系统时间两步。 一、绘制表盘 首先为了效果显示美观一点&…

数据驱动测试、结果报告生成,Python接口自动化测试全方位解析

B站首推&#xff01;2023最详细自动化测试合集&#xff0c;小白皆可掌握&#xff0c;让测试变得简单、快捷、可靠https://www.bilibili.com/video/BV1ua4y1V7Db 目录 一、背景 二、准备工作 三、编写测试脚本 四、数据驱动测试 五、结果报告生成 六、总结 七、参考链接 …

线性表,顺序表,链表

线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直线 …

阿里云对象存储OSS使用 HTTPS访问

阿里云对象存储OSS使用 HTTPS ​ 在部署项目的时候遇到了一个问题&#xff0c;就是https页面访问http资源报错的问题。 问题&#xff1a; 写了一个前端项目在云服务器部署&#xff0c;我的域名申请了ssl证书并在云服务器nginx部署&#xff0c;所以页面是https页面&#xff0c;但…

Ansible的脚本-playbook 剧本

目录 1.剧本&#xff08;playbook&#xff09; 1.playbook介绍 2. playbooks 的组成 3.案例&#xff1a;编写httpd的playbook 4.定义、引用变量 5.指定远程主机sudo切换用户 6.when条件判断 7.迭代 2.playbook的模块 1.Templates 模块 2.tags 模块 3.Roles 模块 1.…

TCP协议——这篇文章GET全

TCP协议文章目录 1. UDP和TCP协议的比较1.1 UDP协议1.2 TCP协议1.3 特点比较 2. TCP协议建立连接的三次握手3. TCP协议断开连接的四次挥手4. TCP协议的几个特性4.1 确认应答4.2 超时重传4.3 连接管理4.4 滑动窗口4.5 流量控制4.6 拥塞控制 1. UDP和TCP协议的比较 UDP和TCP作为…

多维时序 | MATLAB实现BP神经网络多变量时间序列预测(考虑历史特征的影响,多指标、多图输出)

多维时序 | MATLAB实现BP神经网络多变量时间序列预测(考虑历史特征的影响,多指标、多图输出) 目录 多维时序 | MATLAB实现BP神经网络多变量时间序列预测(考虑历史特征的影响,多指标、多图输出)预测效果基本介绍程序设计学习总结参考资料预测效果 基本介绍 MATLAB实现BP神经网…

Java中的Reflection(反射)、暴力反射

文章目录 1. 反射(Reflection)的概念1.1 反射的出现背景1.2 反射概述1.3 Java反射机制研究及应用1.4 反射相关的主要API1.5 反射的优缺点 2. Class类并获取Class实例2.1 理解Class2.1.1 理论上2.1.2 内存结构上 2.2 获取Class类的实例(四种方法)2.3 哪些类型可以有Class对象2.4…

Windows安装rabbitmq

Windows安装rabbitmq 一、下载1、下载erlang2、下载rabbitmq 二、安装1、安装erlang2、安装rabbitmq3、简单使用 一、下载 1、下载erlang 点击右侧下载地址&#xff0c;跳转下载&#xff0c;点击下载 跳转后&#xff0c;点击download windows install即可下载。 2、下载rab…

微服务---分布式缓存redis进阶-redis集群部署

分布式缓存 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; 0.学习目标 1.Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xf…

基于Kali搭建SSH弱口令靶机并用Nmap实现排查

前言正文1、为宿主主机配置nmap环境变量2、为宿主主机和靶机配置同一局域网环境3、为靶机配置弱口令4、为靶机配置SSH服务[^2]5、主机用Nmap对靶机进行扫描5、主机用弱口令工具对靶机渗透6、验证弱口令 参考文献 前言 有时候&#xff0c;需要我们搭建SSH弱口令环境&#xff0c…

【数据结构】超详细之单向链表(C语言实现)

文章目录 前言一、单向链表是什么&#xff1f;二、单向链表实现步骤 1.打印链表数据以及实现链表头插2.实现链表尾插3.实现链表头删尾删4.实现链表查找5.实现链表在pos之前/之后插入6.实现链表删除pos位置的值7.实现链表删除pos之后位置的值总结 前言 今天我要介绍单向链表&am…

可变参数列表的使用与原理

序言 我们自己编写的函数通常参数是固定的&#xff0c;这样使得某些功能不能得到我们想要的结果&#xff0c;比如我们想求出2个数的最大值的代码不能用于求处3个数的最大值&#xff0c;因此&#xff0c;C语言定义了可变参数列表来编写参数个数不确定的函数。具有可变参数列表的…

Golang每日一练(leetDay0054)

目录 157. 用 Read4 读取 N 个字符 Read-n-characters-given-read4 &#x1f31f;&#x1f31f; 158. 用 Read4 读取 N 个字符 II Read-n-characters-given-read4-ii-call-multiple-times II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Gol…

拿捏SQL:以“统计连续登录天数超过3天的用户“为例拿捏同类型SQL需求

文章目录 [TOC](文章目录) 一、介绍案例&#xff1a;以"统计连续登录天数超过3天的用户"为需求。数据准备方案1&#xff1a;常规思路针对对数据user_id分组&#xff0c;根据用户的活动日期排序用登录日期与rn求date_sub&#xff0c;得到的差值日期如果是相等的&#…

Python非线性回归预测模型实验完整版

非线性回归预测模型 实验目的 通过非线性回归预测模型&#xff0c;掌握预测模型的建立和应用方法&#xff0c;了解非线性回归模型的基本原理 实验内容 非线性回归预测模型 实验步骤和过程 (1)第一步&#xff1a;学习非线性回归预测模型相关知识。 非线性回归预测模型是指…

Spring框架中的单例Beans是线程安全的么?

在Spring框架中&#xff0c;单例Beans默认是线程安全的。 当你在Spring框架中声明一个单例Bean并配置为默认的单例作用域时&#xff0c;Spring会确保对该Bean的并发访问是线程安全的。以下是一个简单的代码演示&#xff1a; 假设我们有一个名为 SingletonBean 的单例 Bean 类…

Mysql目录结构

一、目录结构 <1> 主要目录结构 find / -name mysql<2> 数据库文件目录 目录&#xff1a;/var/lib/mysql/ 配置方式&#xff1a;show variables like ‘datadir’; <3> 相关命令目录 目录&#xff1a;/usr/bin&#xff08;mysqla…