数据结构(ing)

学习内容 

指针

指针的定义:

指针是一种变量,它的值为另一个变量的地址,即内存地址。

指针在内存中也是要占据位置的。

指针类型:

指针的值用来存储内存地址,指针的类型表示该地址所指向的数据类型并告诉编译器如何解释该指针所指向的内存中的数据。

指针的初始化:

指针的赋值是运用&这个操作符完成的,用于产生操作数的内存地址。

指针的运用(取值):

运用单目操作符*来取出指针所指向的内存块的值

	int a = 921; 
	int* b = &a; // b取得a在内存中的起始位置 
	int c = *b; // 得到b指向的内存块的值
	printf("a在内存中的起始地址为 %p \n", (void*)b);
	printf("b指针在内存中所指向的值为 %d \n", c);

 练习:

*&a = 25 

理解:

&a表示取a的起始地址,*(&a)表示取(&a)所指向的内存块的值

所以其实这个意思就是a=25


线性表

概念

定义:

具有相同特性的数据元素的一个有限序列,由n (n >= 0) 个数据元素(结点)a1、a2、a3.....an组成的有限序列。包括起始节点、终端节点、数据元素......

存储结构:

1.顺序存储结构:

        把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构

2.链式存储结构:

         结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻。访问时只能通过头指针进入链表。


顺序存储结构(顺序表)

优点:以物理位置相邻表示逻辑关系,任一元素均可随机存取,存储密度大。

缺点:在插入、删除某一元素时,需要移动大量元素,浪费存储空间,属于静态存储形式,数据元素的个数不能自由扩充。

特点: 地址连续、依次存放、随机存取 、类型相同

存储表示

逻辑结构:(a1,a2,a3,...... an)

存储结构:

顺序表的定义

顺序表的数组下标是从0开始的

数组静态分配

#define N 100

typedef struct {
	int e;
} Node;

typedef struct {  
	Node element[N]; //静态分配数组
	int length; //存储顺序表的长度
} SqList;

数组动态分配

typedef struct {
	int e;
} Node;

typedef struct {  
	Node *element; //动态分配数组
	int length; //存储顺序表的长度
} SqList;

顺序表的基本操作

初始化线性表

// 线性表的初始化
bool InitList_Sq(SqList &L, int n)
{
	// 分配内存
	L.element = (Node*)malloc(sizeof(Node)*n);	
	if (!L.element) return false; //分配失败
	L.length = 0; // 初始化空表长度为0
	return true; // 初始化成功
}

销毁线性表

// 销毁线性表
void DestroyList(SqList &L)
{
	if (L.element) delete L.element; // 释放存储空间
}

清空线性表

// 清空线性表
void ClearList(SqList &L)
{
	L.length = 0; //将线性表的长度置为0
}

求线性表的长度

// 求线性表的长度
int GetLength(SqList L) 
{
	return L.length;
}

判断线性表是否为空

// 判断线性表是否为空
bool IsEmpty(SqList L)
{
	if (L.length == 0) return true;
	else return false;
}

顺序表取值

// 顺序表的取值(根据位置获取元素)
bool GetElement(int idx, SqList L, Node &e) 
{
	if (idx < 1 || idx > L.length) return false;
	e = L.element[idx - 1];
	return true;
}

按值查找

// 按值查找
int LocateElem(SqList L, Node e) 
{
	for (int i = 0; i < L.length; i ++)
	{
		if (L.element[i].e == e.e) 
				return i + 1;
	}
	return 0; // 查找失败
}

顺序表的插入

// 顺序表的插入
bool ListInsert_Sq(SqList &L, int idx, Node e)
{
	if (idx < 1 || idx > L.length + 1) return false;
	for (int i = L.length - 1; i >= idx - 1; i --)
	{
		L.element[i + 1] = L.element[i];
	}
	L.element[idx - 1] = e;
	L.length ++;
	return true;
}

顺序表的删除

// 顺序表的删除
bool ListDelete_Sq(SqList &L, int idx)
{
	if (idx < 1 || idx > L.length) return false;
	for (int i = idx; i < L.length; i ++)
	{
		L.element[i - 1] = L.element[i];
	}
	L.length --;
	return true;
}

链式存储结构(链表)

定义:

