第 2 章 线性表(线性表的动态分配顺序存储结构实现)

news2024/11/26 18:41:21

1. 背景说明

线性表(linear Iist)是最常用且最简单的一种数据结构。简言之,一个线性表是 n 个数据元素的有限序列。

至于每个数据元素的具体含义,在不同的情况下各不相同,它可以是一个数或一个符号,也可以是一页书,甚至其他更复杂的信息。

2. 示例代码

1) status.h

/* DataStructure 预定义常量和类型头文件 */

#ifndef STATUS_H
#define STATUS_H

/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define INFEASIABLE    		   	2			/* 返回值未知 */
#define ERR_MEMORY     		   	3			/* 访问内存错 */
#define ERR_NULL_PTR   			4			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		5			/* 内存分配错 */
#define ERR_NULL_STACK			6			/* 栈元素为空 */
#define ERR_PARA				7			/* 函数参数错 */
#define ERR_OPEN_FILE			8			/* 打开文件错 */
#define ERR_NULL_QUEUE			9			/* 队列为空错 */
#define ERR_FULL_QUEUE			10			/* 队列为满错 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */

#endif // !STATUS_H

2) dynSqList.h

/* 线性表的动态分配顺序存储结构头文件 */

#ifndef DYNSQLIST_H
#define DYNSQLIST_H

#include "status.h"

#define LIST_INIT_SIZE 10 			/* 线性表存储空间的初始分配量 */
#define LISTINCREMENT 2 			/* 线性表存储空间的分配增量 */

typedef int ElemType;

typedef struct {
	ElemType *elem;					/* 存储空间基址 */
	int length;						/* 当前长度 */
	int listSize;					/* 当前分配的存储容量(以 sizeof(ElemType) 为单位) */
} SqList;

/* 算法 2.3, 操作结果:构造一个空的顺序线性表 */
Status InitList(SqList *L);

/* 初始条件:顺序线性表 L 已存在。操作结果:销毁顺序线性表 L */
Status DestroyList(SqList *L);

/* 初始条件:顺序线性表 L 已存在。操作结果:将 L 重置为空表 */
Status ClearList(SqList *L);

/* 初始条件:顺序线性表 L 已存在。操作结果:若 L 为空表,则返回 TRUE,否则返回 FALSE */
Bollean ListEmpty(SqList L);

/* 初始条件:顺序线性表 L 已存在。操作结果:返回 L 中数据元素个数 */
int ListLength(SqList L);

/* 初始条件:顺序线性表 L 已存在,1 ≤ i ≤ ListLength(L)
   操作结果:用 e 返回 L 中第 i 个数据元素的值 */
Status GetElem(SqList L, int i, ElemType *e);

/* 算法 2.6, 初始条件:顺序线性表 L 已存在,compare() 是数据元素判定函数(满足为 1,否则为 0)
   操作结果:返回 L 中第 1 个与 e 满足关系 compare() 的数据元素的位序
   若这样的数据元素不存在,则返回值为 0 */
int LocateElem(SqList L, ElemType e, Status(*compare)(ElemType, ElemType));

/* 初始条件:顺序线性表 L 已存在
   操作结果:若 cur_e 是 L 的数据元素,且不是第一个,则用 pre_e 返回它的前驱
   否则操作失败,pre_e 无定义 */
Status PriorElem(SqList L, ElemType cur_e, ElemType *pre_e);

/* 初始条件:顺序线性表 L 已存在
   操作结果:若 cur_e 是 L 的数据元素,且不是最后一个,则用 next_e 返回它的后继
   否则操作失败,next_e 无定义 */
Status NextElem(SqList L, ElemType cur_e, ElemType *next_e);

/* 算法 2.4,初始条件:顺序线性表 L 已存在,1 ≤ i ≤ ListLength(L) + 1
   操作结果:在 L 中第 i 个位置之前插入新的数据元素 e,L 的长度加 1 */
Status ListInsert(SqList *L, int i, ElemType e);

/* 算法 2.5,初始条件:顺序线性表 L 已存在,1 ≤ i ≤ ListLength(L)
   操作结果:删除 L 的第 i 个数据元素,并用 e 返回其值,L 的长度减 1 */
Status ListDelete(SqList *L, int i, ElemType *e);

