C 数据结构1 —— 线性表-顺序表\单链表\双链表

news2024/5/18 18:59:15

文章目录

  • 1. 线性表
    • 1.1 定义
    • 1.2 特点
  • 2. 顺序表(顺序存储结构)
    • 2.1 定义(存储结构代码描述)
    • 2.2 插入元素
      • 2.2.1 图形演示
      • 2.2.2 代码表示
    • 2.3 删除元素
      • 2.3.1 图形演示
      • 2.3.2 代码表示
    • 2.4 完整代码
    • 2.5 动态分配数组
  • 3. 单链表(链式存储结构)
    • 3.1 定义(存储结构代码描述)
    • 3.2 单链表的读取
    • 3.3 单链表的插入
      • 3.4.0 插入第i位
      • 3.3.1 头插法
      • 3.3.2 尾插法
    • 3.4 单链表的查找
      • 3.4.1 按序号查找
      • 3.4.2 按值查找
    • 3.5 单链表的删除
    • 3.6 完整代码
  • 4. 双链表
    • 4.1 定义
    • 4.2 双链表的插入
      • 4.2.0 插入第i位
      • 4.2.1 头插法
      • 4.2.2 尾插法
    • 4.3 双链表的查找
    • 4.4 双链表的删除

1. 线性表

1.1 定义

在这里插入图片描述

1.2 特点

在这里插入图片描述

2. 顺序表(顺序存储结构)

2.1 定义(存储结构代码描述)

  • 线性表的顺序存储:指的是用一段地址连续的存储单元依次存储线性表的数据结构
  • 使用一维数组来实现顺序存储结构
  • 顺序表存储的结构代码如下:
#define MAXSIZE 20		// 存储空间初始分配量, 表示最大存储容量
typedef int ElemType;	// ElemType类型根据实际情况而定,这里为int
typedef struct
{
	ElemType data[MAXSIZE];// 数组,存储数据元素
	int length;			// 线性表当前长度
}SqList;

在这里插入图片描述

  • 优缺点
    在这里插入图片描述
  • 数组长度和线性表长度的区别
  • 数组长度是存储线性表空间的长度
  • 线性表的长度是线性表中数据元素的个数,随着线性表插入和删除的进行,量是变化的

2.2 插入元素

2.2.1 图形演示

在这里插入图片描述

2.2.2 代码表示

  • 在L中第i个位置之前插入新的数据元素e,L的长度加1
    在这里插入图片描述