n个结点由指针链组成一个链表。它是线性表的链式存储映像,称为线性表的链式存储结构。

概念表示:

结点:

数据元素的存储映像称为结点,它由数据域和指针域两部分组成。

特殊结点:

  • 头结点:在链表的首元结点之前额外设置的一个结点。
  • 首元结点:链表中存储第一个数据元素a1的结点

数据域:存储当前结点的数据。

指针域:存储下一个节点的位置。 

头指针: 

指向链表中第一个节点的指针。

链表:

 链表分为单链表、双链表、循环链表。

  • 单链表:结点只有一个指针域,存储的是下一个节点的地址。
  • 双链表:结点有两个指针域。存储相邻两个结点的地址。
  • 循环链表:是一种头尾相接的链表,表中的最后一个结点的指针域指向头结点,整个链表形成一个环。

存储表示:

逻辑结构:(a1,a2,a3,...... an)

存储结构:

第一种 (无头结点) :

第二种(有头结点):

空表

1.无头结点时,头指针为空时表示空表,表示空表。

2.有头结点时,头结点的指针域为空时,表示空表。

单链表

数组模拟单链表:数组模拟单链表文章浏览阅读118次。数组模拟单链表https://blog.csdn.net/m0_73569492/article/details/128693718?ops_request_misc=%257B%2522request%255Fid%2522%253A%25220bb3388a11ebbfdf7502eedcb53293d6%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=0bb3388a11ebbfdf7502eedcb53293d6&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128693718-null-null.nonecase&utm_term=%E5%8D%95%E9%93%BE%E8%A1%A8&spm=1018.2226.3001.4450

链表定义

定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类

typedef struct {
	int e;
} Data;

typedef struct Lnode {
	Data data; // 结点的数据域
	struct Lnode *next; // 结点的指针域
} LNode, *LinkList; // 定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类型。

LinkList L; // 定义链表L
LNode *p; // 定义结点指针
LinkList q; //定义结点指针

链表操作
初始化单链表

1.生成新节点作为头结点

2.头指针指向头结点

3.头结点的指针域指向空

分配内存:

L = (LinkList)malloc(sizeof(LNode));

这一行代码调用了 malloc 函数来为一个新的 LNode 结构体分配内存。malloc 返回的是一个指向所分配内存块的指针(类型为 void*),然后通过 (LinkList) 强制转换为 LinkList 类型(即 LNode*)。此时,L 已经指向了这块新分配的内存,这块内存代表了一个新的链表节点。

// 单链表的初始化
bool InitList_L(LinkList &L) 
{
	L = (LinkList)malloc(sizeof(LNode)); 
	L->next = NULL;
	return true;
}
 判断单链表是否为空

其实就是判断头结点的指针域是否为空,如果为空,则代表是空表,如果不为空,则代表不为空表。

// 判断链表是否为空
bool IsEmpty_List(LinkList L)
{
	if (L->next == NULL) 
		return true;
	return false;
}
单链表的销毁

销毁过程如下:

// 单链表的销毁
void Destroy_List(LinkList &L)
{
	LNode *p;
	while (L)
	{
		p = L;
		L = L->next;
		free(p);
	}
}
清空单链表

// 清空单链表
void Clear_List(LinkList &L)
{
	LNode *p;
	while (L->next) 
	{
		p = L->next;
		L->next = p->next;
		free(p);
	}
}
求单链表的表长
// 求单链表的表长
int Caculate_Length(LinkList L)
{
	int cnt = 0;
	for (LNode* p = L->next; p != NULL; p = p->next)
		cnt ++;
		
	return cnt;
}
根据位置获取元素
// 取值-取单链表中第idx个元素的内容
bool GetElement(LinkList L, Data &e, int idx)
{
	int cnt = 0;
	for (LNode* p = L->next; p != NULL; p = p->next)
	{
		 cnt ++;
		 if (cnt == idx) 
		 {
		 	e = p->data;
		 	return true;
		 }	
	}
	return false;
}
按值查找
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList L, Data &element)
{
	int cnt = 0;
	for (LNode* p = L->next; p != NULL; p = p->next)
	{
		 cnt ++;
		 if (p->data.e == element.e) return cnt; 
	}
	return -1;
}
单链表的插入(任意位置)