/* 初始条件:顺序线性表 L 已存在
   操作结果:依次对 L 的每个数据元素调用函数 vi()。一旦 vi() 失败,则操作失败
   vi() 的形参加 '&',表明可通过调用 vi() 改变元素的值 */
Status ListTraverse(SqList L, void(*vi)(ElemType*));

#endif // !DYNSQLIST_H

3) dynSqList.c

#include "dynSqList.h"
#include <stdlib.h>
#include <stdio.h>

/* 算法 2.3, 操作结果:构造一个空的顺序线性表 */
Status InitList(SqList *L)
{
	(*L).elem = (ElemType*)malloc(sizeof(ElemType) * LIST_INIT_SIZE);
	if (!(*L).elem) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return ERR_MEMORY_ALLOCATE;
	}

	(*L).length = 0;
	(*L).listSize = LIST_INIT_SIZE;

	return RET_OK;
}

/* 初始条件:顺序线性表 L 已存在。操作结果:销毁顺序线性表 L */
Status DestroyList(SqList *L)
{
	free((*L).elem);
	(*L).length = 0;
	(*L).listSize = 0;

	return RET_OK;
}

/* 初始条件:顺序线性表 L 已存在。操作结果:将 L 重置为空表 */
Status ClearList(SqList *L)
{
	(*L).length = 0;

	return RET_OK;
}

/* 初始条件:顺序线性表 L 已存在。操作结果:若 L 为空表,则返回 TRUE,否则返回 FALSE */
Bollean ListEmpty(SqList L)
{
	return (L.length == 0) ? TRUE : FALSE;
}

/* 初始条件:顺序线性表 L 已存在。操作结果:返回 L 中数据元素个数 */
int ListLength(SqList L)
{
	return L.length;
}

/* 初始条件:顺序线性表 L 已存在,1 ≤ i ≤ ListLength(L)
   操作结果:用 e 返回 L 中第 i 个数据元素的值 */
Status GetElem(SqList L, int i, ElemType *e)
{
	if (i < 1 || i > L.length) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_PARA);
		return ERR_PARA;
	}

	*e = *(L.elem + i - 1);

	return RET_OK;
}

/* 算法 2.6, 初始条件:顺序线性表 L 已存在,compare() 是数据元素判定函数(满足为 1,否则为 0)
   操作结果:返回 L 中第 1 个与 e 满足关系 compare() 的数据元素的位序
   若这样的数据元素不存在,则返回值为 0 */
int LocateElem(SqList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
	ElemType *p = L.elem;
	int i = 1;
	while (i <= L.length && !compare(*p++, e)) {
		++i;
	}

	return (i <= L.length) ? i : 0;
}

/* 初始条件:顺序线性表 L 已存在
   操作结果:若 cur_e 是 L 的数据元素,且不是第一个,则用 pre_e 返回它的前驱
   否则操作失败,pre_e 无定义 */
Status PriorElem(SqList L, ElemType cur_e, ElemType *pre_e)
{
	ElemType *p = L.elem + 1;
	int i = 2;
	while (i++ <= L.length && *p++ != cur_e);
	if (i > L.length) {
		return INFEASIABLE;
	}
	
	*pre_e = *(--p);

	return RET_OK;
}

/* 初始条件:顺序线性表 L 已存在
   操作结果:若 cur_e 是 L 的数据元素,且不是最后一个,则用 next_e 返回它的后继
   否则操作失败,next_e 无定义 */
Status NextElem(SqList L, ElemType cur_e, ElemType *next_e)
{
	ElemType *p = L.elem;
	int i = 1;
	while (i < L.length && *p != cur_e) {
		++i;
		++p;
	}

	if (i == L.length) {
		return INFEASIABLE;
	}

	*next_e = *(++p);

	return RET_OK;
}

/* 算法 2.4,初始条件:顺序线性表 L 已存在,1 ≤ i ≤ ListLength(L) + 1
   操作结果:在 L 中第 i 个位置之前插入新的数据元素 e,L 的长度加 1 */
