数据结构基础内容-----第四章 栈与队列

这篇具有很好参考价值的文章主要介绍了数据结构基础内容-----第四章 栈与队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

栈的定义

栈(Stack)是计算机科学中的一种抽象数据类型,它是一个只能在一端进行插入和删除操作的线性数据结构。栈按照后进先出(LIFO)的原则存储数据,即最后放入的元素最先被取出。类比物理世界中的堆叠物品,每次加入的物品都被放在上面,取出时也只能从上面取出,最后放入的物品最先被取出。

栈有两个基本的操作:

  • push:将元素压入栈顶。
  • pop:将栈顶元素弹出。

除此之外,栈还常常涉及到以下几个概念:

  • 栈顶(Top):表示栈顶元素所在位置的下标或指针。
  • 空栈(Empty):表示栈内没有任何元素。
  • 满栈(Full):表示栈已经无法再容纳新的元素。
  • 栈的大小(Size):表示栈可以容纳的元素的最大数量。
    栈的应用非常广泛,例如表达式求值、函数调用、回溯算法等都与栈密切相关。

站的抽象数据类型

**抽象数据类型(ADT)**是一种数学模型,它定义了数据的逻辑行为和操作。具体来说,ADT 描述了数据对象的属性和可对其执行的操作,并不考虑这些操作的具体实现方式。

栈(Stack)是一种常见的 ADT,其特点是后进先出(Last In First Out,LIFO),即最后加入的元素最先被取出。栈只支持两个基本操作:压入(Push)和弹出(Pop)。在栈中插入一个元素时,该元素会被放置在栈顶;在弹出一个元素时,栈顶的元素将被移除,并返回该元素的值。

根据这些基本操作,可以衍生出其他一些操作,例如查看栈顶元素(Top)、判断**栈是否为空(IsEmpty)**等。这些操作都可以通过压入和弹出操作来实现。

栈可以用于许多应用场景,例如函数调用时的内存分配、括号匹配、表达式求值等。在实际编程中,栈通常使用数组或链表来实现。

Push(item): 将一个元素item压入栈顶。
Pop(): 弹出栈顶元素,并将其返回。
Top(): 返回栈顶的元素,但不弹出该元素。
IsEmpty(): 判断栈是否为空,如果为空返回True,否则返回False。
Size(): 返回栈中元素的个数。

数据结构基础内容-----第四章 栈与队列
在实际编程中,栈通常使用数组或链表来实现。这里介绍一种用数组实现栈的方法,叫做顺序存储结构。

顺序存储结构是指将栈中的元素保存在连续的内存空间中,可以通过数组来实现。具体来说,我们需要定义一个数组、一个栈顶指针、以及一些相关的操作。

#define MAXSIZE 100

typedef struct {
    int data[MAXSIZE];
    int top; // 栈顶指针
} Stack;

void init(Stack *s) {
    s->top = -1;
}

int is_empty(Stack *s) {
    return s->top == -1;
}

int is_full(Stack *s) {
    return s->top == MAXSIZE - 1;
}

void push(Stack *s, int x) {
    if (is_full(s)) {
        printf("Stack Overflow!\n");
        return;
    }
    s->top++;
    s->data[s->top] = x;
}

int pop(Stack *s) {
    if (is_empty(s)) {
        printf("Stack Underflow!\n");
        return -1;
    }
    int x = s->data[s->top];
    s->top--;
    return x;
}

int top(Stack *s) {
    if (is_empty(s)) {
        printf("Stack Empty!\n");
        return -1;
    }
    return s->data[s->top];
}

int size(Stack *s) {
    return s->top + 1;
}

两栈共享空间

两栈共享空间是指在一个数组中实现两个栈的数据结构。这种实现方法可以节省空间,因为两个栈共用一个数组。

具体实现方法是将数组分成两个部分,**一个部分为第一个栈的存储区域,另一个部分为第二个栈的存储区域。**两个栈的起始位置分别从数组的两端开始向中间靠拢。当两个栈的栈顶指针相遇时,表示两个栈都满了。

