【数据结构】顺序表与单链表的增删查改

文章目录

  • 前言
  • 顺序表增删查改
    • 顺序表的定义与初始化
    • 增删查改操作
    • 测试代码
    • 完整代码
  • 单链表的增删查改
    • 数据结构定义
    • 动态申请节点
    • 单链表的尾插和头插
    • 单链表的尾删和头删
    • 单链表的查找
    • 单链表的插入和删除
    • 销毁链表
    • 测试代码
    • 完整代码
  • 总结

前言

在计算机编程领域,数据结构是非常重要的基础知识之一。顺序表和单链表作为常见的线性数据结构,在实际的软件开发中被广泛应用。本文将介绍了C语言中顺序表和单链表的实现方式,并对其进行了增删查改操作的详细讲解。通过阅读本文,读者将能够深入了解顺序表和单链表的底层实现原理,掌握它们的基本操作及相关的代码编写技巧。

顺序表增删查改

当今计算机编程领域中最重要的数据结构之一是顺序表。顺序表是一种线性表,其中的元素在内存中按照顺序存储,可以通过下标来访问。本文将介绍一个简单的顺序表实现,并对其进行增删查改操作。

顺序表的定义与初始化

首先,我们需要定义一个结构体来表示顺序表,并声明一些相关的变量和函数。顺序表的结构体包含一个动态数组 a,用于存储数据;size 表示当前顺序表中元素的个数;capacity 表示顺序表的容量,即当前数组 a 的大小。

typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity;
}SeqList;void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);
void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);
int SeqListFind(SeqList* ps, SLDateType x);
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
void SeqListErase(SeqList* ps, int pos);

在初始化顺序表之前,我们需要实现一个辅助函数 SLCheckCapacity,用于检查顺序表的容量,并在需要时进行扩容。

void SLCheckCapacity(SeqList* ps)
{assert(ps);if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* tmp = realloc(ps->a, newCapacity * sizeof(SLDateType));if (tmp == NULL){printf("realloc fail!\n");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}
}

接下来,我们实现顺序表的初始化函数 SeqListInit 和销毁函数 SeqListDestroy

void SeqListInit(SeqList* ps)
{assert(ps);ps->a = NULL;ps->capacity = ps->size = 0;
}void SeqListDestroy(SeqList* ps)
{assert(ps);if (ps->a){free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0;}
}

增删查改操作

顺序表的增删查改操作是对数据进行管理的核心部分。我们实现了以下函数来完成这些操作:

  • SeqListPrint:打印顺序表中的所有元素。
  • SeqListPushBack:在顺序表的末尾插入一个元素。
  • SeqListPushFront:在顺序表的头部插入一个元素。
  • SeqListPopFront:从顺序表的头部删除一个元素。
  • SeqListPopBack:从顺序表的末尾删除一个元素。
  • SeqListFind:在顺序表中查找指定元素,并返回其索引位置。
  • SeqListInsert:在顺序表的指定位置插入一个元素。
  • SeqListErase:从顺序表的指定位置删除一个元素。
void SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0; i < ps->size; ++i){printf("%d ", ps->a[i]);}printf("\n");
}void SeqListPushBack(SeqList* ps, SLDateType x)
{SeqListInsert(ps, ps->size, x);
}void SeqListPushFront(SeqList* ps, SLDateType x)
{SeqListInsert(ps, 0, x);
}void SeqListPopFront(SeqList* ps)
{SeqListErase(ps, 0);
}void SeqListPopBack(SeqList* ps)
{SeqListErase(ps, ps->size - 1);
}int SeqListFind(SeqList* ps, SLDateType x)
{assert(ps);for (int i = 0; i < ps->size; ++i){if (ps->a[i] == x) return i;}return -1;
}void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);memmove(ps->a + pos + 1, ps->a + pos, (ps->size - pos) * sizeof(SLDateType));ps->a[pos] = x;ps->size++;
}void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);memmove(ps->a + pos, ps->a + pos + 1, (ps->size - pos - 1) * sizeof(SLDateType));ps->size--;
}

测试代码

为了验证顺序表的正确性,我们编写了一个简单的测试代码。在测试代码中,我们创建了一个顺序表,并进行了一系列的增删查改操作。

