C语言基础——⑩③数据结构——②栈和队列

news2024/12/23 4:10:13

一、栈(Stack)

1、基本概念

栈是一种逻辑结构,是特殊的线性表。特殊在:

  • 只能在固定的一端操作

只要满足上述条件,那么这种特殊的线性表就会呈现一种“后进先出”的逻辑,这种逻辑就被称为栈。栈 在生活中到处可见,比如堆叠的盘子、电梯中的人们、嵌套函数的参数等等。

由于约定了只能在线性表固定的一端进行操作,于是给栈这种特殊的线性表的“插入”、“删除”,另起了 下面这些特定的名称:

  • 栈顶:可以进行插入删除的一端;
  • 栈底:栈顶的对端;
  • 入栈:将节点插入栈顶之上,也称为压栈,函数名通常为push();
  • 出栈:将节点从栈顶剔除,也称为弹栈,函数名通常为pop();
  • 取栈顶:取得栈顶元素,但不出栈,函数名通常为top()

基于这种固定一端操作的简单约定,栈获得了“后进先出”的基本特性,如下图所示,最后一个放入的元素,最先被拿出来:

2、存储形式

栈只是一种数据逻辑,如何将数据存储于内存则是另一回事。一般而言,可以采用顺序存储形成顺序栈,或采用链式存储形成链式栈

1.顺序栈(sequenceStack)

顺序存储意味着开辟一块连续的内存来存储数据节点,一般而言,管理栈数据除了需要一块连续的 内存之外,还需要记录栈的总容量、当前栈的元素个数、当前栈顶元素位置,如果有多线程还需要 配互斥锁和信号量等信息,为了便于管理,通常将这些信息统一于在一个管理结构体之中:

// 顺序栈节点
struct seqStack
{
    datatype *data; // 顺序栈入口
    int size;       // 顺序栈总容量
    int top;        // 顺序栈栈顶元素下标
};

2.链式栈(linkStack)

链式栈的组织形式与链表无异,只不过插入删除被约束在固定的一端。为了便于操作,通常也会创 建所谓管理结构体,用来存储栈顶指针、栈元素个数等信息:

// 链式栈节点
typedef struct node
{
    datatype data;
    struct node *next;
}node;
// 链式栈管理结构体
struct linkStack
{
    node *top; // 链式栈栈顶指针
    int  size; // 链式栈当前元素个数
};

3、完整代码

  • 顺序栈(sequenceStack)

  1. sstack.h
    #ifndef __SSTACK_H
    #define __SSTACK_H
    // 数据类型
    typedef int DATA;
    // 顺序栈结构体
    typedef  struct
    {
        DATA      *pData; // 栈中元素的地址
        int         size; // 栈的总容量
        int         top;  // 栈顶元素下标
    }SeqStack;
    // 初始化栈
    int SStack_init(SeqStack *s, int num);
    // 判断栈是否已满
    int SStack_isfull(SeqStack *st);
    // 判断栈是否为空
    int SStack_isempty(SeqStack *st);
    // 入栈/压栈
    int SStack_push(SeqStack *st,DATA data);
    // 出栈/弹栈
    int SStack_pop(SeqStack *st,DATA *data);
    // 回收栈
    int SStack_free(SeqStack *st);
    #endif
    
  2. sstack.c
    #include <stdlib.h>
    #include "sstack.h"
    // 初始化栈
    int SStack_init(SeqStack* s,int num)
    {
        s -> pData = (DATA*)calloc(sizeof(DATA),num);
        if(s -> pData == NULL)
           return -1;
        s -> size  = num ;
        s -> top   = -1;
        return 0;
    }
    // 判断栈是否已满
    int SStack_isfull(SeqStack *st)
    {
        return st -> top + 1 == st -> size;
    }
    // 判断栈是否为空
    int SStack_isempty(SeqStack *st)
    {
        return st -> top == -1;
    }
    // 压栈/入栈
    int SStack_push(SeqStack *st,DATA data)
    {
        if(SStack_isfull(st))
           return -1;
        st -> top++;
        st -> pData[st -> top] = data;
        return 0;
    }
    // 出栈/弹栈
    int SStack_pop(SeqStack *st,DATA *data)
    {
        if(SStack_isempty(st))
           return -1;
        *data = st -> pData[st -> top];
        st -> top--;
        return 0;
    }
    // 回收栈
    int SStack_free(SeqStack *st)
    {
        if(st -> pData)
       {
             free(st->pData);
             st -> pData = NULL;
       }
        st -> top = -1;  
    }
    
  3. sstack_main.c
    #include "sstack.h"
    #include <stdio.h>
    int main(void)
    {
       SeqStack  st;
      
       SStack_init(&st,10);
       register int i = 1;
       for(; i <=10; i++)
          SStack_push(&st,i);
       if(-1 == SStack_push(&st,1024))
         fprintf(stderr,"满栈,插入失败\n");
        while(!SStack_isempty(&st))
       {
             DATA   data = 0;
             SStack_pop(&st,&data);
             printf("%4d",data);         
       }
        printf("\n");
        SStack_free(&st);
       
        return 0;  
    }
    