需要注意的是,在进行入栈和出栈操作时,需要判断哪个栈的栈顶指针需要移动。具体判断方法是,如果要对第一个栈进行入栈操作,则将元素插入到第一个栈的栈顶,并将第一个栈的栈顶指针加1;如果要对第二个栈进行入栈操作,则将元素插入到第二个栈的栈顶,并将第二个栈的栈顶指针减1。出栈操作也是类似的。

以下是一个简单的示例代码,实现了两个栈在同一个数组内共享空间的功能:

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

#define MAX_SIZE 100

typedef struct {
    int array[MAX_SIZE];
    int top1;
    int top2;
} TwoStacks;

void initStacks(TwoStacks *stacks) {
    stacks->top1 = -1;
    stacks->top2 = MAX_SIZE;
}

void push1(TwoStacks *stacks, int item) {
    if (stacks->top1 < stacks->top2 - 1) {
        stacks->top1++;
        stacks->array[stacks->top1] = item;
    } else {
        printf("Stack Overflow\n");
        exit(1);
    }
}

void push2(TwoStacks *stacks, int item) {
    if (stacks->top1 < stacks->top2 - 1) {
        stacks->top2--;
        stacks->array[stacks->top2] = item;
    } else {
        printf("Stack Overflow\n");
        exit(1);
    }
}

int pop1(TwoStacks *stacks) {
    if (stacks->top1 >= 0) {
        int item = stacks->array[stacks->top1];
        stacks->top1--;
        return item;
    } else {
        printf("Stack Underflow\n");
        exit(1);
    }
}

int pop2(TwoStacks *stacks) {
    if (stacks->top2 < MAX_SIZE) {
        int item = stacks->array[stacks->top2];
        stacks->top2++;
        return item;
    } else {
        printf("Stack Underflow\n");
        exit(1);
    }
}

int main() {
    TwoStacks stacks;
    initStacks(&stacks);

    push1(&stacks, 1);
    push2(&stacks, 2);
    push1(&stacks, 3);
    push2(&stacks, 4);
    push1(&stacks, 5);

    printf("%d\n", pop1(&stacks)); // Output: 5
    printf("%d\n", pop2(&stacks)); // Output: 4
    printf("%d\n", pop1(&stacks)); // Output: 3
    printf("%d\n", pop2(&stacks)); // Output: 2
    printf("%d\n", pop1(&stacks)); // Output: 1

    return 0;
}

栈的作用

栈还可以用于解决一些特定的编程问题,例如表达式求值、递归算法、回溯算法等等。在这些情况下,栈可以帮助我们存储和跟踪程序运行时的状态信息,以便于算法的正确执行。

这里是用栈做的小的运用

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

#define MAX_STACK_SIZE 100

// 定义栈结构体
typedef struct {
    int data[MAX_STACK_SIZE];
    int top;
} Stack;

// 初始化栈
void init_stack(Stack *s) {
    s->top = -1;
}

// 判断栈是否为空
int is_empty(Stack *s) {
    return s->top == -1;
}

// 判断栈是否已满
int is_full(Stack *s) {
    return s->top == MAX_STACK_SIZE - 1;
}

// 入栈操作
void push(Stack *s, int value) {
    if (is_full(s)) {
        printf("Stack is full.\n");
        exit(1);
    }
    s->data[++(s->top)] = value;
}

// 出栈操作
int pop(Stack *s) {
    if (is_empty(s)) {
        printf("Stack is empty.\n");
        exit(1);
    }
    return s->data[(s->top)--];
}

// 递归函数
int factorial(int n) {
    Stack s;
    init_stack(&s);

    int result = 1;
    push(&s, n); // 入栈
    while (!is_empty(&s)) {
        int x = pop(&s); // 出栈
        if (x == 1) {
            break;
        }
        result *= x;
        push(&s, x - 1); // 入栈
    }

    return result;
}

// 示例程序
int main() {
    int n = 5;
    printf("%d! = %d\n", n, factorial(n));
    return 0;
}

递归的定义

递归是一种在函数定义中使用自身的技术。在递归中,一个函数调用自身,直到达到某个终止条件为止。通常情况下,递归用于解决可以被分割成相同模式的子问题的问题,这些问题可以通过不断地调用函数来得到解决。

