当前位置: 首页 > news >正文

顺序表,链表,顺序栈,顺序循环队列,链式队列的基本操作

数据结构的学习笔记,有点混杂,以后有时间再来整理

中文解释是用来凑字数的


目录

1.顺序表

2.链表

3.原地逆置链表

4.单链表的基本操作

5.顺序栈(使用数组实现的栈)的基本操作

6.顺序循环队列的基本操作

7.链式队列的基本操作


1.顺序表

#include<stdio.h>//顺序表#define MaxSize 50
typedef int ElemType;typedef struct {ElemType data[MaxSize];int length;
}SqList;void printList(bool result, SqList L) {if (!result) {printf("false");}else{for (int i = 0; i < L.length; i++) {printf("%3d", L.data[i]);}printf("\n");}
}bool insertList(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];}L.data[i - 1] = e;L.length++;return true;
}bool deleteList(SqList& L, int i, ElemType& e) {if (i<1 || i>L.length) {return false;}e = L.data[i - 1];for (int j = i; j < L.length; j++) {L.data[j - 1] = L.data[j];}L.length--;return true;
}int main() {SqList L;L.data[0] = 1;L.data[1] = 2;L.data[2] = 3;L.length = 3;ElemType e;scanf_s("%d", &e);//插入的元素bool result;result = insertList(L, 2, e);printList(result, L);int i;scanf_s("%d", &i);//删除的位置result = deleteList(L, i, e);printList(result, L);return 0;
}

这段代码实现了一个顺序表(线性表)的基本操作,包括插入元素和删除元素。顺序表的最大容量为50个元素。代码的功能和执行步骤如下:

  1. 定义顺序表结构体:定义了一个结构体 SqList,包括一个存储数据的数组 data 和表示当前长度的变量 length

  2. 打印列表函数printList 函数用于打印顺序表的内容。如果操作失败,打印“false”;否则,依次打印顺序表中的每个元素。

  3. 插入元素函数insertList 函数在顺序表的指定位置插入一个新元素。插入操作成功返回 true,失败返回 false。插入操作的步骤包括:

    • 检查插入位置是否合法。
    • 检查顺序表是否已满。
    • 将插入位置及其后的元素后移一位。
    • 插入新元素,并增加顺序表的长度。
  4. 删除元素函数deleteList 函数删除顺序表中指定位置的元素。删除操作成功返回 true,失败返回 false。删除操作的步骤包括:

    • 检查删除位置是否合法。
    • 记录被删除的元素。
    • 将删除位置后的元素前移一位。
    • 减少顺序表的长度。
  5. 主函数main 函数初始化一个顺序表 L,并进行以下操作:

    • 初始化顺序表,包含三个元素:1、2、3。
    • 从用户输入中读取一个元素,将其插入到顺序表的第2个位置。
    • 调用 printList 函数打印插入操作后的顺序表。
    • 从用户输入中读取一个位置,删除该位置的元素。
    • 调用 printList 函数打印删除操作后的顺序表。

代码中的 scanf_s 函数用于从控制台读取用户输入的插入元素和删除位置。程序的执行结果将根据用户输入的具体值而变化。

2.链表

#include<stdio.h>
#include<stdlib.h>//链表typedef int ElemType;typedef struct LNode {ElemType data;struct LNode* next;
}LNode, * LinkList;//头插法建立链表
void headInsertList(LinkList& L) {L = (LinkList)malloc(sizeof(LNode));L->next = NULL;ElemType x;scanf_s("%d", &x);LNode* node;while (x != 9999){node = (LNode*)malloc(sizeof(LNode));node->data = x;node->next = L->next;L->next = node;scanf_s("%d", &x);}
}//尾插法建立链表
void tailInsertList(LinkList& L) {L = (LinkList)malloc(sizeof(LNode));LNode* r, * node;r = L;ElemType x;scanf_s("%d", &x);while (x != 9999){node = (LNode*)malloc(sizeof(LNode));node->data = x;r->next = node;r = node;scanf_s("%d", &x);}r->next = NULL;
}//按序号查找节点
LNode* getElemByPos(LinkList L, int i) {if (i < 0) {return NULL;}if (i == 0) {return L;}int j = 1;LNode* p = L->next; //第一个元素节点while (p && j < i){p = p->next;j++;}return p;
}//按值查找节点
LNode* getElemByValue(LinkList L, ElemType e) {LNode* p = L->next;while (p && p->data != e){p = p->next;}return p;
}//在指定位置插入节点
bool insertElemByPos(LinkList L, int i, ElemType e) {LNode* p = getElemByPos(L, i - 1);if (p == NULL) {return false;}LNode* q = (LNode*)malloc(sizeof(LNode));q->data = e;q->next = p->next;p->next = q;return true;
}//删除指定位置节点
bool deleteElemByPos(LinkList L, int i) {LNode* p = getElemByPos(L, i - 1);if (p == NULL) {return false;}LNode* q = p->next;// 要删除的位置是链表长度+1的位置,get函数获取到最后一个节点,p不为空,但后继为NULLif (q == NULL){return false;}p->next = q->next;free(q);return true;
}void printList(LinkList L) {while (L = L->next){printf("%3d", L->data);}printf("\n");
}int main() {LinkList L;//headInsertList(L);tailInsertList(L);printList(L);//LNode* result = getElemByPos(L, 2);//LNode* result = getElemByValue(L, 4);//printf("%d", result->data);//bool result = insertElemByPos(L, 2, 99);//if (result) {//	printList(L);//}deleteElemByPos(L, 2);printList(L);return 0;
}