【课堂练习1】

使用顺序栈,接收键盘的输入,实现如下功能:

1. 输入数字时,依次入栈。

2. 输入字母时,依次出栈。

3. 每次入栈或者出栈,都将顺序栈中的各个元素输出出来。

  • 完整代码(链式栈(linkStack))

  1. linkstack.h
    #ifndef __LINKSTACK_H
    #define __LINKSTACK_H
    // 数据类型
    typedef   int   DATA;
    // 链式栈节点
    typedef   struct  _node
    {
        DATA       data; // 数据
        struct _node *next; // 指向下一个栈的节点
    }NODE;
    // 链式栈管理结构体
    typedef  struct
    {
        NODE     *pHead;// 链式栈栈顶指针
        int       size; // 链式栈当前元素个数
        int       num;
    }LinkStack;
    // 初始化链式栈
    int LStack_init(LinkStack *s, int num);
    // 判断栈是否已满
    int LStack_isfull(LinkStack *st);
    // 判断栈是否为空
    int LStack_isempty(LinkStack *st);
    // 压栈/入栈
    int LStack_push(LinkStack *st,DATA data);
    // 弹栈/出栈
    int LStack_pop(LinkStack *st,DATA *data);
    // 回收栈
    int LStack_free(LinkStack *st);
    #endif
    
  2. linkstack.c
    #include "linkstack.h"
    #include <stdio.h>
    #include <stdlib.h>
    // 初始化栈
    int LStack_init(LinkStack *st, int num)
    {
        st -> pHead = NULL;
        st -> size  = num;
        st -> num   = 0;
        return 0 ;
    }
    // 判断栈是否已满
    int LStack_isfull(LinkStack *st)
    {
        return st -> num == st -> size;
    }
    // 判断栈是否为空
    int LStack_isempty(LinkStack *st)
    {
         return st -> num == 0;
    }
    // 入栈
    int LStack_push(LinkStack *st,DATA data)
    {
        if(LStack_isfull(st))
           return -1;
        NODE* p = (NODE*)malloc(sizeof(NODE));
        if(!p)
           return -1;
        p -> data   = data;
        p -> next   = st -> pHead;
        st -> pHead = p;
        
       (st -> num)++;
        return 0;
    }
    // 出栈
    int LStack_pop(LinkStack *st,DATA *data)
    {
        if(LStack_isempty(st))
           return -1;
        NODE* p = st -> pHead;
        if(!p)
           return -1;
        *data = p -> data;
        st -> pHead = p -> next;
        free(p);
       (st -> num)--;
        return 0;
    }
    // 回收栈
    int LStack_free(LinkStack *st)
    {
        NODE* p = st -> pHead, *q = NULL;
        while(p)
       {
            q  = p;
            p  = p -> next;
            free(q);       
       }
        st -> pHead = NULL;
        st -> num   = 0;
        return 0;
    }
    
  3. linkstack_main.c
    #include "linkstack.h"
    #include <stdio.h>
    int main(void)
    {
       LinkStack  st;
       LStack_init(&st,10);
       register int i = 1;
       for(; i <= 10; i++)
          LStack_push(&st,i);
       if(-1 == LStack_push(&st,1024))
         fprintf(stderr,"满栈,插入失败\n");
        while(!LStack_isempty(&st))
       {
             DATA   data = 0;
             LStack_pop(&st,&data);
             printf("%4d",data);         
       }
        printf("\n");
        LStack_free(&st);
        return 0;  
    }
    

【课堂练习2】

使用链式栈,实现十进制转八进制:键盘输入一个十进制数,经过链式栈的相关算法,输出八进制 数。

代码:

 

