数据结构——(双)链表

news2025/2/23 2:45:22

文章目录

1. 定义

2. 双链表和单链表的区别

3. 代码示例

3.1 双链表节点和结构定义

3.2 初始化双链表

3.3 返回双链表的长度

3.4 在指定位置插入元素

3.5 在末尾插入元素

3.6 删除指定位置的元素并返回被删除的元素

3.7 删除末尾元素

3.8 获取指定位置的元素

3.9 修改指定位置的元素

3.10 释放双链表内存

4. 流程

5. 完整代码


1. 定义

双链表(Doubly Linked List)是一种链表数据结构,其中每个节点不仅包含一个数据域,还包含两个指针域,一个指向前驱节点,一个指向后继节点。相比单链表,双链表可以更方便地进行双向遍历,插入和删除操作也更高效。

双链表的定义和操作

  1. 节点的定义:每个节点包含数据部分和指向前一个节点和后一个节点的指针部分。
  2. 头节点和尾节点:链表的头节点是链表的起点,尾节点是链表的终点,通过头节点可以遍历整个链表。
  3. 双向链接:每个节点都有指向前一个节点和后一个节点的指针,因此可以双向遍历链表。
  4. 动态扩展:节点在内存中不必是连续的,可以动态分配和释放内存。

2. 双链表和单链表的区别

结构上的区别

  • 单链表

    • 每个节点包含一个数据域和一个指向下一个节点的指针。
    • 只有从头节点向下遍历的方向,没有指向前一个节点的指针。
    • 头节点没有前驱节点,尾节点的指针指向 NULL
  • 双链表

    • 每个节点包含一个数据域、一个指向下一个节点的指针和一个指向前一个节点的指针。
    • 可以从任一节点双向遍历,即可以向前遍历到头节点,也可以向后遍历到尾节点。
    • 头节点的前驱指针指向 NULL,尾节点的后继指针指向 NULL

单链表的优缺点

优点

  1. 简单性:实现和维护相对简单,节点只需要存储一个指针,内存开销小。
  2. 内存占用较少:每个节点只包含一个指针,因此内存占用较双链表少。
  3. 插入和删除操作效率较高:在已知前驱节点的情况下,插入和删除节点的时间复杂度为 O(1)。

缺点

  1. 查找效率较低:从头节点遍历到目标节点的时间复杂度为 O(n)。
  2. 只能单向遍历:不能从尾节点向前遍历到头节点,灵活性差。

双链表的优缺点

优点

  1. 双向遍历:可以从任一节点双向遍历,即可以向前遍历到头节点,也可以向后遍历到尾节点。
  2. 删除节点更方便:在已知节点本身的情况下,删除节点时不需要知道其前驱节点,因为可以通过节点本身直接访问其前驱节点和后继节点。
  3. 灵活性高:在某些情况下,双向遍历能够更方便地实现算法,比如在某些需要回溯的场景下。

缺点

  1. 内存占用较大:每个节点包含两个指针,内存占用较单链表多。
  2. 实现和维护相对复杂:双向链表的实现和维护比单链表更复杂,需要处理更多的指针操作。
  3. 插入和删除操作相对复杂:插入和删除操作需要同时更新前驱和后继节点的指针,操作较为繁琐。

3. 代码示例

3.1 双链表节点和结构定义

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

// 双链表节点结构定义
typedef struct DNode {
    int data;             // 节点存储的数据
    struct DNode *prev;   // 指向前一个节点的指针
    struct DNode *next;   // 指向后一个节点的指针
} DNode;

// 双链表结构定义
typedef struct {
    DNode *head;  // 双链表头节点指针
    DNode *tail;  // 双链表尾节点指针
    size_t size;  // 双链表中的节点个数
} DoublyLinkedList;
  • DNode 结构体定义了双链表的节点,包含数据域 data 和指向前一个节点的指针 prev 以及指向后一个节点的指针 next
  • DoublyLinkedList 结构体定义了双链表,包含指向头节点的指针 head 和指向尾节点的指针 tail,以及链表中节点的个数 size