// 单链表的插入-在第i个元素之前插入
bool Insert(LinkList &L, int idx, Data element)
{
	int cnt = 0;
	for (LNode* p = L; p->next != NULL; p = p->next)
	{
		 if (cnt == idx - 1)
		 {
		 	LNode *e = (LNode*)malloc(sizeof(LNode));
		 	e->data = element;
		 	e->next = p->next;
		 	p->next = e;
		 	return true;
		 }
		 cnt ++;
	}	
	return false;
}
单链表删除元素

// 删除-删除第idx个元素
bool Delete(LinkList &L, int idx)
{
	int cnt = 0;
	for (LNode* p = L; p != NULL; p = p->next)
	{
		 if (cnt == idx - 1)
		 {
		 	LNode *q = p->next;
		 	p->next = q->next;
		 	free(q);
		 	return true;
		 }
		 cnt ++;
	}
	return false;	
}
头插法

// 头插法
bool Insert_Head(LinkList &L, Data element)
{
	LNode *cur = (LNode*)malloc(sizeof(LNode));
	cur->data = element;
	cur->next = L->next;
	L->next = cur;
	return true;
}
尾插法
// 尾插法
bool Insert_Tail(LinkList &L, Data element)
{
	LNode *p = L;
	while (p->next){
		p = p->next;
	}
	LNode *cur = (LNode*)malloc(sizeof(LNode));
	cur->data = element;
	cur->next = NULL;
	p->next = cur;
	return true;
}
输出单链表
// 输出单链表
void Print_List(LinkList &L)
{
	for (LNode* p = L->next; p != NULL; p = p->next)
	{
		printf("%d ", p->data.e);
	}
	printf("\n");
}

循环链表

优点:

从表中任意节点出发都能够找到其他结点。

注意:

当执行遍历操作时,条件与单链表不同,结束条件需要看当前节点的指针域是不是等于头结点。

链表定义:
typedef struct {
	int e;
} Data;

typedef struct Lnode {
	Data data; // 结点的数据域
	struct Lnode *next; // 结点的指针域
} LNode, *LinkList; // 定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类型。
链表操作:

带头指针的:

// 循环链表的初始化
bool InitList_L(LinkList &L) 
{
	L = (LinkList)malloc(sizeof(LNode));
	L->next = L;
	return true;
}
// 判断循环链表是否为空
bool IsEmpty_List(LinkList L)
{
	if (L->next == L) return true;
	return false;
}
// 循环链表的销毁
void Destroy_List(LinkList &L)
{
	LNode *p = L->next;
	while (p->next != L)
	{
		L = L->next;
		free(p);
		p = L->next;
	}
	free(L);
}
// 清空循环链表
void Clear_List(LinkList &L)
{
	LNode *p;
	while (L->next != L)
	{
		p = L->next;
		L->next = p->next;
		free(p);
	}
}
// 求循环链表的表长
int Caculate_Length(LinkList L)
{
	int len = 0;
	LNode *p = L;
	while (p->next != L)
	{
		len ++;
		p = p->next;
	}
	return len;
}
// 取值-取循环链表中第idx个元素的内容
bool GetElement(LinkList L, Data &e, int idx)
{
	int len = 0;
	LNode *p = L;
	while (p->next != L)
	{
		len ++;
		p = p->next;
		if (len == idx)
		{
			e = p->data;
			return true;
		}
	}
	
	return false;
}
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList L, Data &element)
{
	int len = 0;
	LNode *p = L;
	while (p->next != L)
	{
		len ++;
		p = p->next;
		if (p->data.e == element.e)
		{
			return len;
		}
	}
	return -1;
}
// 循环链表的插入-在第i个元素之前插入
bool Insert(LinkList &L, int idx, Data element)
{
	int len = 0;
	LNode *p = L;
	while (p->next != L)
	{
		if (len == idx - 1)
		{
			LNode *q = (LNode*)malloc(sizeof(LNode));
			q->data = element;
			q->next = p->next;
			p->next = q;
			return true;
		}
		len ++;
		p = p->next;
	}
	
	return false;
}
// 删除-删除第idx个元素
bool Delete(LinkList &L, int idx)
{
	int len = 0;
	LNode *p = L;
	while (p->next != L)
	{
		len ++;
		p = p->next;
		if (len == idx - 1)
		{
			LNode *q = p->next;
			p->next = q->next;
			free(q);
			return true;
		}
	}
	return false;
}