int main()
{SeqList sl;SeqListInit(&sl);SeqListPushBack(&sl, 1);SeqListPushBack(&sl, 2);SeqListPushBack(&sl, 3);SeqListPushBack(&sl, 4);SeqListPushBack(&sl, 5);SeqListPushBack(&sl, 6);SeqListPushBack(&sl, 7);SeqListPushBack(&sl, 8);printf("PushBack 测试(尾插8个数):\n");SeqListPrint(&sl);SeqListPushFront(&sl, 9);SeqListPushFront(&sl, 9);SeqListPushFront(&sl, 9);printf("PushFront 测试(头插三个9):\n");SeqListPrint(&sl);SeqListPopFront(&sl);SeqListPopFront(&sl);SeqListPopFront(&sl);printf("PopFront 测试(头删三个数):\n");SeqListPrint(&sl);SeqListPopBack(&sl);SeqListPopBack(&sl);printf("PopBack 测试(尾删两个数):\n");SeqListPrint(&sl);printf("Find 测试(找5和8):\n");int pos = SeqListFind(&sl, 5);if (pos != -1) printf("5 在下标为%d的位置\n", pos);else printf("%d没找到!\n", 5);pos = SeqListFind(&sl, 8);if (pos != -1) printf("8 在下标为%d的位置\n", pos);else printf("%d 没找到!\n", 8);SeqListDestroy(&sl);return 0;
}

在这里插入图片描述

完整代码

//SeqList.h
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity;
}SeqList;void SLCheckCapacity(SeqList* ps);// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);
//Seqlist.c
#include "SeqList.h"void SLCheckCapacity(SeqList* ps)
{assert(ps);if (ps->size == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDateType* tmp = realloc(ps->a, newCapacity * sizeof(SLDateType));if (tmp == NULL){printf("realloc fail!\n");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}
}// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps)
{assert(ps);ps->a = NULL;ps->capacity = ps->size = 0;
}
void SeqListDestroy(SeqList* ps)
{assert(ps);if (ps->a){free(ps->a);ps->a = NULL;ps->capacity = ps->size = 0;}
}void SeqListPrint(SeqList* ps)
{assert(ps);for (int i = 0; i < ps->size; ++i){printf("%d ", ps->a[i]);}printf("\n");
}
void SeqListPushBack(SeqList* ps, SLDateType x)
{SeqListInsert(ps, ps->size, x);
}
void SeqListPushFront(SeqList* ps, SLDateType x)
{SeqListInsert(ps, 0, x);
}
void SeqListPopFront(SeqList* ps)
{SeqListErase(ps, 0);
}
void SeqListPopBack(SeqList* ps)
{SeqListErase(ps, ps->size);
}// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x)
{assert(ps);for (int i = 0; i < ps->size; ++i){if (ps->a[i] == x) return i;}return -1;
}
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);SLCheckCapacity(ps);memmove(ps->a + pos + 1, ps->a + pos, (ps->size - pos) * sizeof(SLDateType));ps->a[pos] = x;ps->size++;
}
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos)
{assert(ps);assert(pos >= 0 && pos <= ps->size);memmove(ps->a + pos, ps->a + pos + 1, (ps->size - pos) * sizeof(SLDateType));ps->size--;
}
//test.c
#include"SeqList.h"int main()
{SeqList sl;SeqListInit(&sl);SeqListPushBack(&sl, 1);SeqListPushBack(&sl, 2);SeqListPushBack(&sl, 3);SeqListPushBack(&sl, 4);SeqListPushBack(&sl, 5);SeqListPushBack(&sl, 6);SeqListPushBack(&sl, 7);SeqListPushBack(&sl, 8);printf("PushBack 测试(尾插8个数):\n");SeqListPrint(&sl);SeqListPushFront(&sl, 9);SeqListPushFront(&sl, 9);SeqListPushFront(&sl, 9);printf("PushFront 测试(头插三个9):\n");SeqListPrint(&sl);SeqListPopFront(&sl);SeqListPopFront(&sl);SeqListPopFront(&sl);printf("PopFront 测试(头删三个数):\n");SeqListPrint(&sl);SeqListPopBack(&sl);SeqListPopBack(&sl);printf("PopBack 测试(尾删两个数):\n");SeqListPrint(&sl);printf("Find 测试(找5和8):\n");int pos = SeqListFind(&sl, 5);if (pos != -1) printf("5 在下标为%d的位置\n", pos);else printf("%d没找到!\n", 5);pos = SeqListFind(&sl, 8);if (pos != -1) printf("8 在下标为%d的位置\n", pos);else printf("%d 没找到!\n", 8);SeqListDestroy(&sl);return 0;
}