3.2 初始化双链表

// 初始化双链表
void initDoublyLinkedList(DoublyLinkedList *list) {
    list->head = NULL; // 初始化头节点为空
    list->tail = NULL; // 初始化尾节点为空
    list->size = 0;    // 初始化节点个数为0
}

  • initDoublyLinkedList 函数将双链表的头节点和尾节点设置为 NULL,并将节点个数初始化为 0。

3.3 返回双链表的长度

// 返回双链表的长度
size_t getLength(const DoublyLinkedList *list) {
    return list->size; // 返回双链表的节点个数
}
  •  getLength 函数返回双链表中的节点个数。

3.4 在指定位置插入元素

// 在指定位置插入元素
void insertAt(DoublyLinkedList *list, size_t index, int element) {
    // 检查插入位置是否有效
    if (index > list->size) {
        return; // 忽略无效的插入位置
    }

    // 创建新节点
    DNode *newNode = (DNode *)malloc(sizeof(DNode));
    newNode->data = element;
    newNode->prev = NULL;
    newNode->next = NULL;

    // 如果插入位置是头节点
    if (index == 0) {
        newNode->next = list->head;
        if (list->head != NULL) {
            list->head->prev = newNode;
        }
        list->head = newNode; // 新节点成为头节点
        if (list->tail == NULL) {
            list->tail = newNode; // 如果链表为空,新节点也是尾节点
        }
    } else if (index == list->size) {
        // 如果插入位置是尾节点
        newNode->prev = list->tail;
        if (list->tail != NULL) {
            list->tail->next = newNode;
        }
        list->tail = newNode; // 新节点成为尾节点
        if (list->head == NULL) {
            list->head = newNode; // 如果链表为空,新节点也是头节点
        }
    } else {
        // 找到插入位置的前一个节点
        DNode *current = list->head;
        for (size_t i = 0; i < index - 1; i++) {
            current = current->next;
        }

        // 插入新节点
        newNode->next = current->next;
        newNode->prev = current;
        if (current->next != NULL) {
            current->next->prev = newNode;
        }
        current->next = newNode;
    }

    list->size++; // 更新节点个数
}
  • insertAt 函数在双链表的指定位置插入一个新的元素。如果插入位置是 0,则新节点成为头节点。如果插入位置是链表的末尾,则新节点成为尾节点。否则,通过遍历找到插入位置的前一个节点,并在该位置插入新节点。更新链表的节点个数。

3.5 在末尾插入元素

// 在末尾插入元素
void insertEnd(DoublyLinkedList *list, int element) {
    insertAt(list, list->size, element); // 在链表末尾插入元素
}
  • insertEnd 函数在双链表末尾插入一个新的元素,通过调用 insertAt 函数实现。

3.6 删除指定位置的元素并返回被删除的元素

// 删除指定位置的元素并返回被删除的元素
int deleteAt(DoublyLinkedList *list, size_t index) {
    // 检查删除位置是否有效
    if (index >= list->size) {
        return -1; // 忽略无效的删除位置
    }

    int deletedElement;

    // 如果删除位置是头节点
    if (index == 0) {
        DNode *temp = list->head;
        list->head = temp->next;
        if (list->head != NULL) {
            list->head->prev = NULL;
        } else {
            list->tail = NULL; // 如果链表只有一个节点
        }
        deletedElement = temp->data;
        free(temp); // 释放被删除节点的内存
    } else if (index == list->size - 1) {
        // 如果删除位置是尾节点
        DNode *temp = list->tail;
        list->tail = temp->prev;
        if (list->tail != NULL) {
            list->tail->next = NULL;
        } else {
            list->head = NULL; // 如果链表只有一个节点
        }
        deletedElement = temp->data;
        free(temp); // 释放被删除节点的内存
    } else {
        // 找到删除位置的前一个节点
        DNode *current = list->head;
        for (size_t i = 0; i < index - 1; i++) {
            current = current->next;
        }

        // 删除节点
        DNode *temp = current->next;
        current->next = temp->next;
        if (temp->next != NULL) {
            temp->next->prev = current;
        }
        deletedElement = temp->data;
        free(temp); // 释放被删除节点的内存
    }

    list->size--; // 更新节点个数
    return deletedElement;
}
  • deleteAt 函数删除双链表中指定位置的节点,并返回该节点的值。如果删除位置是 0,则直接删除头节点。如果删除位置是链表的末尾,则删除尾节点。否则,通过遍历找到删除位置的前一个节点,并删除该位置的节点。更新链表的节点个数。

