0
点赞
收藏
分享

微信扫一扫

Elasticsearch优点和缺点以及要点和难点具体应用

禾木瞎写 2024-05-27 阅读 5

数据结构(一)

数据结构:研究的是数据的逻辑结构、存储结构及其操作
学习数据结构的目的:高效的写程序

逻辑结构

在这里插入图片描述

存储结构

线性关系

顺序存储

顺序表

定义

做一个学生管理系统:采用顺序存储的形式做
#define SIZE (100)
typedef struct student
{
	char name[20];
	char id[20];
	char add[20];
	char age[20];
}data_type; //都是所要研究的对象的数据类型
typedef struct books
{
	char name[20];
	char isbn[20];
	char pro[20];
	char year[20];
}data_type;
//存储数据
//顺序表 : 特点:大小固定空间连续,表满不能存,表空不能取
typedef struct list
{
	data_type Data[SIZE]; //存储空间
	int count; //用来表示表里面有多少元素 count 和 0、size
}List;
//存储数据
//动态顺序表 : 特点:大小固定空间连续
typedef struct list
{
	data_type (*Data)[]; //存储空间,不再是一个数组,而是一个数组指针
	int size; //用来表示当前顺序表的存储能力有多大
	int count; //用来表示表里面有多少元素 表空 count = 0 表满要扩容,count = size
}List;

在这里插入图片描述

动态的顺序表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建

在这里插入图片描述

//函数定义:
//函数功能:创建顺序表
//函数参数:void
//函数返回值:成功返回表的地址,失败返回NULL
List *CreatList(void)
{
	int mysize = 0;
	List *pList = NULL; //避免野指针的出现
	//创建空间
	pList = (List *)malloc(sizeof(List)); //表
	if(!pList)
	{
		puts("MALLOC");
		return NULL;
	}
	memset(pList, 0, sizeof(List));
	//开始创建存储空间的大小
	printf("请输入大小:");
	scanf("%d", &mysize);
	//给顺序表的存储空间
	pList->Data = (data_type *)malloc(sizeof(data_type)*mysize); //大小,显式计算
	//初始化顺序表的大小
	pList->size = mysize;
	return pList;
}
插入

在这里插入图片描述

//函数功能:插入元素
//函数参数:给谁插入,插入的位置,插入的值
//函数返回值:成功返回OK,失败返回失败原因
int InsertItem(List *pList, int pos, data_type item)
{
	//入参判断
	if(!pList) return LIST_NULL;
	//判断是否为满
	if(pList->count == pList->size) return LIST_FULL;
	//判断位置是否合法
	if(pos < -1 || pos > pList->count) return POS_ERR;
	//插入
	//如果 pos = -1 尾插
	if(-1 == pos)
	{
		pList->Data[pList->count] = item;
		//元素个数+1
		pList->count++;
		return OK;
	}
	//1、移动元素
	for(int i = pList->count; i>pos; i--)
	{
		pList->Data[i] = pList->Data[i-1];
	}
	//2、插入
	pList->Data[pos] = item;
	//3、count
	pList->count++;
	return OK;
}
删除

在这里插入图片描述

//函数功能:删除元素
//函数参数:被删除元素的表,删除的位置,删除的值
//函数返回值:成功返回OK,失败返回失败原因
int DeleteItem(List *pList, int pos, data_type *item)
{
	//入参判断
	if(!pList) return LIST_NULL;
	//表为空
	if(0 == pList->count) return LIST_EMPTY;
	//pos
	if(pos < -1 || pos > pList->count-1) return POS_ERR;
	//删除元素
	//尾删
	if(-1 == pos)
	{
		//把最后一个元素保存
		*item = pList->Data[pList->count-1];
		//元素的个数 -1
		pList->count --;
		return OK;
	}
	//正常的删除
	//1、保存元素
	*item = pList->Data[pos];
	//移动元素
	for(int i = pos; i<pList->count-1; i++)
	{
		pList->Data[i] = pList->Data[i+1];
	}
	//个数-1
	pList->count --;
	return OK;
}
显示
//函数功能:显示所有的元素
//函数参数:被显示元素的表
//函数返回值:成功返回OK,失败返回失败原因
int ShowList(List *pList)
{
	//入参判断
	if(!pList)
	{
		return LIST_NULL;
	}
	//如果为空
	if(0 == pList->count) return LIST_EMPTY;
	//从头到尾打印元素
	for(int i=0; i<pList->count; i++)
	{
		printf("%d ", pList->Data[i]);
	}
	printf("\n");
	return OK;
}
查询
int SearchItem(List *pList, data_type item)
{
	//入参判断
	if(!pList)
	{
		return LIST_NULL;
	}
	//如果为空
	if(0 == pList->count) return LIST_EMPTY;
	//从头到尾遍历元素
	for(int i=0; i<pList->count; i++)
	{
		if(pList->Data[i] == item)
		{
			//找到了
			return OK;
		}
	}
	//没找到
	return OK;
}
修改
int SearchItem(List *pList, data_type old_item, data_type new_item)
{
	//入参判断
	if(!pList)
	{
		return LIST_NULL;
	}
	//如果为空
	if(0 == pList->count) return LIST_EMPTY;
	//从头到尾遍历元素
	for(int i=0; i<pList->count; i++)
	{
		if(pList->Data[i] == old_item)
		{
		//找到了
		//替换
			pList->Data[i] = new_item;
			return OK;
		}
	}
	//没找到
	return OK;
}
导入