Status ListInsert(SqList *L, int i, ElemType e)
{
	if (i < 1 || i > (*L).length + 1) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_PARA);
		return ERR_PARA;
	}

	if ((*L).length == (*L).listSize) {
		ElemType* newBase = (ElemType*)realloc((*L).elem, (unsigned long long)((*L).listSize + LISTINCREMENT) * sizeof(ElemType));
		if (!newBase) {
			printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
			return ERR_MEMORY_ALLOCATE;
		}

		(*L).elem = newBase;
		(*L).listSize += LISTINCREMENT;
	}

	ElemType *q = (*L).elem + i - 1;
	for (ElemType* p = (*L).elem + (*L).length - 1; p >= q; --p) {
		*(p + 1) = *p;
	}

	*q = e;
	++(*L).length;

	return RET_OK;
}

/* 算法 2.5,初始条件:顺序线性表 L 已存在,1 ≤ i ≤ ListLength(L)
   操作结果:删除 L 的第 i 个数据元素,并用 e 返回其值,L 的长度减 1 */
Status ListDelete(SqList *L, int i, ElemType *e)
{
	if (i < 1 || (*L).length) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_PARA);
		return ERR_PARA;
	}

	ElemType *p = (*L).elem + i - 1;
	*e = *p;
	ElemType* q = (*L).elem + (*L).length - 1;
	for (++p; p <= q; ++p) {
		*(p - 1) = *p;
	}

	--(*L).length;

	return RET_OK;
}

/* 初始条件:顺序线性表 L 已存在
   操作结果:依次对 L 的每个数据元素调用函数 vi()。一旦 vi() 失败,则操作失败
   vi() 的形参加 '&',表明可通过调用 vi() 改变元素的值 */
Status ListTraverse(SqList L, void(*vi)(ElemType*))
{
	ElemType *p = L.elem;
	for (int i = 1; i <= L.length; ++i) {
		vi(p++);
	}

	return RET_OK;
}

4) algorithm.h

/* 算法实现头文件 */

#ifndef ALGORITHM_H
#define ALGORITHM_H

#include "auxiliary.h"

/* 算法 2.1,将所有在线性表 Lb 中但不在 La 中的数据元素插入到 La 中 */
void Union(SqList *La, SqList Lb);

/* 算法 2.2,已知线性表 La 和 Lb 中的数据元素按值非递减排列
   归并 La 和 Lb 得到新的线性表 Lc, Lc 的数据元素也按值非递减排列 */
void MergeList(SqList La, SqList Lb, SqList *Lc);

/* 算法 2.7,已知顺序线性表 La 和 Lb 的元素按值非递减排列
   归并 La 和 Lb 得到新的顺序线性表 Lc, Lc 的元素也按值非递减排列 */
void MergeList2(SqList La, SqList Lb, SqList *Lc);

/* 另一种合并线性表的方法(根据算法 2.7 下的要求修改算法 2.7) */
void MergeList3(SqList La, SqList Lb, SqList *Lc);

#endif // !ALGORITHM_H

5) algorithm.c

/* 算法实现源文件 */

#include "algorithm.h"
#include <stdio.h>
#include <stdlib.h>

/* 算法 2.1,将所有在线性表 Lb 中但不在 La 中的数据元素插入到 La 中 */
void Union(SqList *La, SqList Lb)
{
	int laLength = ListLength(*La);
	int lbLength = ListLength(Lb);
	ElemType e;
	for (int i = 1; i <= lbLength; ++i) {
		if (GetElem(Lb, i, &e) == RET_OK) {
			if (!LocateElem(*La, e, Equal)) {
				ListInsert(La, ++laLength, e);
			}
		}
	}
}

/* 算法 2.2,已知线性表 La 和 Lb 中的数据元素按值非递减排列
   归并 La 和 Lb 得到新的线性表 Lc, Lc 的数据元素也按值非递减排列 */
void MergeList(SqList La, SqList Lb, SqList *Lc)
{
	int ret = InitList(Lc);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return;
	}

	int laLength = ListLength(La);
	int lbLength = ListLength(Lb);
	InitList(Lc);
	int i = 1, j = 1, k = 0;
	ElemType ai, bj;
	while (i <= laLength && j <= lbLength) {
		(void)GetElem(La, i, &ai);
		(void)GetElem(Lb, j, &bj);
		if (ai <= bj) {
			(void)ListInsert(Lc, ++k, ai);
			++i;
		}
		else {
			(void)ListInsert(Lc, ++k, bj);
			++j;
		}
	}

	while (i <= laLength) {
		(void)GetElem(La, i++, &ai);
		(void)ListInsert(Lc, ++k, ai);
	}

	while (j <= lbLength) {
		(void)GetElem(Lb, j++, &bj);
		(void)ListInsert(Lc, ++k, bj);
	}
}