3.7 删除末尾元素

// 删除末尾元素并返回被删除的元素
int deleteEnd(DoublyLinkedList *list) {
    return deleteAt(list, list->size - 1); // 删除链表末尾的元素
}
  • deleteEnd 函数删除双链表末尾的节点,通过调用 deleteAt 函数实现。

3.8 获取指定位置的元素

// 获取指定位置的元素
int getElementAt(const DoublyLinkedList *list, size_t index) {
    // 检查索引位置是否有效
    if (index >= list->size) {
        return -1; // 返回无效的索引
    }

    // 遍历找到指定位置的节点
    DNode *currentNode = list->head;
    for (size_t i = 0; i < index; i++) {
        currentNode = currentNode->next;
    }

    return currentNode->data; // 返回指定位置的元素
}
  • getElementAt 函数返回双链表中指定位置的元素。通过遍历找到指定位置的节点,并返回该节点的值。

3.9 修改指定位置的元素

// 修改指定位置的元素
void modifyAt(DoublyLinkedList *list, size_t index, int newValue) {
    // 检查修改位置是否有效
    if (index >= list->size) {
        return; // 忽略无效的修改位置
 }

    // 遍历找到指定位置的节点
    DNode *currentNode = list->head;
    for (size_t i = 0; i < index; i++) {
        currentNode = currentNode->next;
    }

    currentNode->data = newValue; // 修改节点的值
}
  • modifyAt 函数修改双链表中指定位置的元素值。通过遍历找到指定位置的节点,并修改该节点的值。

3.10 释放双链表内存

// 释放双链表内存
void destroyDoublyLinkedList(DoublyLinkedList *list) {
    // 遍历释放每个节点的内存
    DNode *currentNode = list->head;
    while (currentNode != NULL) {
        DNode *temp = currentNode;
        currentNode = currentNode->next;
        free(temp); // 释放每个节点的内存
    }

    list->head = NULL; // 头节点置为空
    list->tail = NULL; // 尾节点置为空
    list->size = 0;    // 节点个数置为0
}
  • destroyDoublyLinkedList 函数释放双链表使用的内存。通过遍历链表,逐个释放每个节点的内存。将头节点和尾节点指针置为空,节点个数置为 0。

4. 流程

初始化双链表

  • 判断链表是否为空。
  • 如果为空,设置头指针和尾指针为NULL。
  • 如果不为空,创建头节点和尾节点。

插入节点

  • 判断插入位置是在头部、尾部还是中间。
  • 如果是头部,设置新节点为头节点并更新头节点的前驱指针。
  • 如果是尾部,设置新节点为尾节点并更新尾节点的后继指针。
  • 如果是在中间,找到插入位置前一个节点,设置新节点的前驱和后继指针,并更新前一个节点和后一个节点的指针。
  • 更新链表长度。

删除节点

  • 判断删除位置是在头部、尾部还是中间。
  • 如果是头部,找到头节点并更新头节点指针。
  • 如果是尾部,找到尾节点并更新尾节点指针。
  • 如果是在中间,找到要删除节点的前一个节点,更新前一个节点和后一个节点的指针。
  • 释放被删除节点的内存。
  • 更新链表长度。