// 1.插入元素
// i代表插入的位置,从1开始(就是从第2个位置开始),到L.length结束(插入到最后),e表示要插入的元素
bool ListInsert(SqList& L, int i, ElemType e)
{
	if (i<1 || i>L.length + 1)// 判断要插入的位置是否合法
		return false;
	if (L.length >= MaxSize)// 元素储存满了,不能再存了
		return false;
	for (int j = L.length; j >= i; j--)// 移动顺序表中的元素,依次往后移动
	{
		L.data[j] = L.data[j - 1];// 最后将原来i-1的位置移动到i,空出来i-1的位置
	}
	L.data[i - 1] = e;// 数组下表从零开始,插入第一个位置,访问下标为0
	L.length++;
	return true;// 走到这里代表插入成功,返回true
}
  • 大话数据结构 —— 顺序存储结构的插入操作
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(SqList *L,int i,ElemType e)
{ 
	if (L->length == MAXSIZE)  /* 顺序线性表已经满 */
		return ERROR;
	if (i < 1 || i > L->length + 1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */
		return ERROR;

	if (i <= L->length)        /* 若插入数据位置不在表尾 */
	{
		for(int k = L->length;k >= i;k--)  /* 将要插入位置之后的数据元素向后移动一位 */
			L->data[k] = L->data[k-1];
	}
	L->data[i-1] = e;          /* 将新元素插入 */
	L->length++;

	return OK;
}

2.3 删除元素

2.3.1 图形演示

在这里插入图片描述

2.3.2 代码表示

在这里插入图片描述

  • 删除操作,删除的元素e是需要加符号
// 2.删除元素
// 删除使用元素e的引用的目的是拿出对应值
bool ListDelete(SqList& L, int i, ElemType& e)// 这里和上面不同在于e有&,因为e的值会修改
{
	if (i<1 || i>L.length)// 如果删除的位置是不合法的
		return false;
	if (L.length == 0)// 顺序表中没有元素,无需删除
	{
		return false;
	}
	e = L.data[i - 1];// 获取顺序表中的元素,赋值给e
	for (int j = i; j < L.length; j++)// 从i的位置依次把元素往前覆盖
	{
		L.data[j - 1] = L.data[j];
	}
	L.length--;// 删除一个元素,顺序表长度减1
	return true;
}
  • 大话数据结构 —— 删除操作
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(SqList *L,int i,ElemType *e) // 这里的e是需要修改的,加了指针符号 
{ 
    if (L->length == 0)               /* 线性表为空 */
		return ERROR;
    if (i < 1 || i > L->length)         /* 删除位置不正确 */
        return ERROR;
    *e = L->data[i-1];
    if (i<L->length)                /* 如果删除不是最后位置 */
    {
        for(int k = i;k < L->length;k++)/* 将删除位置后继元素前移 */
			L->data[k-1]=L->data[k];
    }
    L->length--;
    return OK;
}

2.4 完整代码

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

#define MaxSize 50
typedef int ElemType;// 定义int的别名为ElemType,顺序表中元素的类型

// 静态分配
typedef struct
{
	ElemType data[MaxSize];// 定义的数组,用来存元素
	int length;// 当前顺序表中有多少个元素
}SqList;

// 1.插入元素
// i代表插入的位置,从1开始(就是从第2个位置开始),到L.length结束(插入到最后),e表示要插入的元素
bool ListInsert(SqList& L, int i, ElemType e)
{
	if (i<1 || i>L.length + 1)// 判断要插入的位置是否合法
		return false;
	if (L.length >= MaxSize)// 元素储存满了,不能再存了
		return false;
	for (int j = L.length; j >= i; j--)// 移动顺序表中的元素,依次往后移动
	{
		L.data[j] = L.data[j - 1];// 最后一个元素j-1往前赋值
	}
	L.data[i - 1] = e;// 数组下表从零开始,插入第一个位置,访问下标为0
	L.length++;
	return true;// 走到这里代表插入成功,返回true
}

// 2.删除元素
// 删除使用元素e的引用的目的是拿出对应值
bool ListDelete(SqList& L, int i, ElemType& e)// 这里和上面不同在于e有&,因为e的值会修改
{
	if (i<1 || i>L.length)// 如果删除的位置是不合法的
		return false;
	if (L.length == 0)// 顺序表中没有元素,无需删除
	{
		return false;
	}
	e = L.data[i - 1];// 获取顺序表中的元素,赋值给e
	for (int j = i; j < L.length; j++)// 从i的位置依次把元素往前覆盖
	{
		L.data[j - 1] = L.data[j];
	}
	L.length--;// 删除一个元素,顺序表长度减1
	return true;
}

// 3.查找元素
int LocateElem(SqList L, ElemType e)
{
	int i;
	for (i = 0; i < L.length; i++)// 遍历顺序表
	{
		if (L.data[i] == e)
			return i + 1;// 加1就是元素在顺序表中的位置
	}
	return 0;
}

// 打印顺序表元素
void PrintList(SqList& L)
{
	for (int i = 0; i < L.length; i++)
	{
		printf("%3d", L.data[i]);// 要求所有元素打印到一排,默认向右靠齐
	}
	printf("\n");
}

int main()
{
	SqList L;// L是顺序表名称
	bool ret;// 查看返回值,布尔类型是True,或者False
	ElemType del;// 用来存要删除的元素
	// 首先手动在顺序表中前3个赋值
	L.data[0] = 1;
	L.data[1] = 2;
	L.data[2] = 3;
	L.length = 3;// 总计三个元素

	ret = ListInsert(L, 2, 60);// 往第2个位置插入60这个元素
	if (ret)
	{
		printf("插入成功\n");
		PrintList(L);// 打印成功后的顺序表
	}
	else
	{
		printf("插入失败\n");
	}

	printf("\n");

	ret = ListDelete(L, 1, del);// 删除第一个位置的元素,并把元素值输出
	if (ret)
	{
		printf("删除成功\n");
		printf("删除元素值为%d\n", del);
		PrintList(L);
	}
	else 
	{
		printf("删除失败\n");
	}

	printf("\n");

	int elem_pos;
	elem_pos = LocateElem(L, 60);
	if (elem_pos)
	{
		printf("查找成功\n");
		printf("元素位置为%d\n", elem_pos);
	}
	else
	{
		printf("查找失败\n");
	}
	return 0;
}

在这里插入图片描述

2.5 动态分配数组

在这里插入图片描述

3. 单链表(链式存储结构)

3.1 定义(存储结构代码描述)

  • 头指针:指链表指向第一个结点的指针。如果链表有头结点,那么头结点就是链表第一个节点,则头指针则是指向头结点的指针
  • 头指针具有标志作用,所以常用头指针冠以链表的名字
  • 无论链表是否为空,头指针均不为空。头指针是链表的必要元素头结点不一定是链表必需元素
  • 这里L表示头指针,L->next表示头结点,L->next = NULL 表示头结点为空
  • 一般单链表名称是头指针
    在这里插入图片描述
typedef int ElemType;
typedef struct LNode// data是4个字节,指针是4个字节,一共8个字节
{
	ElemType data;
	struct LNode* next;// 指向下一个结点
}LNode,*LinkList;// LinkList等价于struct LNode *,LNode和上面相同没问题
// 结构体类型取别名为LNode, 结构体指针类型取别名为*LinkList,LNode*等价于LinkList

在这里插入图片描述

3.2 单链表的读取

  • 大话数据结构的写法
/* 初始条件:链式线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem(LinkList L,int i,ElemType *e)
{
	int j;
	LinkList p;		/* 声明一结点p */
	p = L->next;		/* 让p指向链表L的第一个结点,L->next是指第1个结点,L->next是头结点 */
	j = 1;		/*  j为计数器 */
	while (p && j<i)  /* p不为空或者计数器j还没有等于i时,循环继续 */
	{   
		p = p->next;  /* 让p指向下一个结点 */
		++j;
	}
	if ( !p || j>i ) 
		return ERROR;  /*  第i个元素不存在 */
	*e = p->data;   /*  取第i个元素的数据 */
	return OK;
}