/* 算法 2.7,已知顺序线性表 La 和 Lb 的元素按值非递减排列
   归并 La 和 Lb 得到新的顺序线性表 Lc, Lc 的元素也按值非递减排列 */
void MergeList2(SqList La, SqList Lb, SqList *Lc)
{
	(*Lc).listSize = (*Lc).length = La.length + Lb.length;
	ElemType *pc = (*Lc).elem = (ElemType*)malloc((*Lc).listSize * sizeof(ElemType));
	if (!(*Lc).elem) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return;
	}

	ElemType *pa = La.elem;
	ElemType *pb = Lb.elem;
	ElemType *pa_last = La.elem + La.length - 1;
	ElemType *pb_last = Lb.elem + Lb.length - 1;
	while (pa <= pa_last && pb <= pb_last) {
		if (*pa <= *pb) {
			*pc++ = *pa++;
		}
		else {
			*pc++ = *pb++;
		}
	}

	while (pa <= pa_last) {
		*pc++ = *pa++;
	}

	while (pb <= pb_last) {
		*pc++ = *pb++;
	}
}

/* 另一种合并线性表的方法(根据算法 2.7 下的要求修改算法 2.7) */
void MergeList3(SqList La, SqList Lb, SqList *Lc)
{
	(*Lc).listSize = La.length + Lb.length;
	ElemType *pc = (*Lc).elem = (ElemType*)malloc((*Lc).listSize * sizeof(ElemType));
	if (!(*Lc).elem) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_MEMORY_ALLOCATE);
		return;
	}

	ElemType *pa = La.elem;
	ElemType *pb = Lb.elem;
	ElemType *pa_last = La.elem + La.length - 1;
	ElemType *pb_last = Lb.elem + Lb.length - 1;
	while (pa <= pa_last && pb <= pb_last) {
		switch (Comp(*pa, *pb)) {
			case  0: pb++;
			case -1: *pc++ = *pa++;
					 break;
			case  1: *pc++ = *pb++;
		}
	}

	while (pa <= pa_last) {
		*pc++ = *pa++;
	}

	while (pb <= pb_last) {
		*pc++ = *pb++;
	}

	(*Lc).length = pc - (*Lc).elem;
}

6) auxiliary.h

/* 辅助函数头文件 */

#ifndef AUXILIARY_H
#define AUXILIARY_H

#include "status.h"
#include "dynSqList.h"

/* 判断两个元素是否相等 */
Status Equal(ElemType e1, ElemType e2);

/* 打印元素 */
void Print(ElemType *e);

/* 比较元素大小 */
int Comp(ElemType e1, ElemType e2);

/* 判断元素之间是否存在平方关系 */
Status compSquare(ElemType e1, ElemType e2);

/* 使元素值加倍 */
void doubleElem(ElemType *e);

#endif // !AUXILIARY_H

7) auxiliary.c

/* 辅助函数实现源文件 */

#include "auxiliary.h"
#include <stdio.h>

/* 判断两个元素是否相等 */
Status Equal(ElemType e1, ElemType e2)
{
	return (e1 == e2) ? TRUE : FALSE;
}

/* 打印元素 */
void Print(ElemType *e)
{
	printf("%d ", *e);
}

/* 比较元素大小 */
int Comp(ElemType e1, ElemType e2)
{
	return (e1 == e2) ? 0 : ((e1 < e2) ? -1 : 1);
}

/* 判断元素之间是否存在平方关系 */
Status compSquare(ElemType e1, ElemType e2)
{
	return (e1 == e2 * e2) ? TRUE : FALSE;
}

/* 使元素值加倍 */
void doubleElem(ElemType *e)
{
	*e *= 2;
}

8) main.c

/* 入口程序源文件 */

#include "algorithm.h"
#include <stdio.h>

