C++ 算法学习栈和队列

快速入门之C++栈、队列的使用,并初探深度优先搜索(DFS)和广度优先搜索(BFS)学习总结 写在前面 最近开始学习算法,备战算法比赛。以下是我对栈和队列,以及运用栈和队列初探深度优先搜索(DFS)和广度优先搜索(BFS) C++栈的基本使用 栈遵循FILO原则,也就是先进后出。也可以被理解成LIFO,也就是后进先出 C++中 stack 头文件有他的具体实现,这里只是讲讲怎么简单的去运用它 ,其中stack.top()只是显示栈顶并不弹出,要用stack.pop()来弹出 #includ... 阅读详情

栈的定义:栈是一种重要的线性结构,栈是线性表的一种具体形式。

官方定义:栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作。所谓的栈,其实也就是一个特殊的线性表(顺序表、链表),但是它在操作上有一些特殊的要求和限制:

栈的元素必须“后进先出”。

栈的操作只能在这个线性表的表尾进行。

注:对于栈来说,这个表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)。

栈的插入操作(Push),叫做进栈,也称为压栈,入栈。

栈的删除操作(Pop),叫做出栈,也称为弹栈。

栈的顺序存储结构:

栈的顺序存储结构和栈的链式存储结构。

最开始栈中不含有任何数据,叫做空栈,此时栈顶就是栈底。然后数据从栈顶进入,栈顶栈底分离,整个栈的当前容量变大。数据出栈时从栈顶弹出,栈顶下移,整个栈的当前容量变小。

看一下数据结构:

typedef struct
{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;

它包含了三个元素:base ,top ,stackSize。其中base是指向栈底的指针变量,top是指向栈顶的指针变量,stackSize指示栈的当前可使用的最大容量。

创建一个栈

#define STACK_INIT_SIZE 100
initStack(sqStack *s)
{
    s->base = (ElemType *)malloc( STACK_INIT_SIZE * sizeof(ElemType) );
    if( !s->base )
        exit(0);
    s->top = s->base;   // 最开始,栈顶就是栈底
    s->stackSize = STACK_INIT_SIZE;
}

入栈操作又叫压栈操作,就是向栈中存放数据。

入栈操作要在栈顶进行,每次向栈中压入一个数据,top指针就要+1,知道栈满为止。

#define SATCKINCREMENT 10

void Push(sqStack *s, ElemType e)
{
    // 如果栈满,追加空间
    if( s->top – s->base >= s->stackSize )
    {
        s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if( !s->base )
            exit(0);

        s->top = s->base + s->stackSize;              // 设置栈顶
        s->stackSize = s->stackSize + STACKINCREMENT; // 设置栈的最大容量
    }

    *(s->top) = e;
    s->top++;
}

出栈操作就是在栈顶取出数据,栈顶指针随之下移的操作。

每当从栈内弹出一个数据,栈的当前容量就-1。

void Pop(sqStack *s,ElemType *e)
{
    if( s->top == s->base)  // 栈已空空是也
        return;

    *e = *--(s->top);
}

栈的另一种定义:

typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int top;        // 用于标注栈顶的位置
    int stackSize;
}

不推荐用这种方法。

清空一个栈:

清空一个栈,就是将栈中的元素全部作废,但栈本身物理空间并不发生改变(不是销毁)。

因此我们只要将s->top的内容赋值为s->base即可,这样s->base等于s->top,也就表明这个栈是空的了。这个原理跟高级格式化只是但单纯地清空文件列表而没有覆盖硬盘的原理是一样的。

void ClearStack(sqStack *s){
    s->top = s->base;
}

销毁一个栈:

销毁一个栈与清空一个栈不同,销毁一个栈是要释放掉该栈所占据的物理内存空间,因此不要把销毁一个栈与清空一个栈这两种操作混淆。

void DestroyStack(sqStack *s){
    int i, len;
    len = s->stackSize;
    for( i=0; i < len; i++ ){
        free( s->base );
        s->base++;
    }
    s->base = s->top = NULL;
    s->stackSize = 0;
}

计算栈的当前容量:

计算栈的当前容量也就是计算栈中元素的个数,因此只要返回s.top-s.base即可。

注意,栈的最大容量是指该栈占据内存空间的大小,其值是s.stackSize,它与栈的当前容量不是一个概念哦。