3.3 单链表的插入

在这里插入图片描述

3.4.0 插入第i位

  • 使用单链表的查找函数
// 新结点插入第i个位置
bool ListFrontInsert(LinkList L, int i, ElemType e)
{
	LinkList p = GetElem(L, i - 1);// p指向a(i-1)的位置,拿到要插入前一个位置的地址值
	if (p = NULL)
	{
		return false;
	}
	LinkList s = (LNode*)malloc(sizeof(LNode));// 为新插入的结点申请空间,LNode*换成LinkList也可以
	s->data = e;
	s->next = p->next;
	p->next = s;// s里面是起始地址,所以让p指向s
	return true;
}

3.3.1 头插法

  • 插入链表的基本操作
    在这里插入图片描述
s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
p->next = s;          /* 将s赋值给p的后继 */

在这里插入图片描述

  • L应该理解为头指针或者是头结点,L->next是第1个结点(就是a1),这样和程序s->next = L->next就吻合了。头插法插入的节点在头结点和第1个结点之间
    在这里插入图片描述
    在这里插入图片描述
// 头插法新建链表
LinkList CreateList1(LinkList& L)// list_head_insert,加了引用&函数中的L与主函数中的L是同一个值,可以修改
{
	LNode* s;// s为结构体指针,所以用->指向成员,这里表示新插入的结点
	int x;
	L = (LinkList)malloc(sizeof(LNode));// 创建带头结点的链表L,L表示头指针
	L->next = NULL;// L->data里边没有东西,L->next是第1个结点(a1),表示L->next = NULL表示不存在
	scanf("%d", &x);// 从标准输入读取数据
	//3 4 5 6 7 9999
	while (x != 9999)
	{
		// s是不断新生成的节点,LNode*等价于LinkList
		s = (LNode*)malloc(sizeof(LNode));// 申请一个空间,强制类型转换
		s->data = x;// 把读取的值,给新空间中的data成员
		// 将L的后继结点赋值给s的后继,下一行的L->next与第二行的L->next不是一个意思
		s->next = L->next;// 让新结点的next指针指向链表的第一个元素(不是指L,而是指a1),第一个放我们数据的元素
		L->next = s;// 让s成为第1个元素,将s赋值给p的后继
		scanf("%d", &x);// 读取标准输入
	}
	return L;
}