这段代码实现了单链表的基本操作,包括创建、查找、插入和删除节点。链表是一种动态数据结构,允许在任意位置插入和删除元素。以下是代码的详细说明:

  1. 定义链表节点结构体:定义了一个结构体 LNode,包含两个成员:存储数据的 data 和指向下一个节点的指针 next。同时定义了 LinkList 类型,表示指向 LNode 的指针。

  2. 头插法建立链表headInsertList 函数通过头插法创建链表,步骤如下:

    • 初始化头节点 L
    • 从用户输入读取数据 x
    • 当输入值不是 9999 时,创建新节点,并将其插入到链表的头部。
  3. 尾插法建立链表tailInsertList 函数通过尾插法创建链表,步骤如下:

    • 初始化头节点 L 和尾指针 r
    • 从用户输入读取数据 x
    • 当输入值不是 9999 时,创建新节点,并将其插入到链表的尾部。
    • 最后将尾节点的 next 设为 NULL
  4. 按序号查找节点getElemByPos 函数根据给定的位置 i 查找对应的节点。返回找到的节点指针,若未找到则返回 NULL

  5. 按值查找节点getElemByValue 函数根据给定的值 e 查找对应的节点。返回找到的节点指针,若未找到则返回 NULL.

  6. 在指定位置插入节点insertElemByPos 函数在指定位置 i 插入值为 e 的新节点,步骤如下:

    • 先找到位置 i-1 处的节点 p
    • p 为空,返回 false 表示插入失败。
    • 创建新节点 q,将其插入到 p 的后面。
  7. 删除指定位置节点deleteElemByPos 函数删除位置 i 处的节点,步骤如下:

    • 先找到位置 i-1 处的节点 p
    • p 为空或 p 的后继为空,返回 false 表示删除失败。
    • 删除 p 的后继节点 q,并释放其内存。
  8. 打印链表printList 函数从头节点开始,依次打印链表中每个节点的数据。

  9. 主函数main 函数进行以下操作:

    • 初始化一个链表 L
    • 使用尾插法建立链表。
    • 打印链表内容。
    • 删除位置 2 处的节点。
    • 再次打印链表内容。

通过这段代码,可以灵活地进行链表的创建、查找、插入和删除操作,并在控制台上展示结果。

3.原地逆置链表