通过上述代码,我们实现了一个简单的顺序表,并对其进行了增删查改操作的测试。顺序表是一种非常常用的数据结构,能够高效地管理线性数据。

单链表的增删查改

单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和指向下一个节点的指针。我将介绍如何使用C语言实现单链表的增删查改操作。

数据结构定义

首先,我们需要定义单链表的数据结构。在给出的代码中,使用了SListNode结构体表示每个节点,其中包含一个整型数据 data 和一个指向下一个节点的指针 next。另外,定义了一个类型别名 SLTDateType 来表示节点数据的类型。

typedef int SLTDateType;
typedef struct SListNode
{SLTDateType data;struct SListNode* next;
} SListNode;

动态申请节点

为了创建一个新的节点,我们需要动态申请内存空间,并将数据和指针赋值。在给出的代码中,定义了一个 BuySListNode 函数来完成这个任务。

SListNode* BuySListNode(SLTDateType x)
{SListNode* newNode = (SListNode*)malloc(sizeof(SListNode));if (newNode == NULL){printf("malloc fail!");exit(-1);}newNode->next = NULL;newNode->data = x;return newNode;
}

单链表的尾插和头插

尾插操作是将新节点插入到链表末尾。给出的代码中,定义了 SListPushBack 函数来实现尾插操作。它首先创建一个新节点,并找到链表的尾部,然后将新节点连接到尾节点的后面。

void SListPushBack(SListNode** pplist, SLTDateType x)
{assert(pplist);SListNode* newNode = BuySListNode(x);SListNode* tail = *pplist;if (tail == NULL) {*pplist = newNode;return;}else {while (tail->next) {tail = tail->next;}}tail->next = newNode;
}

头插操作是将新节点插入到链表的头部。给出的代码中,定义了 SListPushFront 函数来实现头插操作。它首先创建一个新节点,并将新节点的指针指向原链表的头节点,然后更新链表的头节点为新节点。

void SListPushFront(SListNode** pplist, SLTDateType x) 
{assert(pplist);SListNode* newNode = BuySListNode(x);newNode->next = *pplist;*pplist = newNode;
}

单链表的尾删和头删

尾删操作是删除链表的最后一个节点。给出的代码中,定义了 SListPopBack 函数来实现尾删操作。它首先找到链表的倒数第二个节点,然后释放最后一个节点的内存,并将倒数第二个节点的 next 指针置空。