3.3.2 尾插法

// 尾插法新建链表(r用来一直指向尾部)
LinkList CreateList2(LinkList& L)
{
	int x;
	L = (LinkList)malloc(sizeof(LNode));// 带有头结点的链表
	LNode* s, * r = L;// s与r都是结构体指针,写成LinkList s , r = L也可以;r代表链表表尾结点,指向链表尾部
	// 3 4 5 6 7 9999
	scanf("%d", &x);
	while (x != 9999)// r一直是表尾结点,s是新插入的结点
	{
		s = (LNode*)malloc(sizeof(LNode));// LNode* 和 LinkList都可以,本质是等价的
		s->data = x;
		r->next = s;// r本身就是表尾结点,让尾部结点指向新结点s,s就是不断创造出来的新结点
		r = s;// r指向新的尾插结点
		scanf("%d", &x);
	}
	r->next = NULL;// 尾结点的next指针赋值为NULL
	return L;
}

3.4 单链表的查找

3.4.1 按序号查找

  • 这里的p是一个动态的结点
    在这里插入图片描述
// 按序号查找结点,LNode* 换成LinkList也可以,两者是等价的
LNode* GetElem(LinkList L, int i)// L没有被改变,不用加引用&
{
	int j = 1;
	LNode* p = L->next;// L为头指针,让p指向第1个结点就是a1
	if (i == 0)
	{
		return L;// i为0就返回头结点
	}
	if (i < 1)
	{
		return NULL;// i是负值就返回空
	}
	while (p && j < i)
	{
		p = p->next;// p指向下一个a2
		j++;
	}
	return p;
}

3.4.2 按值查找

  • p可以理解为是地址
    在这里插入图片描述
// 按值查询
LinkList LocateElem(LinkList L, ElemType e)
{
	LinkList p = L->next;
	while (p != NULL && p->data != e)
	{
		p = p->next;
	}
	return p;
}

3.5 单链表的删除

在这里插入图片描述

// 删除第i个位置的元素
bool ListDelete(LinkList L, int i)
{
	LinkList p = GetElem(L, i - 1);// 查找删除位置的前驱结点
	if (p = NULL)// 空指针
	{
		return false;// 要删除的位置不存在
	}
	LinkList q = p->next;
	if (q == NULL)
	{
		return false;// q不存在则返回错误
	}
	p->next = q->next;// 断链
	free(q);// 释放对应结点的空间
	q = NULL;// 避免q成为野指针
	return true;// 这里不应该是false
}

3.6 完整代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>// malloc关键字

typedef int ElemType;
typedef struct LNode// data是4个字节,指针是4个字节,一共8个字节
{
	ElemType data;
	struct LNode* next;// 指向下一个结点
}LNode,*LinkList;// LinkList等价于struct LNode*,LNode和上面相同没问题
// 结构体类型取别名为LNode, 结构体指针类型取别名为*LinkList,LNode*等价于LinkList

// 为什么需要在形参的地方使用引用?
// 在子函数中去给对应的形参赋值后,子函数结束,主函数中对应的实参就发生变化。
// 如果没有使用引用,那么在子函数中给形参赋值后,子函数结束,主函数中对应的实参不会变化。