在这里插入图片描述

导出

在这里插入图片描述

销毁
//函数功能:销毁空间
int DestoryList(List **pList)
{
	//入参判断
	printf("Destory Before : %p\n", *pList);
	if(!(*pList)) return LIST_NULL;
	//释放空间
	free((*pList)->Data);
	//释放表
	free(*pList);
	*pList = NULL;
	printf("Destory After : %p\n", *pList);
	return OK;
}

扩容

扩容的思想:大小 * 2
在这里插入图片描述

链式存储

链表的分类

在这里插入图片描述

带头结点的单向不循环链表

定义
在这里插入图片描述
在这里插入图片描述
创建
在这里插入图片描述
在这里插入图片描述
插入
在这里插入图片描述
在这里插入图片描述

//插入
//函数参数:被插入的表、插入的位置、插入的值
//函数返回值:成功返回OK,失败返回失败原因
int InsertItem(LNode *pHead, int pos, data_type item)
{
	LNode *pNew = NULL; //表示新结点
	LNode *pTmp = NULL; //表示辅助操作的
	int i=0; //表示插入的位置
	//入参判断
	if(!pHead) return LINK_NULL;
	//判断pos
	if(pos < -1) return POS_ERR;
	//1.分配空间
	pNew = CreatNode();
	pTmp = pHead;
	//2.赋值
	pNew->Data = item;
	//插入
	if(pos == -1)
	{
		//尾插
		//找到尾结点
		while(pTmp->Next != NULL)
		{
		//王后找
		pTmp = pTmp->Next;
		}
		//插入
		pTmp->Next = pNew;
		pNew->Next = NULL;
		return OK;
	}
	//其余的插入 头插,中插
	while(i < pos && pTmp != NULL)
	{
		//往后
		pTmp = pTmp->Next;
		//次数++
		i++;
	}
	if(!pTmp) return POS_ERR;
	//插入
	//1。保护后面所有的结点
	pNew->Next = pTmp->Next;
	//2。插入
	pTmp->Next = pNew;
	return OK;
}

删除
在这里插入图片描述
在这里插入图片描述

//删除结点
//函数参数:被删除元素的表,被删除的位置,被删除的值
//函数返回值:成功返回OK,失败返回失败原因
int DeleteItem(LNode *pHead, int pos, data_type *item)
{
	//两个指针
	LNode *pDel_Pre = pHead;
	LNode *pDel = NULL;
	int i = 0;
	//入参判断
	if(!pHead) return LINK_NULL;
	//空不能删除
	if(pHead->Next == NULL) return LINK_EMPTY;
	if(pos < -2) return POS_ERR;
	pDel = pHead->Next; //初始化为首届点
	//删除
	//1.找到要删除的位置
	if(pos == -1)
	{
		while(pDel->Next != NULL)
		{
		//往后
		pDel_Pre = pDel_Pre->Next;
		pDel = pDel->Next;
		}
	//保存元素
	*item = pDel->Data;
	//删除结点
	pDel_Pre->Next = NULL;
	//释放
	free(pDel);
	return OK;
	}
	//其余的删除
	while(i<pos && pDel!=NULL)
	{
		//往后
		pDel_Pre=pDel_Pre->Next;
		pDel=pDel->Next;
		i++;
	}
	if(!pDel) return POS_ERR;
	//删除结点
	//1、保存元素
	*item = pDel->Data;
	//删除结点
	pDel_Pre->Next = pDel->Next;
	free(pDel);
	return OK;
}