int main(void)
{
	/* 算法 2.1 测试 */
	SqList La;
	int ret = InitList(&La);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	for (int i = 0; i < 5; ++i) {
		ret = ListInsert(&La, i + 1, i + 1);
		if (ret != RET_OK) {
			printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
			return ret;
		}
	}

	printf("La: ");
	ret = ListTraverse(La, Print);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	printf("\n");

	SqList Lb;
	ret = InitList(&Lb);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	for (int i = 1; i <= 5; ++i) {
		ret = ListInsert(&Lb, i, 2 * i);
		if (ret != RET_OK) {
			printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
			return ret;
		}
	}

	printf("Lb: ");
	ret = ListTraverse(Lb, Print);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	printf("\n");

	Union(&La, Lb);										/* 或 MergeList3(La, Lb, &Ld) */
	printf("La: ");
	ret = ListTraverse(La, Print);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	printf("\n");

	/* 算法 2.2 、2.3 测试 */
	SqList Lc;
	MergeList(La, Lb, &Lc);								/* 或 MergeList2(La, Lb, &Lc) */
	printf("Lc: ");
	ret = ListTraverse(Lc, Print);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	printf("\n");

	/* 基本操作测试 */
	
	/* 求第一个满足条件是 2 的平方的数的位置 */
	int index = LocateElem(Lc, 2, compSquare);
	printf("index = %d\n", index);

	/* 依次对元素加倍并遍历元素 */
	ret = ListTraverse(Lc, doubleElem);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	printf("Lc: ");
	ret = ListTraverse(Lc, Print);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	printf("\n");
	
	/* 销毁线性表 */
	ret = DestroyList(&La);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	ret = DestroyList(&Lb);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
		return ret;
	}

	ret = DestroyList(&Lc);
	if (ret != RET_OK) {
		printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ret);
	}

	return ret;
}

3. 输出示例

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

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

相关文章

千粉福利——— ubuntu安装

&#xff08;一&#xff09;配置虚拟机&#xff0c;首先打开虚拟机 点击创建新的虚拟机或者左上角文件->新建虚拟机&#xff0c;或者使用快捷键CtrlN,选择自定义安装 选择虚拟机就硬件兼容性&#xff0c;默认点击下一步就好 安装客户机操作系统&#xff1a;选择稍后安装操作…

tensorflow QAT

tensorflow qat https://www.wpgdadatong.com/tw/blog/detail/70672 在边缘运算的重点技术之中&#xff0c;除了简化复杂的模块构架&#xff0c;来简化参数量以提高运算速度的这项模块轻量化网络构架技术之外。另一项技术就是各家神经网络框架&#xff08;TensorFlow、Pytorc…

Day7:浅谈useEffect

「目标」: 持续输出&#xff01;每日分享关于web前端常见知识、面试题、性能优化、新技术等方面的内容。 Day7-今日话题 useEffect 是 React 中一个非常重要的 Hook&#xff0c;用于处理副作用和订阅外部数据源的变化。它可以在函数式组件中执行各种操作&#xff0c;例如数据获…

小程序如何上传微信聊天记录的文件