#include<stdio.h>
#include<stdlib.h>typedef int ElemType;typedef struct LNode {ElemType data;struct LNode* next;
}LNode, * LinkList;//尾插法建立链表
void tailInsertList(LinkList& L) {L = (LinkList)malloc(sizeof(LNode));LNode* r, * node;r = L;ElemType x;scanf_s("%d", &x);while (x != 9999){node = (LNode*)malloc(sizeof(LNode));node->data = x;r->next = node;r = node;scanf_s("%d", &x);}r->next = NULL;
}//找到中间结点,将链表分成两半
void findMiddle(LinkList L, LinkList& L2) {L2 = (LinkList)malloc(sizeof(LNode));//给L2头结点分配内存LNode* pcur, * ppre;//pcur走两步,ppre走一步pcur = ppre = L->next;//同时指向第一个元素结点while (pcur != NULL) {pcur = pcur->next;if (pcur == NULL){break;}pcur = pcur->next;//走两步if (pcur == NULL) {break;}ppre = ppre->next;}//结束时ppre处于正中间,L2->next = ppre->next;//让L2指向后半条链表ppre->next = NULL;//前半条链表最后一个结点断链
}//原地逆转链表
void reverseList(LinkList L2) {LNode* r, * s, * t;r = L2->next;//r指向L2第1个结点if (r == NULL) {//空链表return;}s = r->next;//r指向L2第2个结点if (s == NULL) {//链表只有一个结点return;}t = s->next;while (t != NULL){s->next = r;r = s;s = t;t = t->next;}s->next = r;L2->next->next = NULL;L2->next = s;
}//合并两个链表
void mergeList(LinkList L, LinkList L2) {//pcur指向新链表当前位置,p指向L即将被插入的元素,q指向L2即将被插入的元素LNode* pcur, * p, * q;pcur = p = L->next;//pcur和p指向L1的第一个结点,建立新链q = L2->next;//q指向L2的第一个结点p = p->next;//L的第一个结点已经在新链中while (p != NULL && q != NULL){pcur->next = q;q = q->next;pcur = pcur->next;pcur->next = p;p = p->next;pcur = pcur->next;}if (p != NULL) {pcur->next = p;}if (q != NULL) {pcur->next = q;}
}//打印链表
void printList(LinkList L) {while (L = L->next){printf("%3d", L->data);}printf("\n");
}int main() {LinkList L;tailInsertList(L);printList(L);printf("----------------------------------\n");LinkList L2;//后半边链表findMiddle(L, L2);//分为两个链表printList(L);printList(L2);printf("----------------------------------\n");reverseList(L2);//原地逆转L2printList(L2);printf("----------------------------------\n");mergeList(L, L2);free(L2);printList(L);return 0;
}

这段代码实现了对单链表的创建、分割、逆转和合并操作。以下是代码的详细功能和执行步骤:

  1. 定义链表节点结构体

    • 定义了一个结构体 LNode,包含两个成员:存储数据的 data 和指向下一个节点的指针 next
    • 定义了 LinkList 类型,表示指向 LNode 的指针。
  2. 尾插法建立链表

    • tailInsertList 函数通过尾插法创建链表,步骤如下:
      • 初始化头节点 L 和尾指针 r
      • 从用户输入读取数据 x
      • 当输入值不是 9999 时,创建新节点,并将其插入到链表的尾部。
      • 最后将尾节点的 next 设为 NULL
  3. 找到中间节点,将链表分成两半

    • findMiddle 函数找到链表的中间节点,并将链表分成两半,步骤如下:
      • 初始化两个指针 pcurppre,都指向第一个元素节点。
      • pcur 每次走两步,ppre 每次走一步,直到 pcur 走到链表末尾。
      • 结束时,ppre 位于链表中间。
      • L2 指向后半部分链表,pprenext 设为 NULL,断开前半部分链表。
  4. 原地逆转链表

    • reverseList 函数将链表 L2 原地逆转,步骤如下:
      • 初始化指针 rstr 指向第一个节点,s 指向第二个节点,t 指向第三个节点。
      • snext 指向 r,然后 rst 分别向前移动一位。
      • 继续上述操作,直到 t 为空,链表逆转完成。
  5. 合并两个链表

    • mergeList 函数将链表 LL2 交替合并,步骤如下:
      • 初始化指针 pcur 指向新链表的当前位置,p 指向 L 即将被插入的元素,q 指向 L2 即将被插入的元素。
      • 交替插入 pq 到新链表中,直到 pq 为空。
      • p 不为空,将剩余的 p 接到新链表末尾。
      • q 不为空,将剩余的 q 接到新链表末尾。
  6. 打印链表

    • printList 函数从头节点开始,依次打印链表中每个节点的数据。
  7. 主函数

    • main 函数进行以下操作:
      • 初始化一个链表 L 并通过尾插法建立链表。
      • 打印链表内容。
      • 调用 findMiddle 函数将链表分为两半,分别打印前半部分和后半部分。
      • 调用 reverseList 函数逆转后半部分链表,并打印结果。
      • 调用 mergeList 函数合并两个链表,释放 L2 的内存,并打印最终合并的链表。

这段代码通过一系列的操作展示了链表的基本操作及其应用,能够处理链表的分割、逆转和合并等复杂操作。

4.单链表的基本操作