// 头插法
bool Insert_Head(LinkList &L, Data element)
{
	LNode *p = (LNode*)malloc(sizeof(LNode));
	p->data = element;
	p->next = L->next;
	L->next = p;
	return true;
}

// 尾插法
bool Insert_Tail(LinkList &L, Data element)
{
	LNode *p = L;
	while (p->next != L)
	{
		p = p->next;
	}
	LNode *q = (LNode*)malloc(sizeof(LNode));
	q->data = element;
	q->next = p->next;
	p->next = q;
	return true;
}
// 输出循环链表
void Print_List(LinkList &L)
{
	for (LNode* p = L->next; p != L; p = p->next)
	{
		printf("%d ", p->data.e);
	}
	printf("\n");
}

带尾指针的:

// 循环链表的初始化
bool InitList_R(LinkList &R) 
{
	R->next = R;
	return true;
}
// 判断循环链表是否为空
bool IsEmpty_List(LinkList R)
{
	if (R->next == R) return true;
	return false;
}
// 循环链表的销毁
void Destroy_List(LinkList &R)
{
	LNode *p;
	while (R->next != R)
	{
		p = R->next;
		R->next = p->next;
		free(p);
	}
	free(R);
}
// 清空循环链表
void Clear_List(LinkList &R)
{
	LNode *p;
	while (R->next != R)
	{
		p = R->next;
		R->next = p->next;
		free(p);
	}
}
// 求循环链表的表长
int Caculate_Length(LinkList R)
{
	LNode *p = R;
	int len = 0;
	while (p->next != R)
	{
		len ++;
		p = p->next;
	}
	return len;
}
// 取值-取循环链表中第idx个元素的内容
bool GetElement(LinkList R, Data &e, int idx)
{
	int len = 0;
	LNode *p = R;
	while (p->next != R)
	{
		len ++;
		p = p->next;
		if (len == idx)
		{
			e = p->data;
			return true;
		}
	}
	return false;	
}
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList R, Data &element)
{
	int len = 0;
	LNode *p = R;
	while (p->next != R)
	{
		len ++;
		p = p->next;
		if (p->data.e == element.e)
		{
			return len;
		}
	}
	return -1;
}	
// 循环链表的插入-在第i个元素之前插入
bool Insert(LinkList &R, int idx, Data element)
{
	int len = 0;
	LNode *p = R;
	while (p->next != R)
	{
		if (len == idx - 1)
		{
			LNode *q = (LNode*)malloc(sizeof(LNode));
			q->data = element;
			q->next = p->next;
			p->next = q;
			return true;
		}
		len ++;
		p = p->next;
	}
	
	return false;	
}
// 删除-删除第idx个元素
bool Delete(LinkList &R, int idx)
{
	int len = 0;
	LNode *p = R;
	while (p->next != R)
	{
		len ++;
		p = p->next;
		if (len == idx - 1)
		{
			LNode *q = p->next;
			p->next = q->next;
			free(q);
			return true;
		}
	}
	return false;	
}

// 头插法
bool Insert_Head(LinkList &R, Data element)
{
	LNode *p = (LNode*)malloc(sizeof(LNode));
	p->data = element;
	p->next = R->next;
	R->next = p;
	return true;
}

// 尾插法
bool Insert_Tail(LinkList &R, Data element)
{
	
	LNode *p = R;
	while (p->next != R)
	{
		p = p->next;
	}
	LNode *q = (LNode*)malloc(sizeof(LNode));
	q->data = element;
	q->next = R;
	p->next = q;
	return true;
}
// 输出循环链表
void Print_List(LinkList &R)
{
	for (LNode* p = R->next; p != R; p = p->next)
	{
		printf("%d ", p->data.e);
	}
	printf("\n");
}

双链表

数组模拟双链表:数组模拟双链表文章浏览阅读92次。数组模拟双链表_;.ir=k,8https://blog.csdn.net/m0_73569492/article/details/128704895?ops_request_misc=%257B%2522request%255Fid%2522%253A%25221c13d05d054d65bc8bd9b7e25466efa9%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=1c13d05d054d65bc8bd9b7e25466efa9&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-128704895-null-null.nonecase&utm_term=%E5%8F%8C%E9%93%BE%E8%A1%A8&spm=1018.2226.3001.4450