递归函数通常包括两部分:基本情况和递归情况。基本情况是指函数能够直接处理的情况,不需要再次调用自身来解决。递归情况则是指函数需要将问题分解成更小的子问题,并通过调用自身来解决它们。

递归的优点是可以使代码更简洁、易读、易于理解,但同时也可能会导致复杂度高、栈溢出等问题。因此,在使用递归时需要谨慎考虑其使用场景和实现方式。

总之学会递归就要学会递归

数据结构基础内容-----第四章 栈与队列
逆波兰表示法
数据结构基础内容-----第四章 栈与队列

波兰表示法

数据结构基础内容-----第四章 栈与队列

栈运算

使用栈可以很方便地实现算术表达式的求值。具体步骤如下:

  1. 创建两个栈:操作数栈和运算符栈。

  2. 从左到右扫描表达式中的每个字符。

  3. 如果当前字符是数字,则将其压入操作数栈。

  4. 如果当前字符是运算符,则判断运算符栈是否为空,如果不为空,则比较该运算符与运算符栈顶的运算符的优先级,如果该运算符的优先级小于或等于运算符栈顶的运算符,则弹出运算符栈顶的运算符和操作数栈中的两个元素,进行相应的运算,并将结果压入操作数栈。否则将该运算符压入运算符栈。

  5. 如果当前字符是左括号,则将其压入运算符栈。

  6. 如果当前字符是右括号,则循环弹出运算符栈顶的运算符和操作数栈中的两个元素,进行相应的运算,并将结果压入操作数栈,直到遇到左括号为止。

  7. 循环执行步骤 3-6,直到扫描完整个表达式。

  8. 循环弹出运算符栈顶的运算符和操作数栈中的两个元素,进行相应的运算,并将结果压入操作数栈,直到运算符栈为空。

  9. 操作数栈中最后剩下的元素即为表达式的计算结果。

这个方法可以实现任意长度的算术表达式的求值,包括含有加减乘除、括号等多种运算符的复杂表达式。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>   // 需要使用 isdigit 函数

#define MAX_STACK_SIZE 100   // 定义栈的最大容量

int stack[MAX_STACK_SIZE];   // 定义操作数栈
char opstack[MAX_STACK_SIZE];   // 定义运算符栈
int top = -1;   // 操作数栈顶指针
int optop = -1;   // 运算符栈顶指针

int pop() {   // 弹出操作数栈顶元素
    if (top == -1) {
        printf("Stack underflow!\n");
        exit(1);
    }
    return stack[top--];
}

char oppop() {   // 弹出运算符栈顶元素
    if (optop == -1) {
        printf("Stack underflow!\n");
        exit(1);
    }
    return opstack[optop--];
}

void push(int value) {   // 将元素压入操作数栈
    if (top >= MAX_STACK_SIZE - 1) {
        printf("Stack overflow!\n");
        exit(1);
    }
    stack[++top] = value;
}

void oppush(char value) {   // 将元素压入运算符栈
    if (optop >= MAX_STACK_SIZE - 1) {
        printf("Stack overflow!\n");
        exit(1);
    }
    opstack[++optop] = value;
}

int priority(char op) {   // 定义运算符优先级
    if (op == '*' || op == '/') {
        return 2;
    } else if (op == '+' || op == '-') {
        return 1;
    } else {
        return 0;
    }
}