遍历链表

  • 从头节点开始。
  • 判断当前节点是否为NULL。
  • 如果不为NULL,访问节点数据并移动到下一个节点,重复判断。
  • 如果为NULL,遍历结束。

修改节点数据

  • 找到目标节点。
  • 更新节点数据。

 

5. 完整代码

代码包括双链表的基本操作,包括初始化、插入、删除、获取和修改元素,以及释放链表的内存.

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

// 双链表节点结构定义
typedef struct DNode {
    int data;           // 节点存储的数据
    struct DNode *prev; // 指向前一个节点的指针
    struct DNode *next; // 指向后一个节点的指针
} DNode;

// 双链表结构定义
typedef struct {
    DNode *head; // 双链表头节点指针
    DNode *tail; // 双链表尾节点指针
    size_t size; // 双链表中的节点个数
} DoublyLinkedList;

// 初始化双链表
void initDoublyLinkedList(DoublyLinkedList *list) {
    list->head = NULL; // 初始化头节点为空
    list->tail = NULL; // 初始化尾节点为空
    list->size = 0;    // 初始化节点个数为0
}

// 返回双链表的长度
size_t getLength(const DoublyLinkedList *list) {
    return list->size; // 返回双链表的节点个数
}

// 在指定位置插入元素
void insertAt(DoublyLinkedList *list, size_t index, int element) {
    if (index > list->size) {
        return; // 忽略无效的插入位置
    }

    DNode *newNode = (DNode *)malloc(sizeof(DNode)); // 创建新节点
    newNode->data = element;
    newNode->prev = NULL;
    newNode->next = NULL;

    if (index == 0) { // 插入位置是头节点
        newNode->next = list->head;
        if (list->head != NULL) {
            list->head->prev = newNode;
        }
        list->head = newNode;
        if (list->tail == NULL) {
            list->tail = newNode;
        }
    } else if (index == list->size) { // 插入位置是尾节点
        newNode->prev = list->tail;
        if (list->tail != NULL) {
            list->tail->next = newNode;
        }
        list->tail = newNode;
        if (list->head == NULL) {
            list->head = newNode;
        }
    } else {
        DNode *current = list->head;
        for (size_t i = 0; i < index - 1; i++) {
            current = current->next;
        }
        newNode->next = current->next;
        newNode->prev = current;
        if (current->next != NULL) {
            current->next->prev = newNode;
        }
        current->next = newNode;
    }

    list->size++; // 更新节点个数
}

// 在末尾插入元素
void insertEnd(DoublyLinkedList *list, int element) {
    insertAt(list, list->size, element); // 在链表末尾插入元素
}

// 删除指定位置的元素并返回被删除的元素
int deleteAt(DoublyLinkedList *list, size_t index) {
    if (index >= list->size) {
        return -1; // 忽略无效的删除位置
    }

    int deletedElement;

    if (index == 0) { // 删除位置是头节点
        DNode *temp = list->head;
        list->head = temp->next;
        if (list->head != NULL) {
            list->head->prev = NULL;
        } else {
            list->tail = NULL; // 如果链表只有一个节点
        }
        deletedElement = temp->data;
        free(temp); // 释放被删除节点的内存
    } else if (index == list->size - 1) { // 删除位置是尾节点
        DNode *temp = list->tail;
        list->tail = temp->prev;
        if (list->tail != NULL) {
            list->tail->next = NULL;
        } else {
            list->head = NULL; // 如果链表只有一个节点
        }
        deletedElement = temp->data;
        free(temp); // 释放被删除节点的内存
    } else {
        DNode *current = list->head;
        for (size_t i = 0; i < index - 1; i++) {
            current = current->next;
        }
        DNode *temp = current->next;
        current->next = temp->next;
        if (temp->next != NULL) {
            temp->next->prev = current;
        }
        deletedElement = temp->data;
        free(temp); // 释放被删除节点的内存
    }

    list->size--; // 更新节点个数
    return deletedElement;
}