链表定义
typedef struct {
	int e;
} Data;

typedef struct Lnode {
	struct Lnode *pre; // 指向前驱结点
	Data data; // 结点的数据域
	struct Lnode *next; // 指向后继结点
} LNode, *LinkList; // 定义了两种类型:LNode 为结构体类型;LinkList 为指向该结构体类型的指针类型。
链表操作
// 双链表的初始化
bool InitList_L(LinkList &L) 
{
	L = (LinkList)malloc(sizeof(LNode));
	L->pre = NULL;
	L->next = NULL;
	return true;
}
// 判断链表是否为空
bool IsEmpty_List(LinkList L)
{
	if (L->next == NULL) return true;
	return false;
}
// 双链表的销毁
void Destroy_List(LinkList &L)
{
	LNode *p;
	while (L)
	{
		p = L;
		L = L->next;
		free(p);
	}	
}
// 清空双链表
void Clear_List(LinkList &L)
{
	LNode *p;
	while (L->next != NULL) 
	{
		p = L->next;
		L->next = p->next;
		free(p);
	}	
}
// 求双链表的表长
int Caculate_Length(LinkList L)
{
	int cnt = 0;
	for (LNode* p = L->next; p != NULL; p = p->next)
		cnt ++;
		
	return cnt;
}
// 取值-取双链表中第idx个元素的内容
bool GetElement(LinkList L, Data &e, int idx)
{
	int cnt = 0;
	for (LNode* p = L->next; p != NULL; p = p->next)
	{
		 cnt ++;
		 if (cnt == idx) 
		 {
		 	e = p->data;
		 	return true;
		 }	
	}
	return false;
}
// 按值查找-根据数据获取该数据所在位置
int GetIdx(LinkList L, Data &element)
{
	int cnt = 0;
	for (LNode* p = L->next; p != NULL; p = p->next)
	{
		 cnt ++;
		 if (p->data.e == element.e) return cnt; 
	}
	return -1;	
}
// 双链表的插入-在第i个元素之前插入
bool Insert(LinkList &L, int idx, Data element)
{
	int cnt = 0;
	for (LNode* p = L; p->next != NULL; p = p->next)
	{
		 if (cnt == idx - 1)
		 {
		 	LNode *e = (LNode*)malloc(sizeof(LNode));
		 	e->data = element;
		 	e->next = p->next;
		 	e->pre = p;
		 	p->next->pre = e;
		 	p->next = e;
		 }
		 cnt ++;
	}	
	return false;	
}
// 删除-删除第idx个元素
bool Delete(LinkList &L, int idx)
{
	int cnt = 0;
	for (LNode* p = L; p != NULL; p = p->next)
	{
		 if (cnt == idx - 1)
		 {
		 	LNode *q = p->next;
		 	if (!q->next) 
		 	{
				p->next = NULL;
				free(q);
				return true; 	
			}
		 	p->next = q->next;
		 	q->next->pre = p;
		 	
		 	free(q);
		 	return true;
		 }
		 cnt ++;
	}
	return false;	
}

// 头插法
bool Insert_Head(LinkList &L, Data element)
{
	LNode *p = (LNode*)malloc(sizeof(LNode));
	p->data = element;
	if (L->next) 
	{
		p->pre = L;
		p->next = L->next;
		L->next->pre = p;
		L->next = p;
	}
	else
	{
		L->next = p;
		p->pre = L;
		p->next = NULL;
	}
	return true;
}

// 尾插法
bool Insert_Tail(LinkList &L, Data element)
{
	LNode *p = L;
	while (p->next != NULL){
		p = p->next;
	}
	// 在p后面插入cur
	LNode *cur = (LNode*)malloc(sizeof(LNode));
	cur->data = element;
	if (p->next)
	{
		cur->pre = p;
		cur->next = p->next;
		p->next->pre = cur;
		p->next = cur;
	}
	else
	{
		p->next = cur;
		cur->pre = p;
		cur->next = NULL;
	}
	return true;
}
// 输出链表
void Print_List(LinkList &L)
{
	for (LNode* p = L->next; p != NULL; p = p->next)
	{
		printf("%d ", p->data.e);
	}
	printf("\n");	
}

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

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