// 头插法新建链表
LinkList CreateList1(LinkList& L)// list_head_insert,加了引用&函数中的L与主函数中的L是同一个值,可以修改
{
	LNode* s;// s为结构体指针,所以用->指向成员
	int x;
	L = (LinkList)malloc(sizeof(LNode));// 创建带头结点的链表L,L表示头指针
	L->next = NULL;// L->data里边没有东西,L->next表示第1个结点
	scanf("%d", &x);// 从标准输入读取数据
	//3 4 5 6 7 9999
	while (x != 9999)
	{
		// s是不断新生成的节点,LNode*等价于LinkList
		s = (LNode*)malloc(sizeof(LNode));// 申请一个空间,强制类型转换
		s->data = x;// 把读取的值,给新空间中的data成员
		// 将L的后继结点赋值给s的后继,下一行的L->next与第二行的L->next不是一个意思
		s->next = L->next;// 让新结点的next指针指向链表的第一个元素(不是指L,而是指第1个结点a1),第一个放我们数据的元素
		L->next = s;// 让s成为第1个元素,将s赋值给p的后继
		scanf("%d", &x);// 读取标准输入
	}
	return L;
}
 
// 尾插法新建链表(r用来一直指向尾部)
LinkList CreateList2(LinkList& L)
{
	int x;
	L = (LinkList)malloc(sizeof(LNode));// 带有头结点的链表
	LNode* s, * r = L;// s与r都是结构体指针,写成LinkList s , r = L也可以;r代表链表表尾结点,指向链表尾部
	// 3 4 5 6 7 9999
	scanf("%d", &x);
	while (x != 9999)// r一直是表尾结点,s是新插入的结点
	{
		s = (LNode*)malloc(sizeof(LNode));// LNode* 和 LinkList都可以,本质是等价的
		s->data = x;
		r->next = s;// r本身就是表尾结点,让尾部结点指向新结点s,s就是不断创造出来的新结点
		r = s;// r指向新的尾插结点
		scanf("%d", &x);
	}
	r->next = NULL;// 尾结点的next指针赋值为NULL
	return L;
}

// 按序号查找结点
// LNode* 换成LinkList也可以,两者是等价的
LNode* GetElem(LinkList L, int i)// L没有被改变,不用加引用&
{
	int j = 1;
	LNode* p = L->next;// L为头结点,让p指向第1个结点就是a1
	if (i == 0)
	{
		return L;// i为0就返回头结点
	}
	if (i < 1)
	{
		return NULL;// i是负值就返回空
	}
	while (p && j < i)
	{
		p = p->next;// p指向下一个a2
		j++;
	}
	return p;
}

// 按值查询
LinkList LocateElem(LinkList L, ElemType e)
{
	LinkList p = L->next;
	while (p != NULL && p->data != e)
	{
		p = p->next;
	}
	return p;
}

// 新结点插入第i个位置
bool ListFrontInsert(LinkList L, int i, ElemType e)
{
	LinkList p = GetElem(L, i - 1);//p指向a(i-1)的位置,拿到要插入前一个位置的地址值
	if (p = NULL)
	{
		return false;
	}
	LinkList s = (LNode*)malloc(sizeof(LNode));// 为新插入的结点申请空间,LNode*换成LinkList也可以
	s->data = e;
	s->next = p->next;
	p->next = s;// s里面是起始地址,所以让p指向s
	return true;
}

// 删除第i个位置的元素
bool ListDelete(LinkList L, int i)
{
	LinkList p = GetElem(L, i - 1);// 查找删除位置的前驱结点
	if (p = NULL)// 空指针
	{
		return false;// 要删除的位置不存在
	}
	LinkList q = p->next;
	if (q == NULL)
	{
		return false;// q不存在则返回错误
	}
	p->next = q->next;// 断链
	free(q);// 释放对应结点的空间
	q = NULL;// 避免q成为野指针
	return true;// 这里不应该是false
}

// 打印链表中每个结点的值
void PrintList(LinkList L)// 这里没写引用
{
	L = L->next;// 意思是L指向第一个放数据的元素a1的位置
	while (L != NULL)// NULL就是代表一张空的藏宝图,
	{
		printf("%3d", L->data);// 打印当前结点数据
		L = L->next;// 指向下一个结点,如果有NULL的话,就截止(L真实指向的应该是结点的第二个位置)
	}
	printf("\n");
}