显示

//函数功能:显示
//函数参数:要显示的表
//函数返回值:成功OK,失败返回失败原因
int ShowLink(LNode *pHead)
{
	LNode *pTmp = NULL;//辅助操作
	//入参判断
	if(!pHead) return LINK_NULL;
	//如果没有元岁
	//头结点= 尾结点
	if(NULL == pHead->Next) return LINK_EMPTY;
	pTmp = pHead->Next;
	while(pTmp) //从首届点,打印到尾结点
	{
		printf("%d ", pTmp->Data); //访问数据域
		//往后
		pTmp = pTmp->Next;
	}
	printf("\n");
	return OK;
}

销毁
采用头删法删除所有的结点,删除到只剩下头节点位置,free(pHead)
保存
把所有的结点都保存。
导入
每一次导入都相当于新建一个结点执行插入操作

带头结点的循环的单向链表

如何逆置一个单链表?头删头插法

静态链表

如果需求更多是插入和删除操作,但是编译环境不支持指针类型:
静态链表(二维数组)
在这里插入图片描述

双向链表

定义

在这里插入图片描述
在这里插入图片描述

创建

在这里插入图片描述

插入

v

//函数功能:插入元素
//函数参数:被插入元素的表,被插入的位置,被插入的值
//函数返回值:成功返回OK,失败返回失败原因
int InsertItem(DBNode *pHead, int pos, data_type item)
{
	DBNode *pNew = NULL;
	DBNode *pTmp = pHead;
	int i=0;
	//入参判断
	if(!pHead) return LINK_NULL;
	//判断pos
	if(pos < 0) return POS_ERR;
	//插入元素
	pNew = CreatNode();
	//赋值
	pNew->Data = item;
	//插入元素
	while(i<pos && pTmp != NULL)
	{
			//往后
			pTmp = pTmp->Next;
			i++;
	}
	if(!pTmp) return POS_ERR;
	//插入元素
	pNew->Next = pTmp->Next;
	pNew->Pre = pTmp;
	if(pTmp->Next!=NULL)
	{
		pTmp->Next->Pre = pNew;
	}
	pTmp->Next = pNew;
	return OK;
}

删除

在这里插入图片描述

//函数功能:删除结点
//函数参数:被删除结点的表、删除的位置、删除的值
//函数返回值:成功返回OK,失败返回失败原因
int DeleteItem(DBNode *pHead, int pos, data_type *item)
{
	int i = 0;
	//定义辅助
	DBNode *pDel = NULL;
	DBNode *pDel_Pre = pHead;
	//入参判断
	if(!pHead) return LINK_NULL;
	if(!pHead->Next) return LINK_EMPTY;
	if(pos < 0) return POS_ERR;
	//初始化
	pDel = pHead->Next;
	//找到要删除的位置
	while(i < pos && pDel != NULL)
	{
		//往后
		pDel_Pre = pDel_Pre->Next;
		pDel = pDel->Next;
		i++;
	}
	/*
	* for(int i=0; i<pos && pDel!=NULL; i++)
	* {
	* //往后
	* }
	*/
	if(!pDel) return POS_ERR;
	//保存元素
	*item = pDel->Data;
	//删除结点
	//如果是为结点
	if(pDel->Next != NULL)
	{
		pDel->Next->Pre = pDel_Pre;
	}
	pDel_Pre->Next = pDel->Next;
	free(pDel);
	return OK;
}

显示

//显示
int ShowLink(DBNode *pHead)
{
	//入参判断和定义
	DBNode *pTmp = NULL;
	if(!pHead) return LINK_NULL;
	if(pHead->Next == NULL) return LINK_EMPTY;
	pTmp = pHead->Next;
	while(pTmp) //从首届点打印到为结点
	{
		printf("%d ", pTmp->Data);
		pTmp = pTmp->Next;
	}
	puts(" ")
	return OK;
}

双向循环链表

受限的线性表

栈、队列、串

栈顺序存储

线性表的顺序存储:静态的