// 删除末尾元素并返回被删除的元素
int deleteEnd(DoublyLinkedList *list) {
    return deleteAt(list, list->size - 1); // 删除链表末尾的元素
}

// 获取指定位置的元素
int getElementAt(const DoublyLinkedList *list, size_t index) {
    if (index >= list->size) {
        return -1; // 返回无效的索引
    }

    DNode *currentNode = list->head;
    for (size_t i = 0; i < index; i++) {
        currentNode = currentNode->next;
    }

    return currentNode->data; // 返回指定位置的元素
}

// 修改指定位置的元素
void modifyAt(DoublyLinkedList *list, size_t index, int newValue) {
    if (index >= list->size) {
        return; // 忽略无效的修改位置
    }

    DNode *currentNode = list->head;
    for (size_t i = 0; i < index; i++) {
        currentNode = currentNode->next;
    }

    currentNode->data = newValue; // 修改节点的值
}

// 释放双链表内存
void destroyDoublyLinkedList(DoublyLinkedList *list) {
    DNode *currentNode = list->head;
    while (currentNode != NULL) {
        DNode *temp = currentNode;
        currentNode = currentNode->next;
        free(temp); // 释放每个节点的内存
    }

    list->head = NULL; // 头节点置为空
    list->tail = NULL; // 尾节点置为空
    list->size = 0;    // 节点个数置为0
}

// 打印双链表中的所有元素
void printDoublyLinkedList(const DoublyLinkedList *list) {
    DNode *currentNode = list->head;
    while (currentNode != NULL) {
        printf("%d ", currentNode->data);
        currentNode = currentNode->next;
    }
    printf("\n");
}

// 主函数测试双链表操作
int main() {
    DoublyLinkedList myList; // 声明双链表

    initDoublyLinkedList(&myList); // 初始化双链表
    printf("初始化双链表成功!\n");

    insertEnd(&myList, 1); // 链表尾部插入元素1
    insertEnd(&myList, 2); // 链表尾部插入元素2
    insertEnd(&myList, 3); // 链表尾部插入元素3
    printf("向双链表插入了3个元素\n");
    printDoublyLinkedList(&myList); // 打印链表中的元素

    printf("双链表长度为: %zu\n", getLength(&myList)); // 获取双链表长度

    insertAt(&myList, 1, 4); // 在索引1处插入元素4
    printf("在索引1处插入元素4\n");
    printDoublyLinkedList(&myList); // 打印链表中的元素

    printf("双链表长度为: %zu\n", getLength(&myList)); // 再次获取双链表长度

    printf("索引1处的元素为: %d\n", getElementAt(&myList, 1)); // 获取索引1处的元素

    modifyAt(&myList, 0, 5); // 修改索引0处的元素
    printf("把索引0处的元素修改为5\n");
    printDoublyLinkedList(&myList); // 打印链表中的元素

    printf("删除索引1处的元素,该元素值是: %d\n", deleteAt(&myList, 1)); // 删除索引1处的元素
    printDoublyLinkedList(&myList); // 打印链表中的元素

    destroyDoublyLinkedList(&myList); // 销毁双链表
    printf("双链表销毁成功!\n");

    return 0;
}
  • 初始化双链表initDoublyLinkedList 函数初始化双链表,将头节点和尾节点设置为 NULL,节点个数初始化为 0。
  • 返回双链表的长度getLength 函数返回双链表中的节点个数。
  • 在指定位置插入元素insertAt 函数在双链表的指定位置插入一个新节点,根据插入位置调整前后节点的指针。
  • 在末尾插入元素insertEnd 函数在双链表末尾插入一个新节点,调用 insertAt 函数实现。
  • 删除指定位置的元素deleteAt 函数删除双链表中指定位置的节点,并返回该节点的值,根据删除位置调整前后节点的指针。
  • 删除末尾元素deleteEnd 函数删除双链表末尾的节点,调用 deleteAt 函数实现。
  • 获取指定位置的元素getElementAt 函数返回双链表中指定位置的元素,通过遍历找到目标节点。
  • 修改指定位置的元素modifyAt 函数修改双链表中指定位置的节点的值,通过遍历找到目标节点并更新其数据。
  • 释放双链表内存destroyDoublyLinkedList 函数释放双链表中的所有节点内存,并将链表恢复到初始状态。
  • 打印双链表中的所有元素printDoublyLinkedList 函数遍历双链表并打印每个节点的数据。

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

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

