数据结构:线性结构(C语言)

2023-05-16

文章目录

  • 线性结构
    • 线性表
      • 什么是线性表
      • 线性表的抽象类型描述
      • 线性表的实现
    • 广义表
      • 广义表定义
      • 多重链表
    • 堆栈
      • 什么是堆栈
      • 堆栈的抽象数据类型描述
      • 堆栈的顺序存储实现
      • 堆栈的链式存储实现
      • 堆栈的应用
    • 队列
      • 什么是队列
      • 队列的抽象数据类型描述
      • 队列的顺序存储实现
      • 队列的链式存储实现


线性结构

线性表

什么是线性表

  1. 线性表(Linear List):由同类型数据元素构成有序序列的线性结构。

    • 表中元素个数称为线性表的长度
    • 线性表没有元素时,称为空表
    • 表起始位置称表头,表结束位置称表尾

线性表的抽象类型描述

  1. 类型名称:线性表(List)。

  2. 数据对象集:线性表是 n(n≥0) 个元素构成的有序序列 ( a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an)

  3. 操作集:线性表 L ∈ L i s t L \in List LList,整数i表示位置,元素 X ∈ E l e m e n t T y p e X \in ElementType XElementType,线性表的基本操作主要有:

    1. List MakeEmpty():初始化空线性表L
    2. ElementType FindKth(int K,List L):根据位序K,返回相应元素。
    3. int Find(ElementType X,List L): 在线性表L中查找X的第一次出现的位置。
    4. void Insert(ElementType X,int i,List L):在位序i前插入一个新元素X。
    5. void Delete(int i,List L):删除指定位序i的元素。
    6. int Length(List L):返回线性表L的长度n。