int evaluate(char *expression) {   // 表达式求值函数
    int i, len, operand1, operand2;
    char c, op;

    len = strlen(expression);
    for (i = 0; i < len; i++) {
        c = expression[i];

        if (isdigit(c)) {   // 如果是数字字符,将其转换为整数并压入操作数栈
            push(c - '0');
        } else if (c == '(') {   // 如果是左括号,将其压入运算符栈
            oppush(c);
        } else if (c == ')') {   // 如果是右括号,则弹出运算符栈顶的运算符和操作数栈中的两个元素,进行相应的运算,并将结果压入操作数栈,直到遇到左括号为止
            while (opstack[optop] != '(') {
                operand2 = pop();
                operand1 = pop();
                op = oppop();
                switch (op) {
                    case '+': push(operand1 + operand2); break;
                    case '-': push(operand1 - operand2); break;
                    case '*': push(operand1 * operand2); break;
                    case '/': 
                        if (operand2 == 0) {   // 处理除数为0的情况
                            printf("Division by zero!\n");
                            exit(1);
                        }
                        push(operand1 / operand2); 
                        break;
                }
            }
            oppop();   // 弹出左括号
        } else if (c == '+' || c == '-' || c == '*' || c == '/') {   // 如果是运算符,则比较该运算符与运算符栈顶的运算符的优先级,如果该运算符的优先级小于或等于运算符栈顶的运算符,则弹出运算符栈顶的运算符和操作数栈中的两个元素,进行相应的运算,并将结果压入操作数栈。否则将该运算符压入运算符栈。
            while (optop >= 0 && priority(c) <= priority(opstack[optop]))
            {
operand2 = pop();
operand1 = pop();
op = oppop();
switch (op) {
case '+': push(operand1 + operand2); break;
case '-': push(operand1 - operand2); break;
case '*': push(operand1 * operand2); break;
case '/':
if (operand2 == 0) {   // 处理除数为0的情况
printf("Division by zero!\n");
exit(1);
}
push(operand1 / operand2);
break;
}
}
oppush(c);
} else if (c == ' ') {   // 如果是空格,则忽略
continue;
} else {   // 如果不是数字、括号或运算符,则输入的表达式有误
printf("Invalid expression!\n");
exit(1);
}
}

while (optop >= 0) {   // 处理剩余的运算符
    operand2 = pop();
    operand1 = pop();
    op = oppop();
    switch (op) {
        case '+': push(operand1 + operand2); break;
        case '-': push(operand1 - operand2); break;
        case '*': push(operand1 * operand2); break;
        case '/': 
            if (operand2 == 0) {   // 处理除数为0的情况
                printf("Division by zero!\n");
                exit(1);
            }
            push(operand1 / operand2); 
            break;
    }
}

return pop();   // 返回操作数栈顶元素,即为表达式求值结果
}

int main() {
char expression[100];

printf("Please enter an arithmetic expression:\n");
fgets(expression, 100, stdin);

printf("The result is: %d\n", evaluate(expression));

return 0;
}



队列

队列是一种常见的数据结构,它按照先进先出(FIFO)的原则来存储和访问元素。队列通常用于在多个处理单元之间分配任务或缓冲数据。

在队列中,新元素被添加到队列的尾部,而从队列中删除元素时则从队列的头部开始进行。这意味着最先添加的元素会最先被取出,而最后添加的元素则会最后被取出。这种方式确保了队列中的元素按照添加顺序进行处理。

队列的基本操作包括入队(将元素添加到队列尾部)和出队(从队列头部删除元素)。此外,队列还可以支持其他操作,如查看队列头部元素、检查队列是否为空等。

数据结构基础内容-----第四章 栈与队列

队列的实现

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

#define MAX_QUEUE_SIZE 100

// 定义一个队列结构体
struct queue {
    int items[MAX_QUEUE_SIZE];
    int front, rear;
};

// 初始化队列
struct queue* create_queue() {
    struct queue* q = (struct queue*)malloc(sizeof(struct queue));
    q->front = -1;
    q->rear = -1;
    return q;
}

// 检查队列是否为空
int is_empty(struct queue* q) {
    if (q->rear == -1)
        return 1;
    else
        return 0;
}

// 检查队列是否已满
int is_full(struct queue* q) {
    if (q->front == 0 && q->rear == MAX_QUEUE_SIZE - 1)
        return 1;
    else if (q->front == q->rear + 1)
        return 1;
    else
        return 0;
}

// 向队列尾部插入元素
void enqueue(struct queue* q, int value) {
    if (is_full(q)) {
        printf("Queue is full.\n");
    } else {
        if (q->front == -1) {
            q->front = 0;
        }
        q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
        q->items[q->rear] = value;
        printf("Enqueued item: %d\n", value);
    }
}

// 从队列头部删除元素并返回该元素
int dequeue(struct queue* q) {
    int item;
    if (is_empty(q)) {
        printf("Queue is empty.\n");
        item = -1;
    } else {
        item = q->items[q->front];
        if (q->front == q->rear) {
            q->front = -1;
            q->rear = -1;
        } else {
            q->front = (q->front + 1) % MAX_QUEUE_SIZE;
        }
    }
    return item;
}