相关文章

pandas 在可空列上聚合

pandas支持group_by进行聚合&#xff0c;有如下Excel 按照A B C D四列进行聚合&#xff0c;其中D列可空也就是nan import pandas as pd from pandas import ExcelFile from pathlib import Path import os import io import sys sys.stdout io.TextIOWrapper(sys.stdout.buf…

hdu物联网硬件实验3 按键和中断

学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…

【IT领域新生必看】探索Java中的对象创建:深入理解`new`与`clone`的对比

文章目录 引言什么是new关键字&#xff1f;使用new关键字的基本语法示例&#xff1a; 什么是clone方法&#xff1f;使用clone方法的基本语法示例&#xff1a; new与clone的区别内存分配与初始化调用方式适用场景性能 new关键字的优缺点优点缺点 clone方法的优缺点优点缺点 深入…

语音模块——LSYT201B模组(超详细)

写在前面&#xff1a; 在嵌入式的学习过程中&#xff0c;语音模块是必不可少的&#xff0c;无论是做项目组合还是单个测试&#xff0c;对于语音模块我们应当有一款合适的模块。今天给大家介绍的是一款质量好、成本低、功能齐全的语音模块——LSYT201B语音模组。它的技术支持详细…

DataWhaleAI夏令营 对话要素提取 Baseline2 微调进阶

Baseline2链接&#xff1b;基于星火大模型的群聊对话分角色要素提取挑战-baseline2 - 飞桨AI Studio星河社区 (baidu.com) 数据集再构造 因为数据集中的对话数据还是标离散的&#xff0c;我们可以使用大模型自己先对数据集做一次抽取&#xff0c;构建一个新的数据集 这里对原…

12.SQL注入-盲注基于时间(base on time)

SQL注入-盲注基于时间(base on time) boolian的盲注类型还有返回信息的状态&#xff0c;但是基于时间的盲注就什么都没有返回信息。 输入payload语句进行睡5秒中&#xff0c;通过开发这工具查看时间&#xff0c;如图所示&#xff0c;会在5秒钟后在执行&#xff0c;因此存在基于…

【SpringCloud】概述 -- 微服务入门

在Java的整个学习过程中&#xff0c;大家势必会听见一些什么分布式-微服务、高并发、高可用这些专业术语&#xff0c;给人的感觉很高级&#xff0c;有一种高深莫测的感觉。可以看一下这篇博客对这些技术架构的演变有一个初步的认识: 服务端⾼并发分布式结构演进之路-CSDN博客文…

数据结构——单向循环链表

文章目录 1. 概念 2. 区别 2.1 结构区别 2.2 访问方式区别 2.3 优缺点对比 3. 流程 4. 基本操作 5. 代码示例 1. 概念 单向循环链表是一种特殊的单链表&#xff0c;其中最后一个节点的后继指针指向头节点&#xff0c;形成一个环。单向循环链表适合用于需要循环访问数据…

UCOS-III 系统移植

1. 移植前准备 1.1 源码下载 UCOS-III Kernel Source&#xff1a; https://github.com/weston-embedded/uC-OS3.git Micriμm CPU Source &#xff1a; https://github.com/weston-embedded/uC-CPU.git Micriμm Lib Source&#xff1a; https://github.com/weston-embedded…