void SListPopBack(SListNode** pplist)
{assert(pplist);assert(*pplist);SListNode* tail = *pplist;SListNode* prev = NULL;if (tail->next == NULL) {*pplist = NULL;}else {while (tail->next) {prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}

头删操作是删除链表的第一个节点。给出的代码中,定义了 SListPopFront 函数来实现头删操作。它首先将链表的头节点保存起来,然后更新链表的头节点为原头节点的下一个节点,并释放保存的头节点的内存。

void SListPopFront(SListNode** pplist)
{assert(pplist);assert(*pplist);SListNode* front = *pplist;*pplist = (*pplist)->next;free(front);
}

单链表的查找

查找操作是在链表中寻找特定的数据。给出的代码中,定义了 SListFind 函数来实现查找操作。它遍历链表,直到找到数据等于目标值的节点,然后返回该节点的指针。

SListNode* SListFind(SListNode* plist, SLTDateType x)
{assert(plist);SListNode* cur = plist;while (cur->next && cur->data != x) {cur = cur->next;}if (cur->next) {return cur;}return NULL;
}

单链表的插入和删除

在给出的代码中,还定义了 SListInsertAfter、SListEraseAfter、SListInsertSListErase 函数来实现在指定位置之后插入节点、删除指定位置之后的节点、在指定位置之前插入节点以及删除指定位置的节点。

//具体的实现细节请参考给出的代码。

销毁链表

为了释放链表占用的内存空间,给出的代码中,定义了 SListDestroy 函数来销毁链表。它遍历链表的每个节点,依次释放内存,并将链表的头节点置为NULL

void SListDestroy(SListNode** pplist)
{assert(pplist);SListNode* cur = *pplist;while (cur){SListNode* next = cur->next;free(cur);cur = next;}*pplist = NULL;
}

测试代码

给出的代码还包括了一个 main 函数来测试上述函数的功能。它首先创建一个空链表,然后进行了一系列的增删查改操作,并输出每一步操作后的链表结果。

int main()
{SListNode* plist = NULL;// 测试代码return 0;
}

以上就是关于C语言实现单链表的增删查改的代码解析和使用方法。
在这里插入图片描述

完整代码

//slist.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLTDateType;
typedef struct SListNode
{SLTDateType data;struct SListNode* next;
}SListNode;// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x);
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x);
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x);
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?
void SListInsertAfter(SListNode* pos, SLTDateType x);
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?
void SListEraseAfter(SListNode* pos);// 在pos的前面插入
void SListInsert(SListNode** pplist, SListNode* pos, SLTDateType x);
// 删除pos位置
void SListErase(SListNode** pplist, SListNode* pos);
//销毁链表
void SListDestroy(SListNode** pplist);
//slist.c
#include "slist.h"// 动态申请一个节点
SListNode* BuySListNode(SLTDateType x)
{SListNode* newNode = (SListNode*)malloc(sizeof(SListNode));if (newNode == NULL){printf("malloc fail!");exit(-1);}newNode->next = NULL;newNode->data = x;
}
// 单链表打印
void SListPrint(SListNode* plist)
{SListNode* cur = plist;while (cur != NULL){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTDateType x)
{assert(pplist);SListNode* newNode = BuySListNode(x);SListNode* tail = *pplist;//找尾if (tail == NULL) {*pplist = newNode;return;}else {while (tail->next) {tail = tail->next;}}tail->next = newNode;
}
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTDateType x) 
{assert(pplist);SListNode* newNode = BuySListNode(x);newNode->next = *pplist;*pplist = newNode;
}
// 单链表的尾删
void SListPopBack(SListNode** pplist)
{assert(pplist);assert(*pplist);SListNode* tail = *pplist;SListNode* prev = NULL; //尾的前一个//找尾if (tail->next == NULL) {*pplist = NULL;}else{while (tail->next) {prev = tail;tail = tail->next;}free(tail);prev->next = NULL;}
}
// 单链表头删
void SListPopFront(SListNode** pplist)
{assert(pplist);assert(*pplist);SListNode* front = *pplist;*pplist = (*pplist)->next;free (front);
}
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTDateType x)
{assert(plist);SListNode* cur = plist;while (cur->next && cur->data != x) {cur = cur->next;}if (cur->next) {return cur;}return NULL;
}
// 单链表在pos位置之后插入x
// 分析思考为什么不在pos位置之前插入?如果在pos之前经行插入需要遍历一遍前面的链表,效率低
void SListInsertAfter(SListNode* pos, SLTDateType x)
{assert(pos);SListNode* newNode = BuySListNode(x);SListNode* tmp = pos->next;pos->next = newNode;newNode->next = tmp;
}
// 单链表删除pos位置之后的值
// 分析思考为什么不删除pos位置?同上
void SListEraseAfter(SListNode* pos)
{assert(pos);SListNode* del = pos->next;pos->next = pos->next->next;free(del);
}// 在pos的前面插入
void SListInsert(SListNode** pplist, SListNode* pos, SLTDateType x)
{assert(pplist);assert(pos);if (pos == *pplist){SListPushFront(pplist, x);return;}SListNode* newNode = BuySListNode(x);SListNode* prev = *pplist;while (prev->next != pos){prev = prev->next;}newNode->next = pos;prev->next = newNode;
}
// 删除pos位置
void SListErase(SListNode** pplist, SListNode* pos)
{assert(pplist);assert(*pplist);assert(pos);SListNode* prev = *pplist;SListNode* del = pos;while (prev->next != pos){prev = prev->next;}prev->next = pos->next;free(del);
}
//销毁链表
void SListDestroy(SListNode** pplist)
{assert(pplist);SListNode* cur = *pplist;while (cur){SListNode* next = cur->next;free(cur);cur = next;}*pplist = NULL;
}
//test.c
#include"slist.h"int main()
{SListNode* plist = NULL;SListPushBack(&plist, 1);SListPushBack(&plist, 2);SListPushBack(&plist, 3);SListPushBack(&plist, 4);SListPushBack(&plist, 5);SListPushBack(&plist, 6);SListPushBack(&plist, 7);SListPushBack(&plist, 8);printf("PushBack 测试(尾插8个数):\n");SListPrint(plist);SListPushFront(&plist, 0);SListPushFront(&plist, 0);SListPushFront(&plist, 0);printf("PushFront 测试(头插三个0):\n");SListPrint(plist);SListPopBack(&plist);SListPopBack(&plist);printf("PopBack 测试(尾删两个数):\n");SListPrint(plist);SListPopFront(&plist);SListPopFront(&plist);SListPopFront(&plist);printf("PopFront 测试(头删三个数):\n");SListPrint(plist);printf("Find 测试(找4):\n");SListPrint(SListFind(plist, 4));printf("InsertAfter 测试(找4后插):\n");SListInsertAfter(SListFind(plist, 4), 999);SListPrint(plist);printf("EraseAfter 测试(找4后删):\n");SListEraseAfter(SListFind(plist, 4));SListPrint(plist);printf("Insert 测试(找4前插):\n");SListInsert(&plist, SListFind(plist, 4), 999);SListPrint(plist);printf("Erase 测试(找4删4):\n");SListErase(&plist, SListFind(plist, 4));SListPrint(plist);SListDestroy(&plist);printf("Destroy!\n");SListPrint(plist);return 0;
}