// 显示队列中所有元素
void display(struct queue* q) {
    int i;
    if (is_empty(q)) {
        printf("Queue is empty.\n");
    } else {
        printf("Queue contains the following items:\n");
        for (i = q->front; i <= q->rear; i++) {
            printf("%d ", q->items[i]);
        }
        printf("\n");
    }
}

// 主函数用于演示队列操作
int main() {
    struct queue* q = create_queue();

    // 向队列添加元素
    enqueue(q, 1);
    enqueue(q, 2);
    enqueue(q, 3);
    enqueue(q, 4);

    // 显示队列中的元素
    display(q);

    // 从队列删除元素
    int removed_item = dequeue(q);
    printf("Removed item: %d\n", removed_item);

    // 显示更新后的队列
    display(q);
    
    return 0;
}

循环队列

循环队列是一种使用固定大小的环形缓冲区来实现队列的数据结构。在循环队列中,队列的尾部连接到了队列的头部,使得元素可以按照先进先出(FIFO)的顺序被访问。

在循环队列中,需要维护两个指针:一个指向队列的头部(front),另一个指向队列的尾部(rear)。当向队列中插入元素时,将元素添加到尾部指针所指向的位置,并将尾部指针后移。同样地,当从队列中删除元素时,将元素从头部指针所指向的位置删除,并将头部指针后移。由于循环队列是环形的,当指针到达缓冲区的尾部时,它会返回缓冲区的开头。

循环队列相对于普通队列的好处在于,它可以有效地利用内存空间并避免因为队列的头部或尾部始终在数组的末尾而导致的空间浪费。此外,在循环队列中,我们可以更高效地判断队列是否已满或为空。

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

#define MAX_SIZE 5  // 定义最大队列长度为5

typedef struct {
    int front;  // 队头指针
    int rear;   // 队尾指针
    int data[MAX_SIZE];  // 队列数组
} Queue;

/**
 * 初始化队列
 * @param q 待初始化的队列
 */
void init(Queue *q) {
    q->front = q->rear = 0;
}

/**
 * 判断队列是否为空
 * @param q 待判断的队列
 * @return 如果队列为空,则返回1;否则返回0。
 */
int is_empty(Queue *q) {
    return q->front == q->rear;
}

/**
 * 判断队列是否已满
 * @param q 待判断的队列
 * @return 如果队列已满,则返回1;否则返回0。
 */
int is_full(Queue *q) {
    return (q->rear + 1) % MAX_SIZE == q->front;
}

/**
 * 入队操作
 * @param q 队列指针
 * @param x 入队元素
 * @return 成功入队则返回1,否则返回0。
 */
int enqueue(Queue *q, int x) {
    if (is_full(q)) {  // 如果队列已满,则无法入队
        printf("队列已满,无法入队。\n");
        return 0;
    } else {
        q->data[q->rear] = x;         // 将元素插入队尾
        q->rear = (q->rear + 1) % MAX_SIZE;  // 队尾指针加1,注意取模
        return 1;
    }
}

/**
 * 出队操作
 * @param q 队列指针
 * @param x 出队元素的存储地址
 * @return 成功出队则返回1,否则返回0。
 */
int dequeue(Queue *q, int *x) {
    if (is_empty(q)) {  // 如果队列为空,则无法出队
        printf("队列为空,无法出队。\n");
        return 0;
    } else {
        *x = q->data[q->front];          // 取出队头元素
        q->front = (q->front + 1) % MAX_SIZE;  // 队头指针加1,注意取模
        return 1;
    }
}