int main()
{
	LinkList L;// 链表头,是结构体指针类型
	LinkList search;// 用来存储拿到的某一个节点
	CreateList1(L);// 输入的数据可以为3 4 5 6 7 999
	//CreateList2(L);// 输入的数据可以为3 4 5 6 7 999
	PrintList(L);// 打印链表

	// 按照序号查找
	search = GetElem(L, 2);// 查找链表第2个位置元素的值
	if (search != NULL)
	{
		printf("按序号查找成功\n");
		printf("%d\n", search->data);
	}
	
	// 按照值来查询
	search = LocateElem(L, 6);// 按值查询
	if (search != NULL)
	{
		printf("按值查找成功\n");
		printf("%d\n", search->data);
	}

	// 插入
	ListFrontInsert(L, 2, 99);// 新结点插入第i个位置
	PrintList(L);

	// 删除
	ListDelete(L, 4);// 删除第4个结点
	PrintList(L);
}

4. 双链表

4.1 定义

// 给结构体类型起别名叫DNode, 结构体指针类型的别名叫DLinkList
// DLinkList等价于struct DNode*,即结构体指针
typedef int ElemType;
typedef struct DNode
{
	ElemType data;
	struct DNode* prior, * next;// 前驱,后继
}DNode, * DLinkList;

在这里插入图片描述

4.2 双链表的插入

在这里插入图片描述

4.2.0 插入第i位

//新结点插入第i个位置
bool DListFrontInsert(DLinkList DL, int i, ElemType e)
{
	DLinkList p = GetElem(DL, i - 1);
	if (p == NULL)
	{
		return false;
	}
	DLinkList s = (DLinkList)malloc(sizeof(DNode));//为新插入的结点申请空间
	s->data = e;
	s->next = p->next;
	p->next->prior = s;
	s->prior = p;
	p->next = s;
	return true;
}

4.2.1 头插法

//双向链表头插法
DLinkList Dlist_head_insert(DLinkList& DL)
{
	DNode* s; int x;
	DL = (DLinkList)malloc(sizeof(DNode));//带头结点的链表
	DL->next = NULL;//前驱指针和后继指针都填写为NULL
	DL->prior = NULL;
	scanf("%d", &x);//从标准输入读取数据
	//3 4 5 6 7 9999
	while (x != 9999)
	{
		s = (DLinkList)malloc(sizeof(DNode));//申请一个空间,强制类型转换
		s->data = x;
		s->next = DL->next;
		if (DL->next != NULL)//插入第1个结点时,不需要这个操作
		{
			DL->next->prior = s;
		}
		s->prior = DL;//要插入的结点指向头结点
		DL->next = s;
		scanf("%d\n", &x);
	}
}

4.2.2 尾插法

// 双向链表尾插法
DLinkList DList_tail_insert(DLinkList& DL)
{
	int x;
	DL = (DLinkList)malloc(sizeof(DNode));// 带头结点的链表
	DNode* s, * r = DL;// r代表尾指针
	DL->next = NULL;
	//3 4 5 6 7 9999
	scanf("%d", &x);
	while (x != 9999)
	{
		s = (DNode*)malloc(sizeof(DNode));
		s->data = x;
		r->next = s;
		s->prior = r;
		r = s;// r指向新的表尾结点
		scanf("%d", &x);
	}
	r->next = NULL;
	return DL;
}

4.3 双链表的查找