线性表的实现

  1. 利用数组的连续存储空间顺序存放线性表的各元素。

    struct LNode{
        ELementType Data[MAXSIZE];//MAXSIZE是空间大小
        int Last;//最后一个元素的下标是Last,而不是Last+1
    };
    typedef struct LNode* List;
    struct LNode L;
    List LPtr;
    

    访问下标为i的元素:L.Data[i]或LPtr->Data[i]。
    线性表的长度:L.Last+1或者LPtr->Last+1。

    • 主要操作的实现

      1. 初始化(建立空的顺序表)

        List MakeEmpty()
        {
            List LPtr=NULL;
            LPtr=(List)malloc(sizeof(struct LNode));
            LPtr->Last=-1;
            return LPtr;
        }
        
      2. 查找

        int Find(ElementType X,List LPtr)
        {
            int i=0;
            while(i<=LPtr->Last&&LPtr->Data[i]!=x)
            {
                i++;
            }
            if(i>LPtr->Last)
            {
                return -1;//如果没有找到,返回-1
            }
            else
            {
                return i;//找到后返回存储位置i
            }
        }
        
        
      3. 插入(第i( 1 ≤ i ≤ n + 1 1 \leq i \leq n+1 1in+1)个位置上插入一个之为X的新元素)

        下标i01……i-1i……n-1……MAZSIZE-1
        Data a 1 a_1 a1 a 2 a_2 a2…… a i a_i ai a i + 1 a_{i+1} ai+1…… a n ( L a s t ) a_n(Last) an(Last)……-

        再第i个位置插入,将 a i a_i ai~ a n a_n an往后移动,再插入。

        下标i01……i-1ii+1……n……MAZSIZE-1
        Data a 1 a_1 a1 a 2 a_2 a2…… a i a_i ai a i + 1 a_{i+1} ai+1…… a n ( L a s t ) a_n(Last) an(Last)……-

        算法实现:

        void Insert(ElementType X,int i,List LPtr)
        {
            int j=0;
            //表空间已满,不能插入
            if(LPtr->Last==MAXSIZE-1)
            {
                printf("表满\n")return}
        
            //检查插入位置的合法性
            if(1>i||LPtr->Last+2<i)
            {
                printf("位置不合法\n");
                return;
            }
        
            //将a_i~a_n往后移动
            for(j=LPtr->Last;j>=i-1;j--)
            {
                LPtr->Data[j+1]=LPtr->Data[j];
            }
            LPtr->Data[i-1]=X;//将数据X放在第i个位置
            LPtr->Last++;//Last指向最后一个元素
        }
        

        平均移动次数为n/2
        平均时间复杂度为O(n)。

      4. 删除(删除表的第i( 1 ≤ i ≤ n 1 \leq i \leq n 1in)个位置上的元素)

        下标i01……i-1i……n-1……MAZSIZE-1
        Data a 1 a_1 a1 a 2 a_2 a2…… a i a_i ai a i + 1 a_{i+1} ai+1…… a n ( L a s t ) a_n(Last) an(Last)……-

        删除第i个位置的数据,将第i个数据之后的数据往前挪。

        下标i01……i-1……n-2n-1……MAZSIZE-1
        Data a 1 a_1 a1 a 2 a_2 a2…… a i + 1 a_{i+1} ai+1…… a n ( L a s t ) a_n(Last) an(Last)……-

        算法实现:

        void Delete(int i,List LPtr)
        {
            int j=0;
            //检查空表及删除位置的合法性
            if(1>i||i>LPtr->Last+1)
            {
                printf("不存在第%d个元素",i);
                return;
            }
            //将第i个元素后面的元素向前移动
            for(j=i;j<=LPtr->Last;j++)
            {
                LPtr->Data[j-1]=LPtr->Data[j];
            }
            LPtr->Last--;//Last指向最后元素
        }
        

        平均移动次数为(n-1)/2
        平均时间复杂度O(n)。

  2. 线性表的链式存储实现
    不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。

    • 插入、删除不需要移动数据元素,只需要修改链。

    链表

    struct LNode{
        ElementType Data;
        struct LNode *Next;
    };
    typedef struct LNode *List;
    struct LNode L;
    List LPtr;
    
    • 主要操作的实现

      1. 求表长

        int Length(List LPtr)
        {
            List currentPtr=LPtr;//currentPtr指向第一个节点
            int i=0;
            while(currentPtr)
            {
                currentPtr=currentPtr->Next;
                i++;
            }
            return i;
        }
        

        时间复杂度O(n)。

      2. 查找

        1. 按序号查找:FindKth();

          List FindKth(int K,List LPtr)
          {
              List currentPtr=LPtr;
              int i=1;
              //将currentPtr指向第K个元素或者将currentPtr指向最后的NULL
              while(currentPtr!=NULL&&K>i)
              {
                  currentPtr=currentPtr->Next;
                  i++;
              }
          
              //判断K是否超过链表长度,没有超过返回指向第K个元素指针,超过则返回NULL
              if(K==i)
              {
                  return currentPtr;
              }
              else
              {
                  return NULL;
              }
          }
          

          时间复杂度O(n)。

        2. 按值查找:Find()

          List Find(ElementType X,List LPtr)
          {
              List currentPtr=LPtr;
              while(currentPtr!=NULL&&X!=currentPtr->Data)
              {
                  currentPtr=currentPtr->Next;
              }
              return currentPtr;
          }
          

          时间复杂度O(n)。

      3. 插入(再第i-1( 1 ≤ i ≤ n + 1 1 \leq i \leq n+1 1in+1)个节点后插入一个值为X的新节点)

        • 先构造一个新节点,用s指向;
        • 再找到链表的第i-1个节点,用p指向;
        • 然后修改指针,在插入节点(p之后插入新节点是s)

        插入前:

        链表插入前

        操作顺序:

        s->Next=p->Next;
        p->Next=s;
        

        插入后:
        链表插入后

        代码示例:

        List Insert(ElementType X,int i,List LPtr)
        {
            List p=NULL,s=NULL;
            //插入节点在表头的情况
            if(i==1)
            {
                s=(List)malloc(sizeof(struct LNode));//构造新节点
                s->Data=X;
                s->Next=LPtr;
                return s;
            }
        
            //插入节点不再表头的情况
            p=FindKth(int i-1,LPtr);//查找第i-1个节点
            //第i-1个节点不存在,不能插入
            if(p=NULL)
            {
                printf("参数i错误");
                return NULL;
            }
            else
            {
                s=(List)malloc(sizeof(struct LNode));//构造新节点
                s->Data=X;
                s->Next=p->Next;
                p->Next=s;
                return LPtr;
            }
        }
        

        时间复杂度O(n)。

      4. 删除(删除链表的第i( 1 ≤ i ≤ n 1 \leq i \leq n 1in)个位置上的节点)

        • 先找到链表的第i-1个节点,用p指向;
        • 再用指针s指向要被删除的节点(p的下一个节点);
        • 然后修改指针,删除s所指节点;
        • 最后释放s所指节点的空间。

        删除前:

        节点删除前

        操作顺序:

        p->Next=s->Next;
        free(s);
        

        删除后:

        节点删除后

        代码示例:

        List Delete(int i,List LPtr)
        {
            List p=NULL,s=NULL;
            //要删除的节点是头节点的情况
            if(1==i)
            {
                s=LPtr;
                //判断是不是空表
                if(LPtr!=NULL)
                {
                    LPtr=LPtr->Next;
                    free(s);
                    return LPtr;
                }
                else
                {
                    return NULL;
                }
            }
        
            //要删除的节点不是头节点的情况
            p=FindKth(i-1,LPtr);
            //第i个节点不存在的情况
            if(p==NULL||p->Next==NULL)
            {
                printf("第%d个节点不存在",i)return NULL;
            }
            //第i个节点存在的情况
            else
            {
                s=p->Next;//s指向将被删除的第i个节点
                p->Next=s->Next;//删除节点
                free(s);//释放被删除节点
                return LPtr;
            }
        }
        

        时间复杂度O(n)。