相关文章

Vue 中el-table-column 进行循环,页面没渲染成功

文章目录 前言效果图代码示例可能出现的问题及原因解决思路 前言 实现效果&#xff1a;el-table-column 进行循环&#xff0c;使之代码简化 遇到的问题&#xff1a; data进行默认赋值&#xff0c;操作列的删除都可以出来&#xff0c;其他表格里面的数据没出来 效果图 示例&am…

OpenGL入门最后一章观察矩阵(照相机)

前面的一篇文章笔者向大家介绍了模型变化矩阵&#xff0c;投影矩阵。现在只剩下最后一个观察矩阵没有和大家讲了。此片文章就为大家介绍OpenGL入门篇的最后一个内容。 观察矩阵 前面的篇章当中&#xff0c;我们看到了即使没有观察矩阵&#xff0c;我们也能对绘制出来的模型有一…

教程:从pycharm基于anaconda构建机器学习环境并运行第一个 Python 文件

1. 安装 PyCharm 访问 PyCharm 官方网站&#xff1a;https://www.jetbrains.com/pycharm/。下载社区版&#xff08;免费&#xff09;或专业版&#xff08;收费&#xff0c;提供更多功能&#xff09;。按照操作系统的安装指导安装 PyCharm。安装后打开 PyCharm&#xff0c;并根…

springcloud篇3-docker需熟练掌握的知识点

docker的原理请参考博文《Docker与Kubernetes》。 一、安装docker的指令 1.1 安装yum工具 yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken补充&#xff1a;配置镜像源 注意&#xff1a; yum安装是在线联网下载安装&#xff0c;而很多的资源…

ceph文件系统

ceph文件系统&#xff1a;高度可扩展&#xff0c;分布式的存储文件系统&#xff0c;旨在提高性能&#xff0c;高可靠性和高可用的对 象存储&#xff0c;块存储&#xff0c;文件系统的存储。使用分布式的算法保证数据的高可用和一致性。 ceph的组件 1、MON&#xff1a;ceph m…

牛客网刷题 ——C语言初阶——BC117 小乐乐走台阶

1.题目 &#xff1a;BC117 小乐乐走台阶 牛客OJ题链接 描述 小乐乐上课需要走n阶台阶&#xff0c;因为他腿比较长&#xff0c;所以每次可以选择走一阶或者走两阶&#xff0c;那么他一共有多少种走法&#xff1f; 输入描述&#xff1a; 输入包含一个整数n (1 ≤ n ≤ 30) …

flux文生图 生成高质量图像

flux文生图 生成高质量图像 flyfish import torch from diffusers import FluxPipeline# 初始化 FluxPipeline model_path "/home/FLUX___1-dev" pipe FluxPipeline.from_pretrained(model_path, torch_dtypetorch.bfloat16) pipe.enable_model_cpu_offload() #…

设计模式 结构型 装饰器模式(Decorator Pattern)与 常见技术框架应用 解析

装饰器模式&#xff08;Decorator Pattern&#xff09;&#xff0c;又称为包装器模式&#xff08;Wrapper Pattern&#xff09;&#xff0c;是一种结构型设计模式。它允许在不改变原有对象结构的基础上&#xff0c;动态地给对象添加一些新的职责&#xff08;即增加其额外功能&a…

计算机毕业设计Python+Vue.js游戏推荐系统 Steam游戏推荐系统 Django Flask 游 戏可视化 游戏数据分析 游戏大数据 爬虫

2021年12月21日 姓名 专业 软件工程 班级 20-IBM-企Java2 题目 基于hadoopSpark的游戏推荐与可视化系统的设计与实现 指导教师 王文钧、王春娴 一、与本题目有关的国内外研究情况、题目研究的目的和意义、主要内容、本课题创新之处、拟解决的问题&#xff1a; 国内外…

[创业之路-222]:波士顿矩阵与GE矩阵在业务组合选中作用、优缺点比较

目录 一、波士顿矩阵 1、基本原理 2、各象限产品的定义及战略对策 3、应用 4、优点与局限性 二、技术成熟度模型与产品生命周期模型的配对 1、技术成熟度模型 2、产品生命周期模型 3、技术成熟度模型与产品生命周期模型的配对 三、产品生命周期与产品类型的对应关系 …