// 按序号查找结点值
DNode* GetElem(DLinkList DL, int i)
{
	int j = 1;
	DNode* p = DL->next;// L为头结点,让p指向第1个结点就是a1
	if (i == 0)
	{
		return DL;
	}
	if (i < 1)
	{
		return NULL;
	}
	while (p && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}

4.4 双链表的删除

在这里插入图片描述

// 删除第i个结点
bool DListDelete(DLinkList DL, int i)
{
	DLinkList p = GetElem(DL, i - 1);
	if (p == NULL)
	{
		return false;
	}
	DLinkList q;
	q = p->next;
	if (q == NULL)// 删除的元素不存在
	{
		return false;
	}
	p->next = q->next;
	if (q->next != NULL)// q的下一个元素不为空,删除的不是最后一个结点。q->next为NULL则删除的是最后一个结点
	{
		q->next->prior = p;
	}
	free(q);// 释放对应结点的空间
	return true;
}

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

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

相关文章

COCO_04 展示COCO格式数据集 目标框与分割mask

文章目录1 前言2 绘制GT2.1 绘制目标框与类别2.2 绘制分割mask3 AppendixA. mask polygon格式转化为图片格式参考1 前言 上篇文章介绍了如何制作COCO个数数据集的Dataset与Dataloader&#xff0c;并绘制了dataloader->batch的返回的信息&#xff0c;https://blog.csdn.net/…

【打卡】医学搜索Query相关性判断学习赛

入坑传送门 赛事介绍 文本匹配拥有广泛的应用场景&#xff0c;可以用于去除重复问题和文本相似度中。在本次学习中我们将学习&#xff1a; 如何计算文本之间的统计距离如何训练词向量 & 无监督句子编码BERT模型搭建和训练 上述步骤都是一个NLP算法工程师必备的基础&…

【GD32F427开发板试用】02-ADC规则组连续采样

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;Stark_GS ADC 简介及特点 器件中集成了一个 12 位 2.6 MSPS 多通道 ADC。 一共有19个多路复用通道&#xff1a;16个外部通道&#xff0c;1个…

office365删除错误发送的邮件

微软喜欢变&#xff0c;office365删个邮件真是不容易。 --管理员登录 Connect-IPPSSession -UserPrincipalName adminmydomain.onmicrosoft.com --创建一个 "deleteemail"的搜索项目&#xff0c;项目名可以任意起&#xff0c;这个名称后面在office365安全合规门户里…

libcurl简介及其编程应用

本文为学习笔记&#xff0c;整合课程内容以及下列文章&#xff1a; 其中&#xff0c;libcurl函数库常用字段解读部分&#xff1a; 参考博文&#xff1a;原文地址 作者&#xff1a;冬冬他哥哥 目录 libcurl简介 libcurl的使用 学会开源包使用的一般步骤 包的解读 重点是看…

Spark 核心编程

文章目录Spark 核心编程一、RDD1、分布式计算模拟(1) 搭建基础的架子(2) 客户端向服务器发送计算任务Spark 核心编程 Spark 计算框架为了能够进行高并发和高吞吐的数据处理&#xff0c;封装了三大数据结构&#xff0c;用于处理不同的应用场景。三大数据结构分别是&#xff1a;…

【数据结构与算法理论知识点】1.1基本概念

1.1基本概念 为什么要学习数据结构与算法&#xff1f; AlgorithmsData StructuresPrograms---- Niklaus Wirth ( Pascal程序设计语言之父、结构化程序设计首创者、图灵奖获得者) 计算机程序&#xff1a;使用计算机求解问题算法是求解问题的步骤的描述&#xff1a;从蛮力到策…

套接字编程(二)UDP服务端与客户端的通信模拟实现

目录 一、前言 二、UDP客户端流程信息 1、创建套接字 2、为套接字绑定地址信息&#xff08;不推荐&#xff09; 3、发送数据&#xff08;将数据放入发送缓冲区中&#xff09; 4、接收数据&#xff08;从socket结构体接收缓冲区中取出数据&#xff09; 5、关闭套接字 三…

机器学习基本概念及问题梳理

前言&#xff1a;整理西瓜书第一、二章中的基本概念 待办&#xff1a;第二章评估方法、性能度量及后续内容未整理 下图梳理机器学习中部分概念 模型评估与选择相关知识点&#xff1a; 错误率&#xff08;error rate, E&#xff09;&#xff1a;如果在m个样本中有a个样本分类…

WordPress安全指南:19个步骤让您的WordPress安全防线坚如磐石

谈到WordPress安全性&#xff0c;您可以采取很多措施来锁定您的网站&#xff0c;以防止黑客和漏洞影响您的电子商务网站或博客。您最不想发生的事情是一天早上醒来发现您的网站一团糟。因此&#xff0c;今天我们将分享许多技巧、策略和技术&#xff0c;您可以使用这些技巧、策略…

WEBSHELL管理工具流量特征——基础篇

前言 前一阵子帮别人做取证题目&#xff0c;有很多关于WEBSHELL的流量要分析&#xff0c;想起来还有没好好分析过于是准备写篇文章总结一下帮助大家能够快速的辨别WEBSHELL流量&#xff0c;下面我们展开文章来讲。 中国菜刀 这个应该是大家最熟悉的WEBSHELL管理工具&#xf…

NeuRay学习笔记

Neural Rays for Occlusion-aware Image-based Rendering 主页&#xff1a;https://liuyuan-pal.github.io/NeuRay/ 论文&#xff1a;https://arxiv.org/abs/2107.13421 Code&#xff1a;https://github.com/liuyuan-pal/NeuRay 效果&#xff1a; desktop摘要 We present a ne…

一文读懂 UniProt 数据库(2023 最新版)

一、UniProt 数据库介绍 Uniprot &#xff08;Universal Protein &#xff09;是包含蛋白质序列&#xff0c;功能信息&#xff0c;研究论文索引的蛋白质数据库&#xff0c;整合了包括EBI&#xff08; European Bioinformatics Institute&#xff09;&#xff0c;SIB&#xff0…

【面试题】前端最新面试题-浏览器 dom、bom篇

原文见&#xff1a;语雀&#xff08;https://www.yuque.com/deepstates/interview/fsitlt&#xff09; ● BOM ● window对象 ○ frames ■ iframe ■ 跨窗口通信 ■ 同源策略/跨域 ○ navigator ● DOM ○ DOM结构 ○ DOM操作 ○ DOM事件 ■ 表单事件 ● 浏览器渲染 ○ 进程、…

Vue组件化编程的组件通信

对于组件化编程&#xff0c;组件之间的通信技术无疑是非常重要的内容&#xff0c;需要将细节牢牢把握。 组件通信&#xff0c;就是子组件放置在父组件内之后&#xff0c;父组件如何向子组件传递参数以及子组件如何与外部组件进行互动。 这部分的知识很重要&#xff0c;需要展开…

基于Ubuntu20.04搭建OpenHarmony v3.0.6的qemu仿真环境

基于Ubuntu20.04搭建OpenHarmony v3.0.6的qemu仿真环境0. 前言1. 安装Ubuntu1.1 更换华为源1.2 安装必要工具2. 下载代码2.1 解压与目录设置3. 配置环境3.1 安装库和工具3.2 设置python版本3.3 安装编译工具hb3.4 切换dash为bash4. 编译4.1 hb构建4.2 启动qemu5. 第二种环境配置…

Java之日期与时间、JDK8新增日期类、包装类、正则表达式、Arrays类、常见算法和Lambda表达式

目录日期与时间DateSimpleDateFormatCalendar概述JDK8新增日期类概述、LocalTime /LocalDate / LocalDateTimeInstantDateTimeFormatterDuration/PeriodchronoUnit包装类正则表达式Arrays类Arrays类概述&#xff0c;常用功能演示Arrays类对于Comparator比较器的支持常见算法选择…

[论文翻译] GIKT: A Graph-based Interaction Model forKnowledge Tracing

摘要随着在线教育的快速发展&#xff0c;知识追踪&#xff08;KT&#xff09;已成为追踪学生知识状态并预测他们在新问题上的表现的基本问题。在线教育系统中的问题通常很多&#xff0c;并且总是与更少的技能相关联。然而&#xff0c;以往的文献未能将问题信息与高阶问题-技能相…

计网必会:电路交换和分组交换

电路交换和分组交换的概念和区别&#xff0c;为什么分组交换更有效&#xff1f; 电路交换&#xff1a;由于电路交换在通信之前要在通信双方之间建立一条被双方独占的物理通路&#xff08;由通信双方之间的交换设备和链路逐段连接而成&#xff09; 特点是源和目标点建立起名副其…

C语言中的void*是什么?

目录1.void *是什么2.void*的解引用3.void*类型的应用场景1.void *是什么 我们之前学过许多类型的指针变量&#xff0c;如整形指针&#xff0c;字符指针&#xff0c;甚至数组指针&#xff0c;函数指针等。 int a 10; int *pa &a;//整形指针pa接受一个整形变量a的地址但…