广义表

广义表定义

  • 广义表是线性表的推广
  • 对于线性表来说,n个元素都是基本的单元素
  • 广义表中,这些元素不仅可以是单元素也可以是另一个广义表
struct GNode{
    int Tag;//标志域:0表示节点是单元素,1表示节点是广义表
    //子表指针域subList与单元数据域Data复用,即共用存储空间
    union{
        ElementType Data;
        GList SubList;
    }URegion;
    struct GNode *Next;//指向后继节点
};
typedef struct GNode* GList;

广义表

多重链表

多重链表:链表中的节点可能同时属于多个链

  • 多重链表中节点的指针域会有多个,如广义表中包含了Next和SubList两个指针域;
  • 但包含两个指针域的链表并不一定是多重链表,比如双向链表不是多重链表

多重链表有广泛的用途:基本上如这样的相对复杂的数据结构都可以采用多重链表方式实现存储。

多重链表的应用:
多重链表的应用

矩阵多重链表示意图:
矩阵多重链表示意图

矩阵多重链表节点设计:
矩阵多重链表节点设计


堆栈

什么是堆栈

堆栈(Stack):具有一定操作约束的线性表。

  • 只在一端(栈顶,Top)做插入、删除

    • 插入数据:入栈(Push)

    • 删除数据:出栈(Pop)

  • 后入先出:Last In First Out(LIFO)

堆栈的抽象数据类型描述

类型名称:堆栈(Stack)
数据对象集:一个有个或多个元素的有穷线性表。
操作集:长度为MaxSize的堆栈 S ∈ S t a c k S \in Stack SStack,堆栈元素 i t e m ∈ E l e m e n t T y p e item \in ElementType itemElementType

  1. Stack CreateStack(int MaxSize):生成空堆栈,其最大长度为MaxSize;
  2. int IsFull(Stack S,int MaxSize):判断堆栈S是否已满;
  3. void Push(Stack S,ElementType item):将元素item压入堆栈;
  4. int IsEmpty(Stack S):判断堆栈S是否为空;
  5. ElementType Pop(Stack S):删除并返回栈顶元素;

堆栈的顺序存储实现

栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成。

#define MaxSize <存储数据元素的最大个数>
struct SNode{
    ElementType Data[MaxSize];
    int Top;//栈顶的下标
};
typedef struct SNode* Stack;
  • 主要操作实现

    1. 入栈

      void Push(Stack SPtr, ElementType itme)
      {
          if(SPtr->Top==MaxSize-1)
          {
              printf("堆栈满");
              return;
          }
          else
          {
              SPtr->Data[++(SPtr->Top)]=itme;//Top先自加一,然后再给栈顶元素赋值。
              return;
          }
      }
      
    2. 出栈

      ElementType Pop(Stack SPtr)
      {
          if(SPtr->Top==-1)
          {
              printf("堆栈空");
              return ERROR;//ERROR是ElementType的特殊值,标志错误
          }
          else
          {
              return (SPtr->Data[(SPtr->Top)--]);//先返回栈顶元素,再将Top减一。
          }
      }
      