二、队列(queue)

1、基本概念

队列是一种逻辑结构,是一种 特殊的线性表。特殊在: 只能在固定的两端操作线性表 只要满足上述条件,那么这种特殊的线性表就会呈现一种“先进先出”的逻辑,这种逻辑就被称为队列。

队列本质上,是从一端进,另一端出,为了保证跟生活的认知一致,我们建议把进的一端叫做队尾,出的一端叫做对头。

由于约定了只能在线性表固定的两端进行操作,于是给队列这种特殊的线性表的插入删除,起个特殊的名称:

  • 队头:可以删除节点的一端;
  • 队尾:可以插入节点的一端;
  • 入队:将节点插入到队尾之后,函数名通常为enQueue();
  • 出队:将队头节点从队列中剔除,函数名通常为outQueue();
  • 取队头:取得队头元素,但不出队,函数名通常为front()。

由于这种固定两端操作的简单约定,队列获得了“先进先出”的基本特性,如下图所示:

2、顺序存储的队列:循环队列(sequenceQueue)

与其他的逻辑结构类似,队列可以采用顺序存储形成循环队列,也可以采用链式存储形成链式队列。 顺序存储的队列之所以被称为循环队列,是因为可以利用更新队头队尾的下标信息,来循环地利用整个数组,出队入队时也不必移动当中的数据。循环队列示意图如下所示:

从上述动图中可以观察到,需要牺牲至少数组中的一个存储位置,来区分循环队列中的满队和空队。 满队和空队的约定如下:

  • 当front与rear相等时,队列为空;
  • 当rear循环加一与front相等时,队列为满;

与其他数据结构一样,管理循环队列除了需要一块连续的内存之外,还需要记录队列的总容量、当前 队列的元素个数、当前队头、队尾元素位置,如果有多线程还需要配互斥锁和信号量等信息,为了便于管理,通常将这些信息统一于在一个管理结构体之中:

typedef   int   DATA;
typedef  struct
{
   DATA      *pData; // 队列入口
   int         size;   // 队列总容量
   int         head;   // 队列队头元素下标
   int         tail;   // 队列队尾元素下标
}SQueue;