使用Python类库pandas操作Excel表格

Date: 2025.01.02 20:33:30 author: lijianzhan 简述&#xff1a;pandas 是处理 Excel 文件的强大工具&#xff0c;它提供了简单易用的接口来读取、操作和写入 Excel 数据。以下是使用 pandas 处理 Excel 文件的详细指南&#xff0c;包括常见操作和示例代码。 安装依赖,pandas …

Deepseek v3 的笔记

基本概述 Deepseek v3是Deepseek发布的旗舰模型&#xff0c;属于607B的混合专家&#xff08;MoE&#xff09;模型&#xff0c;其中活跃参数为37B。在当前的模型领域&#xff0c;它堪称最佳的开源模型&#xff0c;性能超越了Llama 3.1 405b、Qwen和Mistral等知名模型。根据基准…

Python多分类Logistic回归详解与实践

在机器学习中&#xff0c;Logistic回归是一种基本但非常有效的分类算法。它不仅可以用于二分类问题&#xff0c;还可以扩展应用于多分类问题。本文将详细介绍如何使用Python实现一个多分类的Logistic回归模型&#xff0c;并给出详细的代码示例。 一、Logistic回归简介 Logist…

前端,npm install安装依赖卡在sill idealTree buildDeps(设置淘宝依赖)

输入npm i后&#xff0c;一直卡在sill idealTree buildDeps&#xff0c;一动不动 cnpm可以安装成功&#xff0c;但使用cnpm不会生成package-lock.json文件 设置淘宝依赖&#xff0c;依然卡住&#xff0c;挂梯子也不行 解决方法&#xff1a; // 取消ssl验证 set strict-ssl …

装饰者模式

1、定义 装饰者模式&#xff1a;在不必改变原类和使用继承的情况下&#xff0c;动态地扩展一个对象的功能。它是通过创建一个包装对象&#xff0c;也就是装饰来包裹真实的对象 2、实际应用 星巴克的咖啡系统项目&#xff1a; 星巴克要求的各种下单功能&#xff1a;大杯原味、大…

招银网路Java后端一面,难度有点大!

这是一位武汉理工大学同学的招银网络一面面经,同样附带超详细的参考答案。大家可以用来查漏补缺,针对性地补短板。 招银网络一面还是比较简单的,基本都是一些比较重要且高频的常规八股,项目问的不多。到了二面的时候, 会开始主要考察你的项目。 1、自我介绍 自我介绍一般…

C++之设计模式

设计模式 简介单例模式饿汉模式懒汉模式 工厂模式简单工厂模式工厂方法模式抽象工厂模式 建造者模式代理模式 简介 设计模式是前辈们对代码开发经验的总结&#xff0c;是解决特定问题的⼀系列套路它不是语法规定&#xff0c;而是⼀套⽤来提高代码可复用性、可维护性、可读性、…

云效流水线使用Node构建部署前端web项目

云效流水线实现自动化部署 背景新建流水线配置流水线运行流水线总结 背景 先来看看没有配置云效流水线之前的部署流程&#xff1a; 而且宝塔会经常要求重新登录&#xff0c;麻烦的很 网上博客分享了不少的配置流程&#xff0c;这一篇博客的亮点就是不仅给出了npm命令构建&…

pycharm如何拉取一个git项目,然后,修改后再上传到自建的项目中?

以chattts为例 https://github.com/2noise/ChatTTS.git 1.建一个虚拟环境&#xff0c;用于项目使用 2.pychar&#xff4d;新建工程 &#xff13;.忽略 提示 勾选&#xff0c;新建远程仓库 设置账号和密码 设置git路径&#xff0c;一般是正确的&#xff0c;点测试即可 &…

(五)开机自启动以及scp工具文件传输小问题

文章目录 程序开机自启动先制作一个可执行程序第一种 通过命令行实现程序开机自启动第二种 通过 Linux 系统镜像实现程序开机自启动 scp工具文件传输小问题 程序开机自启动 原因&#xff1a;做成产品后&#xff0c;用户直接开机使用&#xff0c;总不能在开机执行程序后才可以使…