堆栈的链式存储实现

堆栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。

思考:栈顶指针Top应该在链表的哪一头?
:应该将栈顶指针放在链表的头部,这样插入和删除操作都很方便;如果将栈顶指针放在链表尾部,那么删除操作实现比较困难。

struct SNode{
    ElementType Data;
    struct SNode *Next;
};
typedef struct SNode* Stack;
  • 主要操作实现

    1. 建立空栈(空栈指只有一个头节点,节点不带任何数据)

      Stack CreateStack()
      {
          //建立堆栈的一个头节点,返回指针。
          Stack S=NULL;
          S=(Stack)malloc(sizeof(struct SNode));
          S->Next=NULL;
          return S;
      }
      
    2. 判断堆栈S是否为空

      int IsEmpty(Stack S)
      {
          //为空返回1;否则返回0
          return (S->Next==NULL);
      }
      
    3. 入栈

      void Push(ElementType item,Stack S)
      {
          //不需要判断空间是否已经满了,因为链式堆栈的空间是动态申请的。
          Stack Temp=NULL;
          Temp=(stack)malloc(sizeof(struct SNode));
          Temp->Data=item;
          Temp->Next=S->Next;
          S->Next=Temp;
      }
      
    4. 出栈

      ElementType Pop(Stack S)
      {
          Stack TempCell=NULL;
          ElementType TempElem=0;
          if(S->Next==NULL)
          {
              printf("d堆栈空");
              return NULL;
          }
          else
          {
              TempCell=S->Next;
              S->Next=TempCell->Next;
              TempElem=TempCell->Data;
              free(TempCell);
              return TempElem;
          }
      }
      

堆栈的应用

  1. 表达式求值
    具体过程详见https://blog.csdn.net/qq_42313728/article/details/99625250
  2. 函数调用及递归实现
  3. 深度优先搜索
  4. 回溯算法

队列

什么是队列

队列(Queue):具有一定操作约束的线性表

  • 删除和插入操作:只能在一端插入,而在另一端删除
    • 数据插入:入队列(AddQ)
    • 数据删除:出队列(DeleteQ)
  • 先进先出:FIFO

队列的抽象数据类型描述

数据名称:队列(Queue)
数据对象集:一个有0个或多个元素的有穷线性表。
操作集:长度为MaxSize的队列 Q ∈ Q u e u e Q \in Queue QQueue,队列元素 i t e m ∈ E l e m e n t T y p e item \in ElementType itemElementType

  1. Queue CreatQueue(int MaxSize):生成长度为MaxSize的空队列;
  2. int IsFull(Queue Q,int MaxSize):判断队列Q是否已满;
  3. void AddQ(Queue Q,ElementType item):将数据元素插入到队列Q中;
  4. int IsEmpty(Queue Q):判断队列Q是否为空;
  5. ElementType DeleteQ(Queue Q):将队头数据元素从队列中删除并返回。

队列的顺序存储实现

队列的顺序存储结构通常由一个一位数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。(rear指向对列尾最后一个元素,front指向队列头元素的前一个元素)

#define MAXSIZE <存储数据元素的最大个数>
struct QNode{
    ElementType Data[MAXSIZE];
    int rear;
    int front;
};
typedef struct QNode *Queue;

在循环队列中,判空和判满的条件都是rear==front:

队列空时:

队列空时

队列将满时(再增加一个元素之后队列满,然后rear==front):

队列将满时

解决这个问题的方法有两种

  1. 使用额外标记:size或者tag域

    1. 用size来记录当前队列元素的个数,插入一个元素size加1,删除一个元素size减1。
    2. 用tag来记录队列上一次操作是插入还是删除,插入一个元素tag=1,删除一个元素tag=0,当front==rear时,根据tag来判断队列是空还是满。
  2. 仅使用MAXSIZE-1个数组空间

  • 主要操作实现(第二种解决方案)
    1. 入队列

      void AddQ(Queue QPtr,ElementType item)
      {
          if((QPtr->rear+1)%MAXSIZE==QPtr->front)
          {
              printf("队列满");
              return;
          }
          QPtr->rear=(QPtr->rear+1)%MAXSIZE;
          QPtr->Data[QPtr->rear]=item;
      }
      
    2. 出队列

      ElementType DeleteQ(Queue QPtr)
      {
          if(QPtr->rear==QPtr->front)
          {
              printf("队列空");
              return ERROR;
          }
          else
          {
              QPtr->front=(QPtr->front+1)%MAXSIZE;
              return QPtr->Data[QPtr->front];
          }
      }
      