int main() {
    Queue q;            // 定义队列
    init(&q);           // 初始化队列

    enqueue(&q, 1);     // 入队元素1
    enqueue(&q, 2);     // 入队元素2
    enqueue(&q, 3);     // 入队元素3
    enqueue(&q, 4);     // 入队元素4
    enqueue(&q, 5);     // 入队元素5,此时队列已满,5入不了队列
    enqueue(&q, 6);     // 入队元素6,此时无法入队

    int x;              // 定义变量x,用于存储出队元素
    dequeue(&q, &x);    // 出队操作,取出队头元素1
    printf("出队元素:%d\n", x);

    dequeue(&q, &x);    // 出队操作,取出队头元素2
    printf("出队元素:%d\n", x);

    enqueue(&q, 6);     // 入队新元素6

    dequeue(&q, &x);    // 出队操作,取出队头元素3
    printf("出队元素:%d\n", x);

    dequeue(&q, &x);    // 出队操作,取出队头元素4
    printf("出队元素:%d\n", x);

    dequeue(&q, &x);    // 出队操作,取出队头元素6
    printf("出队元素:%d\n", x);

    dequeue(&q, &x);    //
    dequeue(&q, &x);    // 出队操作,此时队列为空,无法出队
printf("出队元素:%d\n", x);

return 0;
}

//程序有瑕疵,这里仅是抛砖作用。

队列链式存储结构及实现

首先,定义一个结构体来表示链表中的节点,包含数据域和指针域:

typedef struct ListNode {
    int data;
    struct ListNode* next;
} ListNode;

其中 data 表示节点中存储的数据,next 是指向下一个节点的指针。

接着,定义一个结构体来表示队列,包含头指针和尾指针:

typedef struct Queue {
    ListNode* front; // 队头指针
    ListNode* rear;  // 队尾指针
} Queue;

其中 front 指向队头节点,rear 指向队尾节点。

创建空队列时,可以将 front 和 rear 初始化为 NULL。

入队操作时,需要新建一个节点,并将其插入到队尾:

void enQueue(Queue* q, int value) {
    ListNode* node = (ListNode*)malloc(sizeof(ListNode));
    node->data = value;
    node->next = NULL;

    if (q->rear == NULL) { // 队列为空时
        q->front = q->rear = node;
    } else {
        q->rear->next = node;
        q->rear = node;
    }
}

出队操作时,需要删除队头节点,并更新队头指针:

int deQueue(Queue* q) {
    if (q->front == NULL) { // 队列为空时
        return -1;
    }

    ListNode* node = q->front;
    int value = node->data;

    if (q->front == q->rear) { // 队列只有一个节点时
        q->front = q->rear = NULL;
    } else {
        q->front = q->front->next;
    }

    free(node);
    return value;
}

小例子文章来源地址https://www.toymoban.com/news/detail-471483.html

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

// 链表节点结构体
typedef struct ListNode {
    int data;
    struct ListNode* next;
} ListNode;

// 队列结构体
typedef struct Queue {
    ListNode* front; // 队头指针
    ListNode* rear;  // 队尾指针
} Queue;

// 初始化队列
void initQueue(Queue* q) {
    q->front = NULL;
    q->rear = NULL;
}

// 入队操作
void enQueue(Queue* q, int value) {
    ListNode* node = (ListNode*)malloc(sizeof(ListNode));
    node->data = value;
    node->next = NULL;

    if (q->rear == NULL) { // 队列为空时
        q->front = q->rear = node;
    } else {
        q->rear->next = node;
        q->rear = node;
    }
}

// 出队操作
int deQueue(Queue* q) {
    if (q->front == NULL) { // 队列为空时
        return -1;
    }

    ListNode* node = q->front;
    int value = node->data;

    if (q->front == q->rear) { // 队列只有一个节点时
        q->front = q->rear = NULL;
    } else {
        q->front = q->front->next;
    }

    free(node);
    return value;
}

int main() {
    Queue q;
    initQueue(&q);

    // 入队操作
    enQueue(&q, 1);
    enQueue(&q, 2);
    enQueue(&q, 3);

    // 出队操作
    int value1 = deQueue(&q);
    int value2 = deQueue(&q);
    int value3 = deQueue(&q);

    printf("%d %d %d\n", value1, value2, value3); // 输出:1 2 3

    return 0;
}