总结

本文首先介绍了顺序表的定义与初始化,包括动态数组的使用、容量检查和扩容操作等内容。然后详细讲解了顺序表的增删查改操作,并给出了相应的代码示例。接着,文章转向单链表的实现,包括节点的定义、动态申请节点、尾插和头插操作、尾删和头删操作、查找、插入和删除等操作的具体实现。最后,通过测试代码验证了顺序表和单链表的功能正常运行。

通过本文的学习,读者可以加深对顺序表和单链表的理解,掌握这两种数据结构的增删查改的具体实现方法。同时,对于初学者来说,也能够更好地理解数据结构和算法在实际编程中的应用,为日后的软件开发打下良好的基础。

希望本文能为您对顺序表和单链表的理解和应用提供帮助,欢迎大家在实践中不断探索和应用这些知识,提升自己的编程技能。

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

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

相关文章

SpringBoot+AOP+Redis 防止重复请求提交

本文项目基于以下教程的代码版本&#xff1a; https://javaxbfs.blog.csdn.net/article/details/135224261 代码仓库: springboot一些案例的整合_1: springboot一些案例的整合 1、实现步骤 2.引入依赖 我们需要redis、aop的依赖。 <dependency><groupId>org.spr…

Unity C# Mp3 Mp4 音频 视频 合成

需求 将声音文件合并到视频中 限制 暂时只支持Windows使用 准备 下载ffmpeg.exe 解压后得到exe https://ffmpeg.org/download.html#releases 注意事项&#xff1a; 目录要在一起 代码 public void StartExe(){if (File.Exists(ffmpegExe)){ string mp4;string mp3;//…

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第四节 参数传递对堆栈的影响 1

深入浅出图解C#堆与栈 C# Heaping VS Stacking 第四节 参数传递对堆栈的影响1 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基本工作原理](http…

将H5封装为App:实现跨平台移动应用开发的新趋势

H5技术指的是HTML5、CSS3和JavaScript等一系列前端技术的综合应用。它具有跨平台、开发成本低、开发周期短等优势&#xff0c;可以快速实现丰富的界面和交互效果。而原生应用开发受限于操作系统的差异&#xff0c;需要分别开发不同平台的应用&#xff0c;这就增加了开发成本和工…

2023年度总结(找到工作)

转眼2023年结束了&#xff0c;今天已经12月29日了。从2022年12月25日考研失败后&#xff0c;2023年就变成了找工作以及上班度日的时光了。针对2023年&#xff0c;我想对自己所说的是&#xff1a;终于找到工作了。作为一个普通的专升本&#xff0c;考研落榜生来说&#xff0c;能…

熊猫目标检测数据集VOC格式1200张

熊猫是中国的国宝&#xff0c;也是世界上最受人喜爱的动物之一。熊猫以其独特的外貌和与生俱来的文化象征意义而闻名于世。它们是一种大型的食草动物&#xff0c;主要分布在中国中部地区的竹林和高山地带。 熊猫的身形圆润笨拙&#xff0c;黑白分明&#xff0c;拥有圆润的脸庞…

C++进阶--多态

多态 一、多态的概念二、多态的定义及实现2.1 构成多态的两个硬性条件2.2 虚函数的重写2.2.1 协变(基类与派生类虚函数返回值类型不同)2.2.2 析构函数的重写(基类与派生类析构函数的名字不同) 2.3 final和override2.4 重载、覆盖&#xff08;重写&#xff09;、隐藏&#xff08…