#include <stdio.h>
#include <stdlib.h>typedef int ElemType;typedef struct LNode {ElemType data;struct LNode* next;
}LNode, * LinkList;//尾插法建立链表
LinkList tailInserList(LinkList& L) {L = (LNode*)malloc(sizeof(LNode));LNode* r, * s;r = L;ElemType x;scanf_s("%d", &x);while (x != 9999){s = (LNode*)malloc(sizeof(LNode));s->data = x;r->next = s;r = s;scanf_s("%d", &x);}r->next = NULL;return L;
}//按位置查找元素
LNode* getElemByPos(LinkList L, int i) {LNode* p;int j = 1;p = L->next;if (i < 0) {return NULL;}if (i == 0){return L;}while (p && j < i){p = p->next;j++;}return p;
}//按位置插入元素
bool insertElemByPos(LinkList L, int i, ElemType e) {LNode* p = getElemByPos(L, i - 1);if (p == NULL) {return false;}LNode* q = (LNode*)malloc(sizeof(LNode));q->data = e;q->next = p->next;p->next = q;return true;
}//按位置删除元素
bool deleteElemByPos(LinkList L, int i) {LNode* p = getElemByPos(L, i - 1);if (p == NULL) {return false;}LNode* q = p->next;if (q == NULL) {return false;}p->next = q->next;free(q);q = NULL;return true;
}//打印链表
void printList(LinkList L) {while (L = L->next){printf("%3d", L->data);}printf("\n");
}int main() {LinkList L;tailInserList(L);printf("%d\n", getElemByPos(L, 2)->data);insertElemByPos(L, 2, 99);printList(L);deleteElemByPos(L, 4);printList(L);return 0;
}

这段代码实现了一个单链表的基本操作,包括链表的创建、按位置查找、按位置插入和按位置删除元素,以及打印链表。以下是代码的详细说明:

  1. 定义链表节点结构体

    • 定义了一个结构体 LNode,包含两个成员:存储数据的 data 和指向下一个节点的指针 next
    • 定义了 LinkList 类型,表示指向 LNode 的指针。
  2. 尾插法建立链表

    • tailInserList 函数通过尾插法创建链表,步骤如下:
      • 初始化头节点 L 和尾指针 r
      • 从用户输入读取数据 x
      • 当输入值不是 9999 时,创建新节点 s,并将其插入到链表的尾部。
      • 最后将尾节点的 next 设为 NULL
      • 返回链表的头指针 L
  3. 按位置查找元素

    • getElemByPos 函数根据给定的位置 i 查找对应的节点,步骤如下:
      • 初始化指针 p,指向头节点的下一个节点,计数器 j 从1开始。
      • i 小于0,返回 NULL
      • i 为0,返回头节点 L
      • 遍历链表,直到找到位置 i 的节点,返回该节点指针,若未找到则返回 NULL
  4. 按位置插入元素

    • insertElemByPos 函数在指定位置 i 插入值为 e 的新节点,步骤如下:
      • 先找到位置 i-1 处的节点 p
      • p 为空,返回 false 表示插入失败。
      • 创建新节点 q,将其插入到 p 的后面。
      • 返回 true 表示插入成功。
  5. 按位置删除元素

    • deleteElemByPos 函数删除位置 i 处的节点,步骤如下:
      • 先找到位置 i-1 处的节点 p
      • p 为空或 p 的后继为空,返回 false 表示删除失败。
      • 删除 p 的后继节点 q,并释放其内存。
      • 返回 true 表示删除成功。
  6. 打印链表

    • printList 函数从头节点开始,依次打印链表中每个节点的数据。
  7. 主函数

    • main 函数进行以下操作:
      • 初始化一个链表 L 并通过尾插法建立链表。
      • 打印链表中第2个位置的元素值。
      • 在第2个位置插入值为99的新节点,并打印链表。
      • 删除第4个位置的节点,并打印链表。

通过这段代码,用户可以创建一个链表,并进行查找、插入、删除和打印操作,以方便地操作和管理链表中的数据。

5.顺序栈(使用数组实现的栈)的基本操作

#include <stdio.h>#define MaxSize 50typedef int ElemType;typedef struct {ElemType data[MaxSize];int top;
}SqStack;//栈初始化
void initStack(SqStack &S) {S.top = -1;
}//判断栈空
bool emptyStack(SqStack	S) {if (S.top == -1){return true;}return false;
}//入栈
bool pushStack(SqStack &S, ElemType e) {if (S.top == MaxSize - 1) {return false;}S.data[++S.top] = e;return true;
}//出栈
bool popStack(SqStack& S, ElemType& e) {if (S.top == -1){return false;}e = S.data[S.top--];return true;
}//获取栈顶元素
bool getTopStack(SqStack S, ElemType &e) {if (S.top == -1) {return false;}e = S.data[S.top];return true;
}int main() {SqStack S;bool flag;ElemType e;initStack(S);flag = emptyStack(S);if (flag){printf("栈空\n");}pushStack(S, 3);pushStack(S, 4);pushStack(S, 5);flag = getTopStack(S, e);if (flag){printf("栈顶元素是%d\n", e);}flag = popStack(S, e);if (flag){printf("弹出元素是%d\n", e);}return 0;
}