#define SIZE (100)
typedef struct list
{
	data_type Data[SIZE]; //存储空间
	int count; //存储有多少个成员
}List;
typedef struct stack
{
	data_type Data[SIZE]; //存储空间
	int top; //用来指示栈顶 top = 0 空 top = SIZE 满
}Stack;

定义
在这里插入图片描述
创建
在这里插入图片描述
入栈、出栈
在这里插入图片描述
显示

//函数功能:入栈
//函数参数:入队栈,入栈的元素
//函数返回值:成功返回OK,失败返回失败原因
int Pop(Stack *pStack, data_type item)
{
	//入参判断
	if(!pStack) return LIST_NULL;
	if(pStack->top == SIZE) return LIST_FULL;
	//入栈
	pStack->Data[pStack->top] = item;
	//栈顶移动
	pStack->top++;
	return OK;
}
//出栈
int Push(Stack *pStack, data_type *item)
{
	//入参判断
	if(!pStack) return LIST_NULL;
	//空.
	if(0 == pStack->top) return LIST_EMPTY;
	//出战
	//top--
	pStack->top--;
	栈链式存储:
	共享栈:
	队列顺序存储:
	//保存元素
	*item = pStack->Data[pStack->top];
	return OK;
}
//显示,从0打印到栈顶-1
int ShowStack(Stack *pStack)
{
	//入参判断
	if(!pStack) return LIST_NULL;
	//空
	if(pStack->top == 0) LIST_EMPTY;
	//从0打印到top-1
	for(int i=0; i<pStack->top; i++)
	{
		printf("%d ", pStack->Data[i]);
	}
	puts(" ");
	return OK;
}

栈链式存储

共享栈

在这里插入图片描述

队列顺序存储

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//创建
Queue *CreatQueue(void)
{
	//分配空间
	Queue *pQueue = (Queue *)malloc(sizeof(Queue));
	if(!pQueue) return NULL;
	//清空
	memset(pQueue, 0, sizeof(Queue));
	return pQueue;
}
//入队、出队、显示//创建空间
//入队
//参数:入的队 入队的值
//返回值:成功返回ok,失败返回失败原因
int InQueue(Queue *pQueue, data_type item)
{
	//入参判断
	if(!pQueue) return LIST_NULL;
	//判断对列是否为满
	if(pQueue->head == pQueue->tail && pQueue->tag == 1)
	{
		return LIST_FULL;
	}
	//入队
	pQueue->Data[pQueue->tail] = item;
	//尾移动
	pQueue->tail = (pQueue->tail + 1) % SIZE;
	//入队
	pQueue->tag = 1;
	return OK;
}

//出队
//参数:出队的对列,出队的值
//返回值:成功返回ok,失败返回失败原因
int OutQueue(Queue *pQueue, data_type *item)
{
	//入参判断
	if(!pQueue) return LIST_NULL;
	//空
	if(pQueue->head == pQueue->tail && pQueue->tag == 0)
	{
		return LIST_EMPTY;
	}
	//出队
	//保存元素
	*item = pQueue->Data[pQueue->head];
	//头
	pQueue->head = (pQueue->head + 1) % SIZE;
	//出
	pQueue->tag = 0;
	return OK;
}
//显示
//参数:打印的队
//返回值:成功返回ok,失败返回失败原因
int ShowQueue(Queue *pQueue)
{
	//入参判断
	if(!pQueue) return LIST_NULL;
	//没有元素
	if(pQueue->head == pQueue->tail && pQueue->tag == 0)
	{
		return LIST_EMPTY;
	}
	//打印,不满:从队头打印到队尾
	// 满:把所有元素都打印一遍
	int i=0;
	if(pQueue->head == pQueue->tail && pQueue->tag == 1)
	{
		for(i = 0; i < SIZE; i++)
		{
			printf("%d ", pQueue->Data[(pQueue->head + i)%SIZE]);
		}
		printf("\n");
		return OK;
	}
	//不满
	//for(i = pQueue->head ; i!=pQueue->tail; i = (i+1)%SIZE)
	//{
	// printf("%d ", pQueue->Data[i]);
	//}
	i=pQueue->head;
	while(i != pQueue->tail)
	{
		printf("%d ", pQueue->Data[i]);
		i = (i+1)%SIZE;
	}
	printf("\n");
	return OK;
}
队列链式存储

双端队列

在队头可以入元素,(在队尾可以出元素)

栈和队列的应用

举报

相关推荐

0 条评论