基于Java图书借阅管理系统设计与实现(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

英语中修饰头发的形容词顺序是怎么样的(加补充)

一、英语描述发型 :漂亮长短形状颜色头发。 例如她有一头美丽的黑色的直发。She has beautiful long straight black hair.二、多个形容词修饰同一名词时的顺序是固定的&#xff0c;其顺序为&#xff1a;①冠词、指示代词、不定代词、物主代词②序数词基数词③一般性描绘形容词…

小红书品牌曝光方式有哪些,小红书投放总结!

辛辛苦苦撰写了笔记&#xff0c;却没有人看。不懂平台的曝光策略&#xff0c;就无法获得预期的营销结果。今天就来分享下小红书品牌曝光方式有哪些&#xff0c;小红书投放总结&#xff01; 第一招&#xff0c;打造账号IP 在小红书平台进行传播&#xff0c;打造账号IP非常重要。…

Apache Doris (五十六): Doris Join类型 - 四种Join对比

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 Doris 支持两种物理算子,一类是…

竞赛保研 基于情感分析的网络舆情热点分析系统

文章目录 0 前言1 课题背景2 数据处理3 文本情感分析3.1 情感分析-词库搭建3.2 文本情感分析实现3.3 建立情感倾向性分析模型 4 数据可视化工具4.1 django框架介绍4.2 ECharts 5 Django使用echarts进行可视化展示5.1 修改setting.py连接mysql数据库5.2 导入数据5.3 使用echarts…

2023 楚慧杯 --- Crypto wp

文章目录 初赛so large e 决赛JIGE 初赛 so large e 题目&#xff1a; from Crypto.Util.number import * from Crypto.PublicKey import RSA from flag import flag import randomm bytes_to_long(flag)p getPrime(512) q getPrime(512) n p*q e random.getrandbits(1…

全新研发体系助力产品落地 传音控股成科技出海代表

一直以来&#xff0c;手机都被认为是所有新技术的最佳应用载体&#xff0c;尤其是在数字化、智能化时代&#xff0c;技术创新能力决定着手机厂商的生存与发展。 作为全球新兴市场手机行业的中坚力量之一&#xff0c;传音控股始终坚持以技术创新为驱动&#xff0c;围绕用户需求…

最大后验概率法

在贝叶斯统计中&#xff0c;最大后验概率&#xff08;maximum a posteriori, MAP&#xff09;估计是对后验分布的模的估计。MAP可根据经验数据获得未观测量的点估计。它与最大似然&#xff08;ML&#xff09;估计方法密切相关&#xff0c;但采用了一个包含先验分布的增强优化目…

【数据结构】七、图

一、概念 图&#xff1a;记为G(V,E) 有向图&#xff1a;每条边都有方向 无向图&#xff1a;边无方向 完全图&#xff1a;每个顶点都与剩下的所有顶点相连 完全有向图有n(n-1)条边&#xff1b;完全无向图有n(n-1)/2条边 带权图&#xff1a;边上标有数值的图 连通图&#…

使用 pytest 相关特性重构 appium_helloworld

一、前置说明 在 pytest 基础讲解 章节,介绍了 pytest 的特性和基本用法,现在我们可以使用 pytest 的一些机制,来重构 appium_helloworld 。 appium_helloworld 链接: 编写第一个APP自动化脚本 appium_helloworld ,将脚本跑起来 代码目录结构: pytest.ini 设置: [pyt…

Goby 漏洞发布| QNAP NAS authLogin.cgi 命令执行漏洞(CVE-2017-6361)

漏洞名称&#xff1a;QNAP NAS authLogin.cgi 命令执行漏洞&#xff08;CVE-2017-6361&#xff09; English Name&#xff1a;QNAP NAS authLogin.cgi command execution vulnerability (CVE-2017-6361) CVSS core: 9.8 影响资产数&#xff1a; 2637547 漏洞描述&#xff1…

pd工具箱 Parallels Toolbox

Parallels Toolbox是一款适用于Mac和PC的强大工具箱软件&#xff0c;集成了多种实用的工具和功能&#xff0c;旨在帮助用户提高工作效率和生产力。它提供了文件管理、截图、音频视频处理、清理工具等众多工具&#xff0c;使用户能够方便快捷地完成各种常见任务。Parallels Tool…

“踩坑”经验分享:Swift语言落地实践

作者 | 路涛、艳红 导读 Swift 是一种适用于iOS/macOS应用开发、服务器端的编程语言。自2014年苹果发布 Swift 语言以来&#xff0c;Swift5 实现了 ABI 稳定性、Module 稳定性和Library Evolution&#xff0c;与Objective-C&#xff08;下文简称“OC”&#xff09;相比&#xf…