int StackLen(sqStack s)
{
    return(s.top – s.base);  // 初学者需要重点讲解
}

代码库(二进制转换十进制)

#include <iostream>
#include <cmath>
using namespace std;

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10

typedef char ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;

void InitStack(sqStack *s)
{
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if( !s->base )
    {
        exit(0);
    }

    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

void Push(sqStack *s, ElemType e)
{
    if( s->top - s->base >= s->stackSize )
    {
        s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if( !s->base )
        {
            exit(0);
        }
    }

    *(s->top) = e;
    s->top++;
}

void Pop(sqStack *s, ElemType *e)
{
    if( s->top == s->base )
    {
        return;
    }
    *e = *--(s->top);
}

int StackLen(sqStack s)
{
    return static_cast<int>(s.top - s.base);
}

int main()
{
    ElemType c;
    sqStack s{};
    int len, i, sum = 0;

    InitStack(&s);

    cout << "请输入二进制数,输入#符号表示结束:\t";
    cin >> c;
    while( c != '#' )
    {
        Push(&s, c);
        cin >> c;
    }

    getchar();  // 把'\n'从缓冲区去掉

    len = StackLen(s);
    cout << "栈的当前容量是: " << len << endl;

    for( i=0; i < len; i++ )
    {
        Pop(&s, &c);
        sum = static_cast<int>(sum + (c - 48) * pow(2, i));
    }

    cout << "转化为十进制数是: " << sum << endl;

    return 0;
}

代码库(二进制转换十六进制)

#include <iostream>
#include <cmath>
using namespace std;

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10

typedef char ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;

// 函数功能:初始化栈
// 参数*s:栈的地址
void InitStack(sqStack *s)
{
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if( !s->base )
    {
        exit(0);
    }

    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

// 函数功能:入栈操作
// 参数*s:栈的地址
// 参数e:待压入栈的元素
void Push(sqStack *s, ElemType e)
{
    if( s->top - s->base >= s->stackSize )
    {
        s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if( !s->base )
        {
            exit(0);
        }

        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }

    *(s->top) = e;
    s->top++;
}

// 函数功能:弹栈操作
// 参数*s:栈的地址
// 参数e:存放从栈里弹出的数据
void Pop(sqStack *s, ElemType *e)
{
    if( s->top == s->base )
    {
        return;
    }
    *e = *--(s->top);
}

// 函数功能:计算栈s的当前长度
// 参数s:栈
int StackLen(sqStack s)
{
    return static_cast<int>(s.top - s.base);
}

int main()
{
    ElemType c;
    sqStack s1{};
    sqStack s2{};
    int len, i, j, sum = 0;

    InitStack(&s1); // 初始化栈s1,用来存放二进制输入

    cout << "请输入二进制数,输入#符号表示结束:\t";
    cin >> c;
    while( c != '#' )
    {
        if( c=='0' || c=='1' )  // 检查输入是否二进制
            Push(&s1, c);
        cin >> c;
    }
    getchar();      // 把'\n'从缓冲区去掉
    len = StackLen(s1);

    InitStack(&s2); // 初始化栈s2,用来存放转换的八进制

    for( i=0; i < len; i+=4 )
    {
        for( j=0; j < 4; j++ )
        {
            Pop( &s1, &c ); // 取出栈顶元素
            sum = static_cast<int>(sum + (c - 48) * pow(2, j));

            if( s1.base == s1.top )
            {
                break;
            }
        }

        switch( sum )
        {
            case 10: sum = 'A'; break;
            case 11: sum = 'B'; break;
            case 12: sum = 'C'; break;
            case 13: sum = 'D'; break;
            case 14: sum = 'E'; break;
            case 15: sum = 'F'; break;
            default: sum += 48;
        }

        Push(&s2, static_cast<ElemType>(sum));
        sum = 0;
    }

    cout << "\n转化为十六进制数是: ";
    while( s2.base != s2.top )
    {
        Pop( &s2, &c );
        cout << c;
    }
    cout << endl;

    return 0;
}

代码库(二进制转换八进制)

#include <iostream>
#include <cmath>
using namespace std;

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10

typedef char ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;

// 函数功能:初始化栈
// 参数*s:栈的地址
void InitStack(sqStack *s)
{
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if( !s->base )
    {
        exit(0);
    }

    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

// 函数功能:入栈操作
// 参数*s:栈的地址
// 参数e:待压入栈的元素
void Push(sqStack *s, ElemType e)
{
    if( s->top - s->base >= s->stackSize )
    {
        s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if( !s->base )
        {
            exit(0);
        }

        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }

    *(s->top) = e;
    s->top++;
}

// 函数功能:弹栈操作
// 参数*s:栈的地址
// 参数e:存放从栈里弹出的数据
void Pop(sqStack *s, ElemType *e)
{
    if( s->top == s->base )
    {
        return;
    }
    *e = *--(s->top);
}

// 函数功能:计算栈s的当前长度
// 参数s:栈
int StackLen(sqStack s)
{
    return static_cast<int>(s.top - s.base);
}

int main()
{
    ElemType c;
    sqStack s1{};
    sqStack s2{};
    int len, i, j, sum = 0;

    InitStack(&s1); // 初始化栈s1,用来存放二进制输入

    cout << "请输入二进制数,输入‘#’号表示结束:\t";
    cin >> c;
    while( c != '#' )
    {
        if( c=='0' || c=='1' )  // 检查输入是否二进制
            Push(&s1, c);
        cin >> c;
    }
    getchar();      // 把'\n'从缓冲区去掉
    len = StackLen(s1);

    InitStack(&s2); // 初始化栈s2,用来存放转换的八进制

    for( i=0; i < len; i+=3 )
    {
        for( j=0; j < 3; j++ )
        {
            Pop( &s1, &c ); // 取出栈顶元素
            sum = static_cast<int>(sum + (c - 48) * pow(2, j));

            if( s1.base == s1.top )
            {
                break;
            }
        }

        Push(&s2, static_cast<ElemType>(sum + 48));
        sum = 0;
    }

    cout << "\n转化为八进制数是: ";
    while( s2.base != s2.top )
    {
        Pop( &s2, &c );
        cout << c;
    }
    cout << endl;

    return 0;
}

栈的链式存储:

栈因为只是栈顶来做插入和删除操作,所以比较好的方法就是将栈顶放在单链表的头部,栈顶指针和单链表的头指针合二为一。

栈的链式存储结构定义:

teypedef struct StackNode
{
    ElemType data;  // 存放栈的数据
    struct StackNode *next;
} StackNode, *LinkStackPtr;

teypedef struct LinkStack
{
    LinkStackPrt top;   // top指针
    int count;      // 栈元素计数器
}

对于栈链的Push操作,假设元素值为e的新结点是s,top为栈顶指针,我们得到如下代码:

Status Push(LinkStack *s,ElemType e)
{
    LinkStackPtr p = (LinkStackPtr) malloc(sizeof(StackNode));
    p->data = e;
    p->next = s->top;
    s->top = p;
    s->count++;
    return OK;
}

bool Push(LinkStack *s,ElemType e)
{
    LinkStackPtr p = (LinkStackPtr) malloc(sizeof(StackNode));
    p->data = e;
    p->next = s->top;
    s->top = p;
    s->count++;
    return true;
}

链栈的出战Pop操作,假设变量p用来存储要删除的栈顶结点,将栈顶指针下移一位,最后释放p即可。

Status Pop(LinkStack *s,ElemType *e)
{
    LinkStackPtr p;
    if( StackEmpty(*s))  // 判断是否为空栈
        return ERROR;
    *e = s->top->data;
    p = s->top;
    s->top = s->top->next;
    free(p);
    s->count--;
    return OK;
}

bool Pop(LinkStack *s,ElemType *e)
{
    LinkStackPtr p;
    if( StackEmpty(*s))  // 判断是否为空栈
        return false;
    *e = s->top->data;
    p = s->top;
    s->top = s->top->next;
    free(p);
    s->count--;
    return true;
}

RPN,逆波兰计算器

#include <iostream>
using namespace std;

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10
#define MAXBUFFER       10

typedef double ElemType;
typedef struct {
    ElemType *base;
    ElemType *top;
    int stackSize;
} sqStack;

void InitStack(sqStack *s) {
    s->base = (ElemType *) malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if (!s->base)
        exit(0);

    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}

void Push(sqStack *s, ElemType e) {
// 栈满,追加空间
    if (s->top - s->base >= s->stackSize) {
        s->base = (ElemType *) realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if (!s->base)
            exit(0);

        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACKINCREMENT;
    }

    *(s->top) = e;      // 存放数据
    s->top++;
}

void Pop(sqStack *s, ElemType *e
) {
    if (s->top == s->base)
        return;

    *e = *--(s->top);   // 将栈顶元素弹出并修改栈顶指针
}

int StackLen(sqStack s) {
    return static_cast<int>(s.top - s.base);
}

int main() {
    sqStack s{};
    char c;
    double d, e;
    char str[MAXBUFFER];
    int i = 0;

    InitStack( &s );

    cout << "请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志: \t";
    cin >> c;

    while( c != '#' )
    {
        while( isdigit(c) || c=='.' )  // 用于过滤数字
        {
            str[i++] = c;
            str[i] = '\0';
            if( i >= 10 )
            {
                cout << "出错:输入的单个数据过大" << endl;
                return -1;
            }
            cin >> c;
            if( c == ' ' )
            {
                d = atof(str);
                Push(&s, d);
                i = 0;
                break;
            }
        }

        switch( c )
        {
            case '+':
                Pop(&s, &e);
                Pop(&s, &d);
                Push(&s, d+e);
                break;
            case '-':
                Pop(&s, &e);
                Pop(&s, &d);
                Push(&s, d-e);
                break;
            case '*':
                Pop(&s, &e);
                Pop(&s, &d);
                Push(&s, d*e);
                break;
            case '/':
                Pop(&s, &e);
                Pop(&s, &d);
                if( e != 0 )
                {
                    Push(&s, d/e);
                }
                else
                {
                    cout << "\n出错:除数为零" << endl;
                    return -1;
                }
                break;
            default:break;
        }

        cin >> c;
    }

    Pop(&s, &d);
    cout << "\n最终的计算结果为:" << d << endl;

    return 0;
}

讲完了栈,现在开始看看队列。

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表。

与栈相同的是,队列也是一种重要的线性结构,实现一个队列同样需要顺序表或链表作为基础。

队列的数据结构定义:

typedef struct QNode {
    ElemType data;      
    struct QNode *next;
} QNode, *QueuePrt;

typedef struct {
    QueuePrt front, rear; // 队头、尾指针
} LinkQueue;

创建一个队列要完成两个任务:一是在内存中创建一个头结点,二是将队列的头指针和尾指针都指向这个生成的头结点,因为此时是空队列。

void initQueue(LinkQueue*q)
{
    q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
    if( !q->front )
        exit(0);
    q->front->next = NULL;
}

入队列:

InsertQueue(LinkQueue *q, ElemType e)
{
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if( p == NULL )
        exit(0);
    p->data = e;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
}

出队列:

DeleteQueue(LinkQueue *q, ELemType *e)
{
    QueuePtr p;
    if( q->front == q->rear )
        return;
    p = q->front->next;
    *e = p->data;
    q->front->next = p->next;
    if( q->rear == p )
    q->rear = q->front;
    free(p);
}

销毁一个队列:

由于链队列建立在内存的动态区,因此当一个队列不再有用时应当把它及时销毁掉,以免过多地占用内存空间。

DestroyQueue(LinkQueue*q)
{
    while( q->front ) 
    {
        q->rear =q->front->next;
        free( q->front );
        q->front = q->rear;
    }
}

下面看一下循环队列:

定义一个循环队列

#define MAXSIZE 100
typedef struct
{
    ElemType *base; // 用于存放内存分配基地址
                    //这里你也可以用数组存放
    int front;
    int rear;
};

初始化一个循环队列

void initQueue(cycleQueue *q)
{
    q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
    if( !q->base )
        exit(0);
    q->front = q->rear = 0;
}

入队列操作

bool InsertQueue(cycleQueue *q,ElemType e)
{
    if( (q->rear+1)%MAXSIZE ==q->front )
        return false; // 队列已满
    q->base[q->rear] = e;
    q->rear = (q->rear+1) %MAXSIZE;
}

出队列操作

bool DeleteQueue(cycleQueue*q, ElemType *e)
{
    if(q->front == q->rear )
        return false; // 队列为空
    *e= q->base[q->front];
    q->front= (q->front+1) % MAXSIZE;
}

C++循环队列模板

#include <iostream>
using namespace std;
class Queue{
private:
    int *data;              //定义指向整型的指针,从而动态开辟内存
    int head,tail,length,count;   //head指向队首,tail指向队尾,length表示队列的长度,count用于记录队列中元素个数,从而判断队列是否已满
public:
    explicit Queue (int length_input){       //构造函数,对新声明的队列对象进行初始化
        data = new int [length_input];      //动态开辟100个整型数据的空间
        length = length_input;              //为队列的长度赋初始值
        head = 0;                       //起初head为0,表示head值未改变的情况下,一直指向首元素
        tail = -1;                      //tail初始值为-1,表示此时队列为空,无任何数据元素
        count = 0;
    }
    ~Queue(){
        delete [] data;             //析构函数,删除动态开辟的内存
    }
    void push(int element){            //入队操作,只能从队列的尾部插入数据元素
        if(count < length){             //队列未满的时候才能插入,否则则插入失败
            tail = (tail + 1) % length;     //分两种情况,如果队尾指针此时并未指向队列的最后一位,那么队尾指针直接前移,而当队尾指针此时指向最后一位时
            data[tail] = element;           //那么当队列未满时,则队尾指针将跳转至数组起始位置,再将数据元素插入队尾指针指向的位置
            ++count;                    //入队成功,队列中元素数量加一
        }
    }
    bool pop(){
        if(count < 0){     //队列为空,出队失败
            return false;
        }
        head = (head + 1) % length;         //同样,根据循环队列的性质得出
        --count;            //出队成功,队列中元素数量减一
        return true;
    }
    int top(){
        if(count > 0){      //队列不为空的情况下才能获取队首元素
            return data[head];
        }else{
            return false;
        }
    }
    void output(){
        for(int i = head;i != tail + 1;i = (i + 1)%length){     //从队首一直遍历到队尾,当遍历到最后一位时,跳转至数组起始位置
            //特别注意此时循环截止的条件应该是i != tail + 1,因此可能tail的值小于head
            cout << data[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    Queue queue(100);               //声明一个队列对象,并初始化
    for(int i = 1;i <= 10;++i){
        queue.push(i);             //将1-10这10个数据元素依次插入队列中
    }
    queue.output();             //调用输出的方法
    cout << "当前的队首元素为:" << queue.top() << endl;
    queue.pop();               //出队
    queue.output();             //调用输出的方法
    cout << "出队操作后的队首元素为:" << queue.top() << endl;
    queue.pop();               //出队
    queue.output();             //调用输出的方法
    cout << "出队操作后的队首元素为:" << queue.top() << endl;
    return 0;
}

非模板循环队列

#include <iostream>
using namespace std;

#define MAXSIZE 100

typedef double ElemType;
typedef struct
{
    ElemType *base; // 用于存放内存分配基地址
    //这里你也可以用数组存放
    int front;
    int rear;
    int count;
}cycleQueue;

void initQueue(cycleQueue *q)
{
    q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
    if( !q->base )
        exit(0);
    q->front = q->rear = 0;
}

bool InsertQueue(cycleQueue *q,ElemType e)
{
    if( (q->rear+1)%MAXSIZE ==q->front )
        return false; // 队列已满
    q->base[q->rear] = e;
    q->rear = (q->rear+1) %MAXSIZE;
    q->count++;
}

bool DeleteQueue(cycleQueue *q, ElemType *e)
{
    if(q->front == q->rear )
        return false; // 队列为空
    *e= q->base[q->front];
    q->front= (q->front+1) % MAXSIZE;
}

int main(){
    cycleQueue queue{};
    double d;

    initQueue(&queue);
    InsertQueue(&queue, 1);
    InsertQueue(&queue, 2);
    InsertQueue(&queue, 3);
    InsertQueue(&queue, 4);
    InsertQueue(&queue, 5);
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    InsertQueue(&queue, 6);
    InsertQueue(&queue, 7);
    InsertQueue(&queue, 8);
    InsertQueue(&queue, 9);
    InsertQueue(&queue, 0);
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    DeleteQueue(&queue, &d);
    cout << d << endl;
    return 0;
}
【windows】【系统还原】亦是美kms执行一键关闭defender 之后,windows defender 被卸载了,无论如何都打不开 还是执行 都没有明显效果 那么,我最后是怎么解决得呢? 一、打开控制面板(任务栏搜索kzmb) 阅读详情

相关推荐

AD9826的时序分析及Verliog代码

AD9826的时序分析及Verliog代码 (本文对AD9826的模式和时序进行了分析,如有错误敬请指正,关于这款ADC芯片的基本参数,本文不做过多介绍) 1、AD9826的模式 AD9826的采样模式主要有两种,一种是“CDS模式”,一种是“SHA模式”;在这两种模式下分别有1通道、2通道、3通道的采样模式 (1)CDS模式 简单的来说CDS模式就是,有两个采样时钟,一个是ADCCLK1,用来采样CCD波形的参考电平,一个是ADCCLK2用来采样数据电平,然后经过,偏移量调节,再经过PGA增益放大最

m0_50102488的博客 6482

c语言push_C语言栈的图文解析和实现

栈的介绍栈(stack),是一种线性存储结构,它有以下几个特点:栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的。向栈中添加/删除数据时,只能从栈顶进行操作。栈通常包括的三种操作:push、peek、pop。push——向栈中添加元素。peek——返回栈顶元素。pop——返回并删除栈顶元素的操作。1. 栈的示意图栈中的数据依次是30→20→10。2...

weixin_39571403的博客 1365

ArcGIS:根据DEM数据提取区域水系

利用DEM数据提取区域水系是常见的水文分析应用,为了获取区域的矢量水系数据,我们可以通过ArcGIS对高程DEM数据进行水文分析,为地表水流建立模型,进而获取到该地的水系数据,DEM数据精度越高,获取到的水系数据精度也就越高。以下介绍如何用ArcGIS提供的工具提取水系。

Oruizn的博客 9110

实现栈 Stack

栈是Vector的一个子类,它实现了一个标准的后进先出的栈 栈是一种数据结构 实现Java语言中的栈(Stack),采用数组来实现 import java.util.Arrays; //顺序栈 使用数组 //(还可以用链式栈 链表实现 头插尾插都可以,头插复杂度低) public class MyStack<T> { public T[] elem;//数组 public int top;//表示当前可以存放数据元素的下标 public MyStack() {

jiangkun0331的博客 887

Windows 10下用vcpkg一键搞定libcurl开发环境(Code::Blocks 20.03配置指南)

本文详细介绍了在Windows 10系统下使用vcpkg工具快速配置libcurl开发环境的完整指南,特别针对Code::Blocks 20.03 IDE进行优化设置。通过vcpkg自动化管理依赖项,简化libcurl的安装与配置过程,帮助开发者高效搭建网络通信功能开发环境,并提供了常见问题解决方案和实际项目中的最佳实践。

weixin_28040125的博客 251

DRAM内存模拟持久化设备的方法

由于持久化内存介质NVM技术的发展,越来越多的科研工作者投身到NVM相关的研究当中。但由于目前工业界并没有推出广泛使用的NVM介质设备,所以科研工作都需要自己以现有的条件,模拟NVM设备使用场景。一个简单的方法是:通过修改DRAM模拟器,达到模拟NVM的目的(可以参考:DRAMSim2模拟器分析与应用)。更高端的方式是:在真实系统中,将内存划分出一块儿,用来模拟NVM设备(类似于传统的ramdis

酷炫人笨笨熊 1899

C++入门介绍之“栈”

栈(stack)是一种只能在一端进行插入或删除的线性表下面是一些基础概念栈顶(top) : 表中允许进行插入、删除操作的线性表栈底(bottom):表的另一端空栈 :栈中没有数据元素进栈/入栈(push):栈的插入操作出栈/退栈(pop):栈的删除操作。

m0_73421035的博客 4993

ISO 21434汽车网络安全标准深度解读系列(十):标准实施总结与展望

ISO21434标准深度解读系列总结篇系统回顾了汽车网络安全标准的核心内容与实施要点。文章梳理了10篇系列文章的结构体系,提炼出标准的三大核心价值:系统性方法(全生命周期覆盖、多层次管理)、风险导向理念(威胁驱动、动态管理)和供应链协同机制。总结了实施经验中的关键要素,包括高层承诺、专业团队建设,并提出了分阶段实施路径建议。同时分析了当前面临的技术挑战(系统复杂性、新兴技术)和管理挑战(文化转变、资源投入)。最后展望了AI应用、零信任架构等技术发展趋势,以及标准未来的演进方向,为企业实施提供战略与执行层面的

VehSwHwDeveloper的博客 559

c++数据结构之栈

一、栈的定义 栈(Stack)是由有限个数据类型相同元素组成的有序集合,对元素的操作只能在栈顶进行,遵循后进先出(Last In,First Out)的原则,其相关运算有创建空栈、判空、判满、入栈、出栈等。 二、栈的ADT 数据: 有限个数据类型相同元素所组成的有序集合,用top纪录栈顶元素的位置。 运算: Create(): 创建一个空栈。 IsEmpty(): 若栈空,则返回1,否则返回0。 IsFull(): 若栈满,则返回1,否则返回0。 Push(): 让某元素入栈。 Pop(): 让栈顶元素出栈

weixin_44974029的博客 1万+

多图详解VSCode搭建Python开发环境

本文通过多图的方式详细介绍了VSCode搭建Python开发环境,希望能对学习Python的同学们有所帮助。 文章目录 1. VSCode的介绍和安装 2. 安装插件 2.1 安装中文插件 2.2 安装Python插件 2.3 安装远程插件 3. 远程连接服务器 3.1 配置ssh 3.2 运行代码 3.3 调试代码

weixin_43178406的博客 8万+

1.2、基于卷积神经网络(CNN)的车牌自动识别系统(matlab)

基于卷积神经网络(CNN)的车牌自动识别系统(matlab)

XU157303764的博客 2911

【C++】栈(stack)的使用

C++ 中,`std::stack` 容器是一种*先进后出*(First In Last Out, FILO)的数据结构,且只有一个出口。详细介绍了C++中stack的使用方法,并分析了push与emplace的异同点。

AAADiao的博客 4567

AI Agent在核电站安全监控中的应用

核电站作为一种高效的能源生产设施,其安全问题一直是全球关注的焦点。任何安全事故都可能导致严重的人员伤亡、环境污染和经济损失。传统的核电站安全监控系统主要依赖于人工操作和固定规则的监控算法,存在监控效率低、无法实时应对复杂情况等问题。本文章的目的在于探讨如何利用AI Agent技术提升核电站安全监控的智能化水平,实现实时、准确的监测和智能决策。范围涵盖了AI Agent的基本原理、在核电站安全监控中的应用场景、相关算法和数学模型,以及实际项目的开发和应用。

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 372

数据结构和算法学习之路——栈和队列详解(C++版)

数据结构和算法学习之路——栈和队列详解(C++) 文章目录数据结构和算法学习之路——栈和队列详解(C++)(一) 栈1.1 栈的工作原理 (一) 栈 1.1 栈的工作原理 栈是一种后进先出的线性表,什么是后进先出呢?我们可以举一个例子形象的理解,比如我们有一个桶,一次只能放进一个物体,那么很显然,我们第一次放进去的东西被压在了桶底,如果这个桶每层都有东西的话,我们是无法第一次就把最底下(也就是最早...

凝望,划过星空的博客 1081

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++学习:第四章数据结构和算法 - (三)链表、栈、队列

链表 代码整理 List.h #include <iostream> using namespace std; #ifndef LIST_H #define LIST_H 1 //这个 1 可有可无 class List{ typedef int T; struct Node{ int data; Node* next; Node(const T& d...

Thomas会写字 270

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

代码随想录笔记|C++数据结构与算法学习笔记-栈和队列(〇)|stack、queue、单调队列和优先级队列(priority_queue)、大顶堆和小顶堆

队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为。栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为。队列容器允许从一端新增元素,从另一端移除元素。栈中进入数据称为 —栈中弹出数据称为 —队列中进数据称为 —队列中出数据称为 —

糖炒栗子 816

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

代码随想录笔记|C++数据结构与算法学习笔记-栈和队列(一)|232.用栈实现队列、225. 用队列实现栈、20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

其实我们只需要把元素1取出来加入队列的队尾,把元素2取出来加入队列的队尾,这样元素3就到队列的出口了,我们就可以先弹出元素3。我们现在遍历到第二个b,然后栈顶元素也是b,那么就消除,一下个遍历a,但是由于栈顶的b被消除了,此时的栈顶是a,然后我们再次完成消除,最后遍历c、a。用来存我们遍历过的元素,我们每遍历一个元素,都去栈里面询问一下,我之前有没有遍历a,我的前一个字母是a吗。我们从第一个符号开始遍历,每遍历一次,我们把它的右括号入栈,然后等到匹配的时候,对应出栈即可。把栈A的数据出栈,压入到栈B中。

糖炒栗子 681

C++刷题(二):栈 + 队列

20. 有效的括号 225. 用队列实现栈 232. 用栈实现队列 622. 设计循环队列 面试题03.05. 栈排序

tan_run的博客 956

剑指offer 08. 用两个栈实现队列

📣专栏定位:为找工作的小伙伴整理常考算法题解,祝大家都能成功上岸!

Newin2020的博客 410

【GESP】C++六级考试大纲知识点梳理, (7) 栈与队列

本文梳理了GESP C++六级考试中栈和队列的基础知识点。作为线性数据结构的核心内容,栈和队列是算法实现的"规则容器",规定了数据的进出顺序,是理解DFS、BFS等算法的基础。文章属于作者个人知识总结而非教程,旨在帮助考生掌握栈、队列和循环队列的基本定义、应用场景和常见操作。本文是该系列第七篇,前六篇已涵盖树结构、搜索算法、动态规划等考点内容。

CoderCoding的博客 652

C++ STL 栈与队列完全指南:从容器使用到算法实现

例如现在插入和1一样大小的值,右边不插入的话,此时若pop(左边删除的值若和右边的值相等,则右边也要删除,要更新下一个最小值,但是下一个左边删除6,右边的值是不删除的),右边的1被删除后,更新的下一个最小值变为2了,但实际上最小值为1。这里的解决方法是用两个栈,第一个栈st是正常的栈,第二个栈minst用来记录最小数据,左边的栈进一个4,右边栈也进一个4,只要插入的数据比前一个数据小,minst这个栈就进数据,或者minst为空,也进数据,以此类推。然后弹出4,再压5,之后弹出5,再弹出3,2,1。

m0_74824496的博客 643

c++算法知识点简括

本文主要分为以下几个部分:基本算法、数组和字符串、链表、栈和队列、树和图、排序算法、搜索算法、动态规划、贪心算法、回溯算法、图算法。- 数组和字符串的常见问题:包括数组的旋转、矩阵的转置、字符串的反转和替换等问题。- 链表的常见问题:包括链表的反转、链表的合并、链表的环检测和链表的排序等问题。- 数组的基本操作:包括数组的创建、访问、遍历、插入和删除等操作。- 队列的基本操作:包括队列的创建、入队、出队和队列的大小等操作。- 栈的基本操作:包括栈的创建、入栈、出栈和栈的大小等操作。

weixin_72389218的博客 671

算法常用C++总结

栈(stack) stack实现了一种先进后出的数据结构,使用时需要包含stack头文件 C++定义stack语法: stack<int> s; //int为栈的数据类型,也可以为string,double等 C++中stack的基本操作有: 1、出栈:如 s.pop() 注意并不返回出栈的元素 2、进栈:如 s.push(x) 3、访问栈顶元素:如s.top(); 4、判断栈空:如 s.empty() 栈为空时返回true 5、返回栈中元素个数,如:s.size() 例...

为幸福写歌的博客 630

DS博客作业03--栈和队列

1.本周学习总结 1.栈和队列是两种比较特殊的线性结构,栈具有先进后出的特点,操作时只对栈顶进行操作,队列具有先进先出的特点,操作时从队尾入队,从队头出队,而针对栈和队列的各种操作的时间复杂度均为O(1),利用这一点以及栈和队列的特点可以更加方便的解决问题。 2.随着对c++的深入学习,我也开始逐渐学会了容器的使用,每个容器都带有大量的预编译函数,利用这些函数可以有效的减少代码量,提高编程效率。 ...

weixin_30457551的博客 133

C++算法基础之头文件

#include<cstdio> 在C++中拥有在C语言里一样的语法,像输入输出。 #include<cstring> 包含很多字符串函数,如复制、比较是否相等、字符串连接。 #include<iostream> 输入输出流,包括输出格式的控制 #include<cstdlib> 在C++中拥有在C语言里一样的语法,像开...

weixin_44713462的博客 5863

C++系列: 常见数据结构与C++实现(9)

1. 线性表 顺序表 #include <iostream> #include <vector> using namespace std; void print_vector(vector<auto> vec){ for (auto i:vec){ cout << i << " "; } cout << endl...

rosefun96的博客 908
上一篇: Rabin-Karp算法
下一篇: C++ 数据结构与算法
程序猿胖哥
博客等级 码龄11年 28粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值