这段代码实现了一个顺序栈(使用数组实现的栈)的基本操作,包括初始化栈、判断栈是否为空、入栈、出栈和获取栈顶元素。以下是代码的详细说明:

  1. 定义顺序栈结构体

    • SqStack 结构体包含一个存储数据的数组 data 和一个表示栈顶位置的变量 top
  2. 栈初始化

    • initStack 函数将栈的 top 初始化为 -1,表示栈为空。
  3. 判断栈是否为空

    • emptyStack 函数检查栈的 top 是否为 -1,如果是,则返回 true 表示栈为空,否则返回 false
  4. 入栈操作

    • pushStack 函数将元素 e 压入栈中,步骤如下:
      • 检查栈是否已满(top 是否等于 MaxSize - 1),若满则返回 false 表示入栈失败。
      • 否则,将 e 存入 data 数组中 top 的下一个位置,并更新 top
      • 返回 true 表示入栈成功。
  5. 出栈操作

    • popStack 函数从栈中弹出一个元素,步骤如下:
      • 检查栈是否为空(top 是否为 -1),若空则返回 false 表示出栈失败。
      • 否则,将 data 数组中 top 位置的元素赋值给 e,并更新 top
      • 返回 true 表示出栈成功。
  6. 获取栈顶元素

    • getTopStack 函数获取栈顶元素,步骤如下:
      • 检查栈是否为空(top 是否为 -1),若空则返回 false 表示获取栈顶元素失败。
      • 否则,将 data 数组中 top 位置的元素赋值给 e
      • 返回 true 表示获取栈顶元素成功。
  7. 主函数

    • main 函数进行以下操作:
      • 初始化一个栈 S
      • 检查栈是否为空并打印结果。
      • 将元素 345 依次压入栈中。
      • 获取栈顶元素并打印结果。
      • 从栈中弹出一个元素并打印结果。

这段代码演示了如何使用顺序栈存储和管理数据,通过一系列的栈操作展示了栈的基本功能。

6.顺序循环队列的基本操作

#include <stdio.h>#define MaxSize 5typedef int ElemType;//顺序循环队列
typedef struct {ElemType data[MaxSize];int front, rear;
}SqQueue;//循环队列初始化
void initQueue(SqQueue& Q) {Q.front = Q.rear = 0;
}//队列判空
bool emptyQueue(SqQueue Q) {if (Q.rear == Q.front){return true;}return false;
}//入队
bool enQueue(SqQueue& Q, ElemType e) {if ((Q.rear + 1) % MaxSize == Q.front) {return false;}Q.data[Q.rear] = e;Q.rear = (Q.rear + 1) % MaxSize;return true;
}//出队
bool deQueue(SqQueue& Q, ElemType& e) {if (Q.rear == Q.front) {return false;}e = Q.data[Q.front];Q.front = (Q.front + 1) % MaxSize;return true;
}
int main() {SqQueue Q;bool ret;ElemType e;initQueue(Q);ret = emptyQueue(Q);if (ret){printf("栈空\n");}enQueue(Q, 3);enQueue(Q, 4);enQueue(Q, 5);enQueue(Q, 6);ret = enQueue(Q, 7);if (!ret) {printf("入队失败\n");}ret = deQueue(Q, e);if (ret){printf("出队成功,元素为%d\n", e);}return 0;
}

这段代码实现了一个顺序循环队列的基本操作,包括初始化队列、判断队列是否为空、入队和出队。以下是代码的详细说明:

  1. 定义顺序循环队列结构体

    • SqQueue 结构体包含一个存储数据的数组 data 和两个整型变量 frontrear,分别表示队列的头部和尾部位置。
  2. 循环队列初始化

    • initQueue 函数将队列的 frontrear 初始化为 0,表示队列为空。
  3. 判断队列是否为空

    • emptyQueue 函数检查 rear 是否等于 front,如果相等,则返回 true 表示队列为空,否则返回 false
  4. 入队操作

    • enQueue 函数将元素 e 入队,步骤如下:
      • 检查队列是否已满((rear + 1) % MaxSize 是否等于 front),若满则返回 false 表示入队失败。
      • 否则,将 e 存入 data 数组的 rear 位置,并更新 rear
      • 返回 true 表示入队成功。
  5. 出队操作

    • deQueue 函数从队列中出队一个元素,步骤如下:
      • 检查队列是否为空(rear 是否等于 front),若空则返回 false 表示出队失败。
      • 否则,将 data 数组的 front 位置的元素赋值给 e,并更新 front
      • 返回 true 表示出队成功。
  6. 主函数

    • main 函数进行以下操作:
      • 初始化一个队列 Q
      • 检查队列是否为空并打印结果。
      • 将元素 3456 依次入队。
      • 尝试将元素 7 入队,由于队列已满,打印入队失败信息。
      • 从队列中出队一个元素并打印结果。