队列的链式存储实现

队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行。(front指向队列头元素,rear指向队列尾元素)

:队列指针front和rear应该分别指向链表的哪一头?

:队列front端用来进行删除操作,rear端用来做插入操作;而单向链表的头部插入删除都很方便,尾部插入方便,但是删除麻烦;所以front应该指向单向链表的头部,rear应该指向单向链表的尾部。

//链表节点结构
struct Node{
    ElementType Data;
    struct Node *Next;
};
//队列头尾结构
struct QNode{
    struct Node *rear;
    struct Node *front;
};
typedef struct QNode *Queue;
Queue QPtr;
  • 主要操作实现
    1. 入队列(不带头结点)

      void AddQ(Queue QPtr,ElementType item)
      {
          //新建一个节点
          struct Node *RearCell;
          RearCell=(struct Node*)malloc(sizeof(struct Node));
          RearCell->Data=item;
          RearCell->Next=NULL;
      
          //队列为空的情况
          if(QPtr->rear==NULL)
          {
              QPtr->rear=RearCell;
              QPtr->front=RearCell;
          }
          //队列不为空时
          else
          {
              QPtr->rear->Next=RearCell;
              QPtr->rear=RearCell;
          }
      }
      
    2. 出队列(不带头结点)

      ElementType Delete(Queue QPtr)
      {
          struct Node *FrontCell;
          ElementType FrontElem;
      
          if(QPtr->front==NULL)
          {
              printf("队列空");
              return ERROR;
          }
          FrontCell=QPtr->front;//将FrontCell指向当前头元素
          //队列只有一个元素时
          if(QPtr->front==QPtr->rear)
          {
              //将front和rear都指向空
              QPtr->front=NULL;
              QPtr->rear=NULL;
          }
          //队列不止一个元素时
          else
          {
              //将front指向下一节点
              QPtr->front=QPtr->front->Next;
          }
      
          FrontElem=FrontCell->Data;
          free(FrontCell);//释放被删除节点
          return FrontElem;
      }
      
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构:线性结构(C语言) 的相关文章

  • ES6新特性-含代码-通俗易懂

    一 新增const let变量 const用来定义常量 xff0c 它保存的值是不能再次改变的 这里说的是基本类型 xff0c 如果是对象类型则不可改变其内存地址 可以改变对象中的内容 xff0c 同时也不能多次定义同名变量 const v
  • 考试系统-新版

    最新考试系统 通过JSP xff08 Java Server Page xff09 技术和Tomcat服务器搭建的一个在线考试系统的设计与实现 针对目前的教学考核都普遍存在有选择题 xff0c 题型都是有固定的答案形式 本在线考试系统设计成
  • 金融系统-基金管理

    金融系统 基金管理 本项目为携投基金系统 xff0c 在客户端浏览器输入网址 xff0c 即可载入该系统 xff0c 本系统采用当前主流前端开发语言有 xff1a layui js等前端主流技术 采用的后端开发语言框架等有 xff1a SS
  • 学校教材管理系统-毕设、课设(最佳参考)

    下载地址 高校教材管理系统 项目介绍 基于springboot 43 mybatis 43 jwt 43 layui 43 mybatis 43 html 43 javaScript的用于高校管理教材的系统 项目主要功能 教材信息管理 教材
  • android-校园拍卖管理系统-毕设课设-含源码

    校园拍卖系统 android 源码私信 xff0c 有回必应 xff0c 三连关注 xff0c 免费 xff01 xff01 xff01 android实现校园拍卖系统 xff0c 使用语言为java xff0c 工具idea或者andro
  • ChatGPT 未来的前景以及发展趋势

    当谈到ChatGPT的未来和发展趋势时 xff0c 需要考虑人工智能技术以及文本生成和交互的迅速发展 在这方面 xff0c ChatGPT的前景非常有希望 xff0c 因为它是一种迄今为止最先进的人工智能技术之一 ChatGPT是一种基于机
  • 同步FIFO 两种方法

    RAM 43 空满信号判断 xff0c 两种方法 一 空满标志用指针位置得到 二 空满标志用fifo的中数据的计数得到 一 当写指针超过读指针一圈 xff0c 写满 xff1b 写指针等于读指针 xff0c 读空 96 timescale
  • linux内核串口日志抓取-minicom工具使用方法

    linux抓串口日志 抓串口日志方式minicom保存串口日志log抓取主板串口日志minicom man手册 抓串口日志方式 1 xff09 问题机上 xff0c 找到串口设备 xff0c 比如 dev ttyAMA 0 1 2 3 st
  • 二叉树(七):二叉树的高度与平衡二叉树

    一 二叉树的深度与高度 1 二叉树的深度 对于二叉树中的某个节点 xff0c 其深度是从根节点到该节点的最长简单路径所包含的节点个数 xff0c 是从上面向下面数的 因此访问某个节点的深度要使用先序遍历 2 二叉树的高度 对于二叉树中的某个
  • Python --语法自纠

    文章目录 1 输入2 数据类型转换 xff0c 字符串3 字典 xff0c 列表 xff0c 元组4 语法0 错题 1 输入 输入eval作用一次输入一个或多个 map print format m n format输出 2 数据类型转换
  • 强化学习算法复现(六):DoubleDQN_gym倒立摆

    建立RL brain py span class token keyword import span torch span class token keyword import span torch span class token pun
  • Android的控件绑定----ViewBinding

    在Android开发中 xff0c 控件的绑定是开发者无法绕开的一道程序 是Android开发中最原始 xff0c 也是最基础的一种获取View的方法 在一个复杂布局的页面时 xff0c 我们要一个个控件去调用findViewById方法去
  • C++ OpenCV CV_***未声明的标识符的解决办法

    1 OpenCV cvtColor CV BGR2GRAY未声明的标识符的解决办法 加上这个引用即可 include lt opencv2 imgproc types c h gt 2 opencv里面CV FOURCC找不到标识符 CV
  • 多线程-生产者和消费者模式

    1 简单实现多线程 多线程是多任务处理的一种特殊形式 xff0c 多线程处理允许让一个进程中同时运行两个或两个以上的线程 这样的话 xff0c 能更加充分发挥计算机的性能 xff0c 并高效完成用户的任务 多线程实现的三步骤 xff1a 第
  • HTML网页注册图片

    lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt lt title gt lt style type 61 34 t
  • [WAX云钱包】解决Cloudflare通过SSL指纹识别实现的反爬虫机制

    WAX云钱包 在之前的多篇文章中 xff0c 我们使用 Python 43 Selenium 来实现WAX链游脚本 xff0c 主要是因为很多玩家一开始都是用WAX云钱包注册的账号 xff0c 而WAX云钱包的私钥托管在云端 xff0c 我
  • 小狼毫[rime_win][眀月拼音]简单配置方法

    小狼毫 rime win 朙月拼音 简单配置方法 我自己的配置文件 当配置后 需要重新部署后设置才能生效 需要修改的文件 需要修改 增加的文件均在用户文件夹下 用户文件夹可以通过右键输入法状态栏的图标后点击用户文件夹到达 修改 增加的文件名
  • 生产者消费者模式(c++)

    什么是生产者消费者模式 xff1f 想象一下 xff0c 你早上起来肚子快饿扁了 xff0c 去包子铺买包子 xff0c 包子铺有三个人在做包子 xff08 也可以是一个 xff09 xff0c 这些人就是生产者 xff0c 你作为买包子的
  • go语言interface转string、bool、int

    在go语言中interface转string可以直接使用fmt提供的fmt函数 xff0c 而转bool和int则是在string的基础上来进行转换 xff0c 详见如下代码 func Get f string value interfac
  • centos7中启动juoyter notebook后,复制链接无法打开网页

    centos7中启动juoyter notebook后 xff0c 复制链接无法打开网页 xff0c 一直停留在如下界面 xff1a 解决办法 xff1a 这需要在Linux浏览器中打开 在windows中无法打开 xff0c 若没有安装l

随机推荐