wx.chooseMessageFile({count: 10,type: image,success (res) {// tempFilePath可以作为img标签的src属性显示图片const tempFilePaths res.tempFiles} })参数说明 回调函数说明

数据库实现学生管理系统

1.QT将数据库分为三个层次&#xff1a; 1> 数据库驱动层&#xff1a;QSqlDriver、QSqlDriverCreator、QSqlDriverCreatorBase、QSqlDriverPlugin 2> sql接口层&#xff1a;QSqlDatabase、QSqlQuery、QSqlRecord、QSqlError 3> 用户接口层&#xff1a;提供一些模型QSql…

开眼“观天”,从墨迹天气服贸会之旅看气象服务新未来

今年夏天&#xff0c;天气焦人。先是高温早早上线&#xff0c;然后台风来势汹汹&#xff0c;北京高温、河北暴雨&#xff0c;杜苏芮、苏拉、海葵轮番“奔袭”&#xff0c;极端气象事件频繁登上热搜&#xff0c;其险象环生的过程&#xff0c;让大众对气候问题的关注度节节走高。…

架构师 软件测试

架构师 软件测试 目录概述需求&#xff1a; 设计思路实现思路分析1.软件测试方法 软件测试工具 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for c…

cudnn-windows-x86_64-8.6.0.163_cuda11-archive 下载

网址不太好访问的话,请从下面我提供的分享下载 Download cuDNN v8.6.0 (October 3rd, 2022), for CUDA 11.x 此资源适配 cuda11.x 将bin和include文件夹里的文件&#xff0c;分别复制到C盘安装CUDA目录的对应文件夹里 安装cuda时自动设置了 CUDA_PATH_V11_8 及path C:\Progra…

1123. 最深叶节点的最近公共祖先

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;递归 写在最后 Tag 【递归】【最近公共祖先】【二叉树】 题目来源 1123. 最深叶节点的最近公共祖先&#xff0c;865. 具有所有最深节点的最小子树 此二题系重复的题目。 题目解读 题目意思很明确&#xff0c;找出二叉…

String类的常用方法(Java)

目录 一、字符串构造二、String对象的比较1、比较是否引用同一个对象2、boolean equals(Object anObject) 方法&#xff1a;按照字典序比较3、int compareTo(String s) 方法: 按照字典序进行比较4、int compareToIgnoreCase(String str) 方法&#xff1a;与compareTo方式相同&a…

SpringMVC相对路径和绝对路径

1.相对地址与绝对地址定义 在jsp&#xff0c;html中使用的地址&#xff0c;都是在前端页面中的地址&#xff0c;都是相对地址 地址分类&#xff1a;&#xff08;1&#xff09;&#xff0c;绝对地址&#xff0c;带有协议名称的是绝对地址&#xff0c;http://www.baidu.com&…

c语言练习41:深入理解字符串函数strlen strcpy strcat

深入理解字符串函数strlen strcpy strcat 模拟实现&#xff1a;”strlen strcpy strcat strlen strcat: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<assert.h> strlen 1.通过指针移动模拟 //int my_strlen(char* str) { // size_t c…

Unity之创建第一个游戏

一 Unity环境配置 1.1 Untity资源官网下载&#xff1a;https://unity.cn/releases 1.2 Unity Hub集成环境&#xff0c;包含工具和项目的管理 1.3 Unity Editor编辑器 1.4 Visual Studio 2022脚本编辑器 1.5 AndroidSKD&#xff0c;JDK&#xff0c;NDK工具&#xff0c;用于and…

Python之写文件操作(二十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

长风破浪会有时,直挂云帆济沧海!(工作室年会总结)

前言 我也是有段时间没写过总结性的博客了。最近是很忙的&#xff0c;尤其是年会那两天&#xff0c;我甚至可以说这是我这辈子目前最忙的两天。但这段经历还是很值得我记录下来的&#xff0c;也是给后面有需要的人提供的一些建议。我个人也是第一次筹办这种大型些的活动&#x…

SpringBoot_第六章(知识点总结)

目录 1&#xff1a;拦截器(Interceptor) 1.1&#xff1a;拦截器代码实现 1.2&#xff1a;拦截器源码分析和流程总结 2&#xff1a;过滤器(Filter)、自定义(Servlet)、监听器(Listener) 3&#xff1a;文件上传 3.1&#xff1a;文件上传代码实现 3.2&#xff1a;文件上传源…

部署Redis集群

文章目录 部署Redis集群1. 准备集群主机2. 启用集群功能3. 配置管理主机并创建集群3.1 配置管理主机 192.168.88.573.2 创建集群创建集群命令创建集群失败解决办法 3.3 查看集群信息查看集群统计信息查看集群详细信息 4. **测试集群及集群工作原理**4.1. 访问集群存取数据4.2 *…

Jmeter进阶使用指南-使用参数化

Apache JMeter是一个广泛使用的开源负载和性能测试工具。在进行性能测试时&#xff0c;我们经常需要模拟不同的用户行为和数据&#xff0c;这时候&#xff0c;参数化就显得尤为重要。此文主要介绍如何在JMeter中使用参数化。 什么是参数化&#xff1f; 参数化是一种将静态值替…

OpenCV之ellipse函数

ellipse函数用来在图片中绘制椭圆、扇形&#xff0c;有两个重载函数。 函数原型1&#xff1a; void cv::ellipse( InputOutputArray img,Point center,Size axes,double angle,double startAngle,double …

ORB-SLAM2算法14之局部建图线程Local Mapping

文章目录 0 引言1 概述2 处理队列中的关键帧3 剔除坏的地图点4 创建新地图点5 融合当前关键帧和其共视帧的地图点6 局部BA优化7 剔除冗余关键帧 0 引言 ORB-SLAM2算法7详细了解了System主类和多线程、ORB-SLAM2学习笔记8详细了解了图像特征点提取和描述子的生成、ORB-SLAM2算法…