这段代码展示了如何使用顺序循环队列存储和管理数据,通过一系列的队列操作展示了队列的基本功能。

7.链式队列的基本操作

#include <stdio.h>
#include <stdlib.h>typedef int ElemType;typedef struct LinkNode {ElemType data;struct LinkNode* next;
}LinkNode;typedef struct {LinkNode* front, * rear;
}LinkQueue;//初始化队列
void initQueue(LinkQueue& Q) {Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));//指向头结点Q.front->next = NULL;
}//入队
bool enQueue(LinkQueue& Q, ElemType e) {LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode));p->data = e;p->next = NULL;Q.rear->next = p;Q.rear = p;return true;
}//出队
bool deQueue(LinkQueue& Q, ElemType& e) {if (Q.front == Q.rear) {return false;}LinkNode* q = Q.front->next;e = q->data;Q.front->next = q->next;if (q == Q.rear) {//队列只有一个元素Q.rear = Q.front;//将队列置空}free(q);return true;
}int main() {LinkQueue Q;initQueue(Q);enQueue(Q, 3);enQueue(Q, 4);ElemType e;deQueue(Q, e);printf("%d\n", e);deQueue(Q, e);printf("%d\n", e);if (!deQueue(Q, e)) {printf("队空\n");}printf("%d\n", deQueue(Q, e));return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 为什么说脱离决策的数据分析都是无用功
  • 【AI落地应用实战】DAMODEL深度学习平台部署+本地调用ChatGLM-6B解决方案
  • Android Java和Kotlin的目标JVM版本不一致
  • 数据炼金术:在sklearn中进行增量特征合成的秘诀
  • 弱网常见问题
  • 25考研计算机组成原理复习·3.1/3.2 存储器概述/主存储器
  • Hugo 部署与自动更新(Git)
  • c#中Oracle.DataAccess.dll连接数据库的报错处理
  • TiDB系列之:TiCDC同步TiDB数据库数据到Kafka集群Topic
  • Vulnhub靶机-Jangow 1.0.1
  • javaScript中基本数据类型和复杂数据类型数据的存储
  • linux:二进制包安装与源码包安装详解
  • 【计组】第三章和第四章
  • 【考研数学】概率论:4 种方法解答一道题,你觉得哪种方法又快又好呢?
  • postman请求JSON格式,后台@RequestBody实体类接收不到数据
  • 【翻译】babel对TC39装饰器草案的实现
  • git 常用命令
  • Github访问慢解决办法
  • Selenium实战教程系列(二)---元素定位
  • vue总结
  • 复习Javascript专题(四):js中的深浅拷贝
  • 工作中总结前端开发流程--vue项目
  • 开源SQL-on-Hadoop系统一览
  • 聊聊redis的数据结构的应用
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 通过npm或yarn自动生成vue组件
  • 原生 js 实现移动端 Touch 滑动反弹
  • Prometheus VS InfluxDB
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (02)Unity使用在线AI大模型(调用Python)
  • (二)学习JVM —— 垃圾回收机制
  • (分布式缓存)Redis哨兵
  • (过滤器)Filter和(监听器)listener
  • (每日一问)基础知识:堆与栈的区别
  • (十六)、把镜像推送到私有化 Docker 仓库
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转载)虚函数剖析
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .Net CoreRabbitMQ消息存储可靠机制
  • .net framework 4.8 开发windows系统服务
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET 某和OA办公系统全局绕过漏洞分析
  • .NET多线程执行函数
  • .net中的Queue和Stack
  • @Builder用法
  • @javax.ws.rs Webservice注解
  • @ModelAttribute注解使用
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • @vue-office/excel 解决移动端预览excel文件触发软键盘
  • [ 第一章] JavaScript 简史
  • [ 数据结构 - C++]红黑树RBTree