到了这里,关于数据结构基础内容-----第四章 栈与队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 8月28日上课内容 第四章 MySQL备份与恢复

    本章结构  MySQL 的日志默认保存位置为 /usr/local/mysql/data ##配置文件 vim /etc/my.cnf [mysqld] ##错误日志,用来记录当MySQL启动、停止或运行时发生的错误信息,默认已开启 log-error=/usr/local/mysql/data/mysql_error.log     #指定日志的保存位置和文件名 ##通用查询日志,用来记录MySQL的所有

    2024年02月10日
    浏览(42)
  • 第四章 matlab的循环结构

    循环(loop)是一种 matlab 结构,它允许我们多次执行一系列的语句。循环结构有两种 基本形式:while 循环和 for 循环。两者之间的最大不同在于代码的重复是如何控制的。在 while 循环中,代码的重复的次数是不能确定的,只要满足用户定义的条件,重复就进行下 去。相对地,在

    2024年02月06日
    浏览(25)
  • 第四章 路由基础

    目录 4.1 路由器概述 4.1.1 路由器定义 4.1.2 路由器工作原理 4.1.3 路由表的生成方式 (1)直连路由 (2)静态路由 (3)动态路由 4.1.4 路由器的接口 (1)配置接口 (2)局域网接口 (3)广域网接口 4.1.5 路由器的硬件连接 (1)局域网线缆:双绞线 (2)广域网接口 (3)配置专

    2024年02月08日
    浏览(53)
  • 形象谈JVM-第四章-JVM内存结构

    给我一个CPU,给我一块内存,我来执行一段代码。 我要如何分配呢? new User(); 这里有一个有一个User类,如果我要new出来User对象,必须先知道它长什么样子,我先搞一块区域出来,把User类的样子给存下来。 可以把 “User类的样子” 比作造房子的 “图纸” 或者 “模板” ;

    2024年02月11日
    浏览(29)
  • 计算机网络基础第四章

    主要任务是把 分组 从源端传到目的端,为分组交换网上的不同主机提供通信服务。网络层传输单位是 数据报 。 功能一:路由选择与分组转发( 最佳路径 ) 功能二:异构网络互联 功能三:拥塞控制(若所有结点都来不及接受分组,而要丢弃大量分组的话,网络就处于 拥塞

    2024年02月16日
    浏览(74)
  • 第四章:前端框架Vue基础入门

    本章学习目标: 了解Vue框架架构思想 掌握Vue核心指令 掌握计算属性与监视 掌握组件化开发模式 官方文档:https://cn.vuejs.org/guide/introduction.html. 文档可选择使用optionsAPI(选项式API)阅读,或者CompositionApi(组合式API)阅读。选项式API更适合平滑从vue2过渡,以下示例均以Compositi

    2024年02月12日
    浏览(33)
  • 第四章--Redis基础知识和面试题

    Redis 是一个基于内存的k-v结构数据库 基于内存存储,读写性能高 适合存储热点数据(热点商品, 资讯, 新闻) 企业应用广泛 Redis入门 简介: 应用场景 ⭐缓存 任务队列 消息队列 分布式锁 数据类型 常用命令 redis常用命令链接 redis.net.cn java中操作redis 介绍 :::info redis启动默认有16个

    2024年02月07日
    浏览(37)
  • 【第四章 flutter学习之flutter基础组件】

    android、ios各自平台的资源文件 lib 项目目录 linux macos PC平台资源文件 web web平台资源文件 其他的基本上是一些配置文件 pubspec.yaml 配置文件类似vue中的json 核心文件是main.dart文件 首先我们先清空main.dart文件 引入主题 import ‘package:flutter/material.dart’; 定义入口方法 用来调用组件

    2024年02月15日
    浏览(38)
  • 第四章 云原生架构之Kubernetes基础知识

    ​ Kubernetes是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,简称 K8S。 K8S的本质是一组服务器集群,可以在对应服务器集群的每个节点上运行程序,来对节点中的容器进行管理 。类似Master-Work方式,每个服务器上安装特定的k8s组件,就可以形成集群,然

    2024年02月17日
    浏览(34)
  • C++算法之旅、06 基础篇 | 第四章 动态规划 详解

    状态表示 集合 满足一定条件的所有方案 属性 集合(所有方案)的某种属性(Max、Min、Count等) 状态计算(集合划分) 如何将当前集合划分成多个子集合 状态计算相当于集合的划分 :把当前集合划分成若干个子集,使得每个子集的状态可以先算出来,从而推导当前集合状态

    2024年02月09日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包