Intellj idea无法启动

个人电脑上安装的是2024.01版本的intellj idea作为开发工具&#xff0c;引入了javaagent作为工具包 但是在一次invaliad cache操作后&#xff0c;intellj idea就无法启动了&#xff0c;双击无响应。 重装了idea后也无效&#xff08;这个是有原因的&#xff0c;下面会讲&#…

java项目总结4

1.正则表达式 用于验证字符串是否满足自己所需要的规则。方法&#xff1a;matches 注意&#xff1a;\在Java中有特殊涵义&#xff0c;是将其它的意思本来化&#xff0c;假设"是用来引用字符串的&#xff0c;但是你如果想要输出它&#xff0c;那是不是就变成了System.out…

机器学习---线性回归

1、线性回归 例如&#xff1a;对于一个房子的价格&#xff0c;其影响因素有很多&#xff0c;例如房子的面积、房子的卧室数量、房子的卫生间数量等等都会影响房子的价格。这些影响因子不妨用 x i x_{i} xi​表示&#xff0c;那么房价 y y y可以用如下公式表示&#xff1a; y …

基于Qt实现的PDF阅读、编辑工具

记录一下实现pdf工具功能 语言&#xff1a;c、qt IDE&#xff1a;vs2017 环境&#xff1a;win10 一、功能演示&#xff1a; 二、功能介绍&#xff1a; 1.基于saribbon主体界面框架&#xff0c;该框架主要是为了实现类似word导航项 2.加载PDF放大缩小以及预览功能 3.pdf页面跳转…

01--SpringAI接入大模型,chatgpt,Java接入人工智能大模型

01–SpringAI接入大模型,chatgpt,Java接入人工智能大模型 文章目录 01--SpringAI接入大模型,chatgpt,Java接入人工智能大模型一、准备工作&#xff1f;①&#xff1a;环境准备 二、创建一个springAI项目①&#xff1a;创建一个根项目②&#xff1a;创建一个SpringAI模块01.解决…

Dos(命令符窗口)命令

目录 1. 常用Windows组合键 2. 常用DOS命令 3. 复制操作 4. 当前路径 5. 查看电脑ip地址 6. 切换盘符: 7. 目录 8. 自动补齐 8. 进入某路径&#xff1a;cd 路径 9. 直接进入某个位置 10. 新建文件 11. 查看文件内容 12. 关机 13. 强行终止命令的执行&#xff1a;C…

python conda查看源,修改源

查看源 conda config --show-sources 修改源 可以直接vim .condarc修改源&#xff0c;

查看java版本和安装位置-cnblog

查看java位置 进入设置&#xff0c;高级系统设置 打开环境变量 找到path双击 查看java版本 java -version

中电金信:加快企业 AI 平台升级,构建金融智能业务新引擎

在当今数字化时代的浪潮下&#xff0c;人工智能&#xff08;AI&#xff09;技术的蓬勃发展正为各行业带来前所未有的变革与创新契机。尤其是在金融领域&#xff0c;AI 模型的广泛应用已然成为提升竞争力、优化业务流程以及实现智能化转型的关键驱动力。然而&#xff0c;企业在积…

刷代码随想录有感(126):动态规划——不相交的线

题干&#xff1a; 代码&#xff1a; class Solution { public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>>dp(nums1.size() 1, vector<int>(nums2.size() 1, 0));for(int i 1; i < num…

Github与本地仓库建立链接、Git命令(或使用Github桌面应用)

一、Git命令&#xff08;不嫌麻烦可以使用Github桌面应用&#xff09; git clone [] cd [] git branch -vv #查看本地对应远程的分支对应关系 git branch -a #查看本地和远程所有分支 git checkout -b [hongyuan] #以当前的本地分支作为基础新建一个【】分支,命名为h…