3、完整代码(顺序-循环队列

  • squeue.h

    #ifndef __SQUEUE_H
    #define __SQUEUE_H
    typedef   int   DATA;
    typedef  struct
    {
       DATA      *pData; // 队列入口
       int         size;   // 队列总容量
       int         head;   // 队列队头元素下标
       int         tail;   // 队列队尾元素下标
    }SQueue;
    // 初始化队列
    int SQ_init(SQueue *q, int num);
    // 判断队列是否已满
    int SQ_isfull(SQueue *q);
    // 判断队列是否为空
    int SQ_isempty(SQueue *q);
    // 入队
    int SQ_push(SQueue *q,DATA data);
    // 出队
    int SQ_pop(SQueue *q,DATA *data);
    // 回收队
    int SQ_free(SQueue *q);
    #endif
  • squeue.c

    #include <stdlib.h>
    #include "squeue.h"
    // 初始化队列
    int SQ_init(SQueue* q,int num)
    {
        q -> pData = (DATA*)calloc(sizeof(DATA),num);
        if(q -> pData == NULL)
           return -1;
        q -> size  = num ;
        q -> head  = q -> tail = 0;
        return 0;
    }
    // 判断队列是否已满
    int SQ_isfull(SQueue *q)
    {
        return (q -> tail + 1) % q -> size  == q -> head;
    }
    // 判断队列是否为空
    int SQ_isempty(SQueue *q)
    {
        return q -> tail  == q -> head;
    }
    // 出队
    int SQ_push(SQueue *st,DATA data)
    {
        if(SQ_isfull(st))
           return -1;
        st -> pData[st -> tail] = data;
        st -> tail = (st -> tail+1) % st -> size;
        return 0;
    }
    // 入队
    int SQ_pop(SQueue *st,DATA *data)
    {
        if(SQ_isempty(st))
           return -1;
        *data = st -> pData[st -> head];
        st -> head = (st -> head+1) % st -> size;
        return 0;
    }
    // 回收队列
    int SQ_free(SQueue *st)
    {
        if(st -> pData)
       {
             free(st->pData);
             st -> pData = NULL;
       }
        st -> head = st -> tail  = 0;  
    }
    

注意: 循环队列中,需要牺牲一个存储位置来区分空队和满队

【课堂练习3】

构建一个顺序存储的循环队列,当用户输入数字时,将数字入队,当用户输入字母时,将队头元素出队。每次操作队列之后,将队列中的元素显示出来。

4、链式存储的队列:链式队列(linkQueue)

链式队列的组织形式与链表无异,只不过插入删除被约束在固定的两端。为了便于操作,通常也会创建所谓管理结构体,用来存储队头指针、队尾指针、队列元素个数等信息:

从上图可以看到,链式队列主要控制队头和队尾,由于管理结构体中保存了当前队列元素个数size,因 此可以不必设计链表的头节点,初始化空队列时只需要让队头队尾指针同时指向空即可。

以下是队列链表节点设计和管理结构体设计的示例代码:

typedef  int  DATA;
// 链式队列节点
typedef struct _node
{
    DATA        data;
    struct _node  *next;
}NODE/*,*PNODE*/;

// 链式队列管理结构体
typedef struct
{
   NODE     *pHead; // 队头指针
   NODE     *pTail; // 队尾指针
   int       size ; // 队列当前元素个数
   int       num ;
}LinkQueue;

5、完整代码(链式队列(linkQueue)

当进入新数据时,创建新节点

  • linkQueue.h

    #ifndef __LINKQUEUE_H
    #define __LINKQUEUE_H
    typedef  int  DATA;
    // 链式队列节点
    typedef struct _node
    {
        DATA        data;
        struct _node  *next;
    }NODE/*,*PNODE*/;
    // 链式队列管理结构体
    typedef struct
    {
       NODE     *pHead; // 队头指针
       NODE     *pTail; // 队尾指针
       int       size ; // 队列当前元素个数
       int       num ;
    }LinkQueue;
    void LQ_init(LinkQueue *q,int sz);
    int  LQ_isfull(LinkQueue *q);
    int  LQ_isempty(LinkQueue *q);
    int  LQ_push(LinkQueue *q,DATA data);
    int  LQ_pop(LinkQueue *q,DATA *data);
    int LQ_free(LinkQueue *q);
    #endif
  • linkQueue.c

    #include "LinkQueue.h"
    #include <stdlib.h>
    void LQ_init(LinkQueue *q,int sz)
    {
        q -> pHead = q -> pTail = NULL;
        q -> size  = sz;
        q -> num   = 0;
    }
    int  LQ_isfull(LinkQueue *q)
    {
        return q -> num == q -> size;
    }
    int  LQ_isempty(LinkQueue *q)
    {
        return q -> num == 0;
    }
    int  LQ_push(LinkQueue *q,DATA data)
    {
        if(LQ_isfull(q))
           return -1;
        NODE* pNew = (NODE*)malloc(sizeof(NODE));
        if(!pNew)
            return -1;
        pNew -> data  = data;
        pNew -> next  = NULL;
        if(!(q -> pTail))
           q -> pHead = q -> pTail = pNew;
        else
       {       
           q -> pTail -> next  = pNew;
           q -> pTail = pNew;
       }
        q -> num ++;
        return 0;
    }
    int  LQ_pop(LinkQueue *q,DATA *data)
    {
        if(LQ_isempty(q))
           return -1;
         NODE* p = q -> pHead;
         *data  = p -> data;
         if(p == q -> pTail)
             q -> pHead = q -> pTail = NULL;
         else     
             q -> pHead = p -> next;
             
         free(p);
         q -> num --;
     
        return 0;
    }
    int LQ_free(LinkQueue *queue)
    {
        NODE* p = queue -> pHead, *q = NULL;
        while(p)
       {
            q  = p;
            p  = p -> next;
            free(q);
       }
        queue -> pHead = queue -> pTail = NULL;
        queue -> num   = 0;
        return 0;
    }
    
  • linkQueue_main.c

    #include "LinkQueue.h"
    #include <stdio.h>
    int main(void)
    {
        LinkQueue    queue;
        LQ_init(&queue,10);
        register  int i = 1;    
        for(; i <= 10 ; i++) 
           LQ_push(&queue, i);
        if( -1 == LQ_push(&queue,1024))
          fprintf(stderr,"满队,入队失败!\n");
        while(!LQ_isempty(&queue))
       {
            DATA   data;
            LQ_pop(&queue,&data);
            printf("%4d",data);
       }
        printf("\n");
        LQ_free(&queue);
        return 0; 
    }
    

【课堂练习4】

构建一个链式队列,当用户输入数字时,将数字入队,当用户输入字母时,将队头元素出队。每次操作队列之后,将队列中的元素显示出来。

章节作业

(栈的基本操作)

【1】编程实现功能:将键盘输入的十进制数,转换为十六进制输出。

(栈的基本操作)(选做)

【2】编程实现汉诺塔游戏。

(栈的基本操作)(选做)

【3】面试题

(队列的基本操作)(选做)

【4】蜗牛在制定今天的旅游计划,有 nn 个景点可选,它已经把这些景点按照顺路游览的顺序排成一排了,每个地方有相应的景观标号,这里用一个整数表示,相同的标号意味着相同的景观。 蜗牛希望选取连续的一段景点,还要选出来的每一个景点的景观都不同,问它最多能选出多少个景点进行旅游。

提示:

假设景点的景观标号是: 6 2 8 2 6

那么蜗牛可选的最长不重复的连续景点数是3,即前三个6 2 8,或后三个8 2 6

v图像 小部件

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

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

相关文章

使用Python进行数据可视化:让你的数据“活”起来

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 安装与导入 要使用Matplotlib&#xff0c;首先需要安装。可以使用pip进行安装&#xff1a; pip install matplotlib安装完成后&#xff0c;可以在Python代码中导入Matplotlib库&#xff1a; import matplotlib.py…

2024跨境旺季营销:哪个平台是流量之王?

跨境电商的旺季即将来临&#xff0c;对于卖家们来说&#xff0c;如何进行有效的营销推广至关重要。在多渠道广告覆盖的策略下&#xff0c;选择合适的平台成为关键。那么&#xff0c;哪些平台是跨境旺季营销的首选呢&#xff1f; 一、社交媒体平台 1、Instagram 以图片和短视频…

华为达芬奇人像引擎2.0,人像体验有哪些升级

对于年轻人而言&#xff0c;拍照已成为生活中不可或缺的一部分&#xff0c;不仅是为了记录世界、更重要的是成为生活的主角&#xff0c;大胆表达自己。然而很多喜欢使用手机记录生活的人&#xff0c;既希望能够实现媲美单反的影像实力&#xff0c;同时还想呈现出真实、更具自然…

内存管理篇-21 虚拟内存管理:线性映射区

1.线性映射区的定义 这部分讲线性映射区的内容。一般老的嵌入式平台&#xff0c;它内存很小只有几百兆&#xff0c;都会直接把整个物理内存映射到线性映射区了&#xff0c;只有当物理内存大于1GB以上&#xff0c;线性映射区无法cover的时候就把剩下的放到高端内存。所以这个区域…

CST软件如何仿真Total Scan方向图的

本期将介绍如何在CST软件中得到Total Scan方向图。 CASE1 首先以两个dipole天线为例&#xff0c;如下图所示&#xff1a; 我们完成这个两单元阵的仿真&#xff0c;可以在远场结果看到各个频点的结果如下图所示&#xff1a; 我们可以在combine按钮下任意合成不同幅度相位下的结…

SpringBoot中实现全局异常处理,统一返回错误信息给前端

背景引入&#xff1a;最近实现了一个限流切面类&#xff0c;但是在限流方法中throw异常&#xff0c;会直接打印到控制台&#xff0c;报错500&#xff0c;对前端很不友好。因为是注解&#xff0c;又没办法捕获再处理。那么怎么才能将错误码返回给前端呢&#xff1f;原来是全局异…

linux下的Socket网络编程教程

套接字概念 Socket本身有“插座”的意思&#xff0c;在Linux环境下&#xff0c;用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。与管道类似的&#xff0c;Linux系统将其封装成文件的目的是为了统一接口&#xff0c;使得读写套接字和读写文件的操作…

什么是边缘计算?边缘计算网关有什么作用?

边缘计算是一种分布式计算范式&#xff0c;它将计算、存储和网络服务靠近数据源或用户的位置&#xff0c;以减少延迟、提高响应速度&#xff0c;并减轻中心数据中心的负担。边缘计算网关在这一过程中扮演着至关重要的角色。边缘计算网关的主要作用包括&#xff1a;1. 数据的收集…

问题合集更更更之cssnano配置导致打包重新计算z-index

前言 &#x1f44f;问题合集更更更之cssnano配置导致打包重新计算z-index~ &#x1f947;记得点赞关注收藏&#xff01; 1.问题描述 代码中写了样式代码&#xff0c;z-index层级关系 z-index&#xff1a;2029;进行打包之后&#xff0c;发布到环境中&#xff0c;发现层级变…

《机器学习》PCA数据降维 推导、参数讲解、代码演示及分析

目录 一、主成分分析 1、什么是主成分分析&#xff1f; 2、什么是降维&#xff1f; 3、如何进行主成分分析 1&#xff09;数据标准化 2&#xff09;计算协方差矩阵 3&#xff09;计算特征值和特征向量 4&#xff09;选择主成分 5&#xff09;构建投影矩阵 6&#xff09;数据…

中学理化生实验室如何建设及配置

近年来&#xff0c;各地教育部门陆续出台“关于推进普通中小学校科学类实验室建设”的相关要求&#xff0c;针对小学、初中、高中学段的实验室等设施设备配备提出了标准指引&#xff0c;提升教育装备水平&#xff0c;助力打造品质教育。本文就中学理化生实验室建设要求及配置进…

【ant-design】Table如何设置Empty文案并保留图标

如果只设置了文案&#xff0c;那么为空的时候&#xff0c;并不会有图标 这时候我们可以设置emptyText: <Empty image{Empty.PRESENTED_IMAGE_SIMPLE} description{"没有数据"}/> 即可保留图标

产品经理入门基础

什么是产品&#xff1f; 什么是产品经理&#xff1f; 想清楚产品怎么做的人 1.什么是产品?区别是? 能够解决某个问题的东西就是产品有形的产品、无形的产品2.什么是产品经理? 想清楚产品怎么做的人就是产品经理3.合格的产品经理需要关注哪些核心问题? 用户、场景、需求功能…

k8s工作负载控制器--Statefulset

文章目录 一、概述二、引入"有状态"需求1、管理无状态服务的 Deployment 实现了什么1.1、创建 Deployment1.2、验证 Pod 数量1.3、配置更新策略&#xff08;更新镜像版本&#xff09;1.4、观察更新过程1.5、验证更新后 Pod 的状态1.6、回滚 Deployment 2、新需求分析…

iptable 理解

iptable 理解 这个当初我理解不了&#xff0c;主要是没把netfilter理解清楚。 Netfilter是集成在内核中的&#xff0c;用来定义存储各种规则的。Iptalbe是修改这些规则的工具&#xff0c;修改后存在netfilter里面。 数据包进入LINUX服务器时&#xff0c;先进入服务器的netfilt…

Leetcode 72. 编辑距离 动态规划 优化 C++实现

Leetcode 72.编辑距离 问题&#xff1a;给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a;插入一个字符&#xff0c;删除一个字符&#xff0c;替换一个字符。 算法1&#xff1a;递…

9-6springboot该如何学习

这阶段如何学习 javase&#xff1a;面向对象OOP mysql:持久化 htmlcssjsjquery框架&#xff1a;视图&#xff08;框架不熟练&#xff09;&#xff0c;css不好 javaweb&#xff1a;独立开发MVC三层架构的网站&#xff1a;原始 ssm&#xff1a;框架&#xff1a;简化了我们的…

【课程学习】信号检测与估计

文章目录 3.7-CRB延展到向量的形式3.8-参数变换形式的CRB CRB for transformation, pp45-463.9-高斯分布 CRLB for the General Gaussian Case3.7-CRB延展到向量的形式 0904 向量和变换形式的CRLB形式 估计参数真实值 θ \theta θ,估计值 θ ^ \hat \theta θ^ 与信号与系统…

AcWing算法基础课-786第k个数-Java题解

大家好&#xff0c;我是何未来&#xff0c;本篇文章给大家讲解《AcWing算法基础课》786 题——第 k 个数。本篇文章详细解析了如何使用 Java 实现快速排序算法&#xff0c;以解决查找数组中第 k 个元素的问题。通过深入浅出的讲解&#xff0c;展示了从输入读取到快速排序实现的…

Java程序打jar包(包含作者各种踩坑案例,力求为大家避雷)

一、诉求 将一个spring boot项目打包成一个jar包&#xff0c;直接在windows或者linux系统下直接命令行运行。 二、配置步骤 1、编写assembly.xml配置文件&#xff08;放在pom.xml同级目录&#xff09; <?xml version"1.0"?> <assembly><id>T…