數據結構:棧和隊列的實現附上源代碼(C語言版)

目錄

前言

1.棧

1.1 棧的概念及結構

1.2 棧的底層數據結構選擇

1.2 數據結構設計代碼(棧的實現)

1.3 接口函數實現代碼

(1)初始化棧

(2)銷毀棧

(3)壓棧

(4)出棧

(5)獲取棧頂元素

(6)獲取棧中有效元素的個數

(7)檢測棧是否為空

1.4 測試函數

2. 隊列

2.1 隊列概念及結構

2.2 隊列的底層數據結構的選擇

2.2 數據結構設計代碼(隊列的實現)

2.3 接口函數

(1)初始化隊列

(2)銷毀隊列

(3)隊尾入隊列

(4)隊頭出隊列

(5)獲取隊列頭部元素

(6)獲取隊列尾部元素

(7)獲取隊列中有效元素個數

(8)檢測隊列是否為空

2.4 測試函數

3. 棧和隊列的源代碼

3.1 棧

(1)Stack.h

(2)Stack.c

(3)STtest.c

3.2 隊列

(1)Queue.h

(2)Queue.c

(3)Qtest.c

總結


前言

這篇文章是關于棧和隊列的C語言實現,干貨滿滿,大家可以邊看邊手寫代碼,最后附上棧和隊列的參考代碼。


1.棧

1.1 棧的概念及結構

棧:一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行數據插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。

壓棧:棧的插入操作叫做進棧/壓棧/入棧,入數據在棧頂
出棧:棧的刪除操作叫做出棧。出數據也在棧頂

這個數據結構可以理解為炸串。在最開始,插入丸子時,要插到這根簽的最底部,就是入棧。開始吃的時候,一般從最上面的丸子入手,就是出棧

1.2 棧的底層數據結構選擇

我們學過順序表和鏈表兩種數據結構,用那種會更好呢?

  • 相對而言數組的結構實現更優一些。因為數組在尾上插入數據的代價比較小。不用挪動數據,刪除操作也很簡單。
  • 而鏈表如果要入棧,就是鏈表的尾插,我們需要找到鏈表的尾結點,效率低。出棧也是一樣。

1.2 數據結構設計代碼(棧的實現)

在用C語言實現棧各種接口函數,需要創建三個文件,分別是STtest.c,Stack.c和Stack.h。

  • STtest.c文件用來測試接口函數是否能成功。
  • Stack.c文件里面放的是各種接口函數實現的代碼
  • Stack.h文件放置各種頭文件的聲明,棧數據結構的設計和接口函數的聲明。下面的代碼就是放在此文件中。
typedef int STDataType;
// 下面是定長的靜態棧的結構,實際中一般不實用,所以我們主要實現下面的支持動態增長的棧
typedef int STDataType;
#define N 10
typedef struct Stack
{STDataType _a[N];int _top; // 棧頂
}Stack;// 支持動態增長的棧
typedef struct Stack
{STDataType* a;int top;      //棧頂int capacity; //容量
}ST;//初始化棧
void StackInit(ST* ps);
//銷毀棧
void StackDestroy(ST* ps);
//壓棧
void StackPush(ST* ps, STDataType x);
//出棧
void StackPop(ST* ps);
//獲取棧頂元素
STDataType StackTop(ST* ps);
//獲取棧中有效元素個數
int StackSize(ST* ps);
//檢測棧是否為空,為空返回true
bool StackEmpty(ST* ps);

1.3 接口函數實現代碼

(1)初始化棧

初始化棧一開始要斷言,斷言來判斷ps指針是否為空,如果為空會直接終止程序并給出提示,方便之后的調試,之后的斷言不再贅述。指針指向空,內部整型數據賦值為0。但是top得注意,top其實也是個下標。看下面的注釋,top可以有兩種賦值方式,只是表示不同意思。

void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = 0;//表示指向棧頂的下一個元素//ps->top = -1 ///表示指向棧頂元素ps->capacity = 0;
}

(2)銷毀棧

因為我們是以數組為基礎,是動態開辟的連續空間,直接釋放掉ps中的數組指針,并要置為空。

void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;//易錯ps->top = ps->capacity = 0;
}

(3)壓棧

棧的壓棧操作跟順序表的尾插類似,先要檢查內部空間容量是否足夠,一開始給四個該數據結構的空間,之后的按兩倍來擴容。最后就是插入數據,棧頂減一。

void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}

(4)出棧

這次不僅要判斷ps是否不為空指針,還要判斷棧內是否有元素,這樣才可以刪除元素,讓棧頂減一即可。

void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}

(5)獲取棧頂元素

這里的判斷跟上個接口函數一樣,只有棧內有元素,才能取棧頂元素。

STDataType StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top - 1];
}

(6)獲取棧中有效元素的個數

此時的top表示的是棧頂的下一個元素的下標,剛好就是元素個數,直接返回棧頂top

int StackSize(ST* ps)
{assert(ps);return ps->top;
}

(7)檢測棧是否為空

很多人會寫個if語句判斷,其實可以直接像下面一樣寫,ps->top == 0變成一個判斷語句,如果為真返回一個部位0的數,如果為假返回0。

bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

1.4 測試函數

我們寫兩個測試函數,第一個測試函數,是出棧和入棧的操作,可以調試查看。第二個測試函數是棧的數據打印,需要使用StackTop獲取棧頂元素,然后將打印的數據出棧。

void TestStack1()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);StackPop(&st);StackPop(&st);StackPop(&st);StackPop(&st);StackPop(&st);StackDestroy(&st);
}void TestStack2()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);while (!StackEmpty(&st)){printf("%d ", StackTop(&st));StackPop(&st);}StackDestroy(&st);
}int main()
{TestStack1();TestStack2();return 0;
}

輸出結果:

2. 隊列

2.1 隊列概念及結構

隊列:只允許在一端進行插入數據操作,在另一端進行刪除數據操作的特殊線性表,隊列具有先進先出FIFO(First In First Out)

入隊列:進行插入操作的一端稱為隊尾

出隊列:進行刪除操作的一端稱為隊頭

?這個數據結構可以理解為在銀行取號,先取號的人,就是入隊列。然后先取到號的人,就先去窗口處理業務,這就是出隊列。

2.2 隊列的底層數據結構的選擇

跟棧一樣,隊列也可以用順序表和鏈表來實現,那哪一個更好呢?

  • 相較于數組,使用鏈表更優一些。隊列的入隊和出隊,分別是鏈表的尾插和頭刪,不過我們會創建兩個指針指向頭結點和尾結點,所以不會有時間的消耗。
  • 而數組在頭部插入和刪除數據,都要挪動數據,效率較低。

鏈表的數據結構存儲的是一個數據變量,和指向下一個結點的指針變量。我們入隊列和出隊列分別在隊尾和隊頭,所以我們在隊列的數據結構定義兩個鏈表的指針變量head和tail,表示隊頭和隊尾

2.2 數據結構設計代碼(隊列的實現)

跟棧的實現一樣,首先要創建三個文件Qtest.c,Queue.c和Queue.h。

  • Qtest.c文件用來測試接口函數是否能成功。
  • Queue.c文件里面放的是各種接口函數實現的代碼
  • Queue.h文件放置各種頭文件的聲明,棧數據結構的設計和接口函數的聲明。下面的代碼就是放在此文件中。
// 鏈式結構:表示隊列
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QueueNode;// 隊列的結構
typedef struct Queue
{QueueNode* head;QueueNode* tail;
}Queue;//初始化隊列
void QueueInit(Queue* pq); 
//銷毀隊列
void QueueDestroy(Queue* pq);
//隊尾入隊列
void QueuePush(Queue* pq, QDataType x);
//隊頭出隊列
void QueuePop(Queue* pq);
//獲取隊列頭部元素
QDataType QueueFront(Queue* pq);
//獲取隊列尾部元素
QDataType QueueBack(Queue* pq);
//獲取隊列中有效元素個數
int QueueSize(Queue* pq);
//檢測隊列是否為空,如果為空返回true
bool QueueEmpty(Queue* pq);

2.3 接口函數

(1)初始化隊列

隊列初始化,只需要將隊頭鏈表指針和隊尾鏈表指針置為空指針就好。

void QueueInit(Queue* pq)
{assert(pq);pq->head = NULL;pq->tail = NULL;
}

(2)銷毀隊列

因為是以鏈表為基礎,需要用while循環釋放掉每一個動態開辟的結點。

void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* cur = pq->head;while (cur != NULL){QueueNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;
}

(3)隊尾入隊列

隊尾入隊列就是鏈表的尾插,但是我們有tail指針,直接在tail后面插入就好。不過需要分是否為空隊列兩種情況,如果是空隊列,head和tail指針都指向新結點,如果不是空隊列,在tail之后插入。

void QueuePush(Queue* pq, QDataType x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("Queue malloc fail");return;}newnode->data = x;newnode->next = NULL;if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}
}

(4)隊頭出隊列

在操作之前,我們需要判斷隊列是否有元素。然后在釋放第一個結點,改變指針指向。

void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));QueueNode* next = pq->head->next;free(pq->head);pq->head = next;
}

(5)獲取隊列頭部元素

QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}

(6)獲取隊列尾部元素

QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}

(7)獲取隊列中有效元素個數

這需要一個計數變量。

int QueueSize(Queue* pq)
{assert(pq);int n = 0;QueueNode* cur = pq->head;while (cur){n++;cur = cur->next;}return n;
}

(8)檢測隊列是否為空

跟棧判空相同。

bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}

2.4 測試函數

寫兩個測試函數,第一是入隊列和出隊列的操作,可以一步一步調試看情況。第二個測試函數,是打印隊列里的數據,現獲取隊頭的數據,然后再出隊。

void TestQueue1()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePop(&q);QueuePop(&q);QueuePop(&q);QueuePop(&q);printf("%d\n", QueueBack(&q));QueueDestroy(&q);
}void TestQueue2()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){QDataType front = QueueFront(&q);printf("%d ", front);QueuePop(&q);}printf("\n");
}int main()
{TestQueue1();TestQueue2();return 0;
}

輸出的結果:

3. 棧和隊列的源代碼

3.1 棧

(1)Stack.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int STDataType;下面是定長的靜態棧的結構,實際中一般不實用,所以我們主要實現下面的支持動態增長的棧
//typedef int STDataType;
//#define N 10
//typedef struct Stack
//{
//	STDataType _a[N];
//	int _top; // 棧頂
//}Stack;// 支持動態增長的棧
typedef struct Stack
{STDataType* a;int top;      //棧頂int capacity; //容量
}ST;
//初始化棧
void StackInit(ST* ps);
//銷毀棧
void StackDestroy(ST* ps);
//壓棧
void StackPush(ST* ps, STDataType x);
//出棧
void StackPop(ST* ps);
//獲取棧頂元素
STDataType StackTop(ST* ps);
//獲取棧中有效元素個數
int StackSize(ST* ps);
//檢測棧是否為空,為空返回true
bool StackEmpty(ST* ps);

(2)Stack.c

#include "Stack.h"void StackInit(ST* ps)
{assert(ps);ps->a = NULL;ps->top = 0;//ps->top = -1ps->capacity = 0;
}void StackDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}void StackPop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));ps->top--;
}STDataType StackTop(ST* ps)
{assert(ps);assert(!StackEmpty(ps));return ps->a[ps->top - 1];
}int StackSize(ST* ps)
{assert(ps);return ps->top;
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

(3)STtest.c

#include "Stack.h"void TestStack1()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);StackPop(&st);StackPop(&st);StackPop(&st);StackPop(&st);StackPop(&st);StackDestroy(&st);
}void TestStack2()
{ST st;StackInit(&st);StackPush(&st, 1);StackPush(&st, 2);StackPush(&st, 3);StackPush(&st, 4);//printf("%d ", StackTop(&st));//StackPop(&st);//printf("%d ", StackTop(&st));//StackPop(&st);//StackPush(&st, 5);//StackPush(&st, 6);while (!StackEmpty(&st)){printf("%d ", StackTop(&st));StackPop(&st);}StackDestroy(&st);
}int main()
{TestStack1();//TestStack2();return 0;
}

3.2 隊列

(1)Queue.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>// 鏈式結構:表示隊列
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QueueNode;// 隊列的結構
typedef struct Queue
{QueueNode* head;QueueNode* tail;
}Queue;//初始化隊列
void QueueInit(Queue* pq); 
//銷毀隊列
void QueueDestroy(Queue* pq);
//隊尾入隊列
void QueuePush(Queue* pq, QDataType x);
//隊頭出隊列
void QueuePop(Queue* pq);
//獲取隊列頭部元素
QDataType QueueFront(Queue* pq);
//獲取隊列尾部元素
QDataType QueueBack(Queue* pq);
//獲取隊列中有效元素個數
int QueueSize(Queue* pq);
//檢測隊列是否為空,如果為空返回true
bool QueueEmpty(Queue* pq);

(2)Queue.c

#include "Queue.h"void QueueInit(Queue* pq)
{assert(pq);pq->head = NULL;pq->tail = NULL;
}void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* cur = pq->head;while (cur != NULL){QueueNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;
}void QueuePush(Queue* pq, QDataType x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("Queue malloc fail");return;}newnode->data = x;newnode->next = NULL;if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}
}void QueuePop(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));QueueNode* next = pq->head->next;free(pq->head);pq->head = next;
}QDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->head->data;
}QDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->tail->data;
}int QueueSize(Queue* pq)
{assert(pq);int n = 0;QueueNode* cur = pq->head;while (cur){n++;cur = cur->next;}return n;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}

(3)Qtest.c

void TestQueue1()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePop(&q);QueuePop(&q);QueuePop(&q);QueuePop(&q);printf("%d\n", QueueBack(&q));QueueDestroy(&q);
}void TestQueue2()
{Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);while (!QueueEmpty(&q)){QDataType front = QueueFront(&q);printf("%d ", front);QueuePop(&q);}printf("\n");
}int main()
{//TestQueue1();TestQueue2();return 0;
}


總結

棧和隊列的實現其實相較于鏈表的實現簡單一些,是因為其結構的特殊要求。之后會出一篇關于棧和隊列的OJ題目。多多重復,百煉成鋼!

創作不易,希望這篇文章能給你帶來啟發和幫助,如果喜歡這篇文章,請留下你的三連,你的支持的我最大的動力!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716801.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716801.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716801.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

金三銀四求職攻略:如何在面試中脫穎而出

隨著春天的腳步漸近&#xff0c;對于眾多程序員來說&#xff0c;一年中最繁忙、最重要的時期也隨之而來。金三銀四&#xff0c;即三月和四月&#xff0c;被廣大程序員視為求職的黃金時段。在這段時間里&#xff0c;各大公司紛紛開放招聘&#xff0c;求職者們則通過一場又一場的…

初階數據結構之---棧和隊列(C語言)

引言 在順序表和鏈表那篇博客中提到過&#xff0c;棧和隊列也屬于線性表 線性表&#xff1a; 線性表&#xff08;linear list&#xff09;是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結構。線性表在邏輯上是線性結構&#xff0c;也就是說是連…

xxl-job--02--可視化界面各功能詳細介紹

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 可視化界面1 新增執行器2.新增任務**執行器**&#xff1a;**任務描述**&#xff1a;**路由策略**&#xff1a;**Cron**&#xff1a;cron表達式**運行模式**JobHandl…

01.18 校招 實習 內推 面經

綠*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;內推/實習/校招匯總表格 1、校招 | 中國航天科工四院四部2024春季校園招聘 校招 | 中國航天科工四院四部2024春季校園招聘 2、阿里集團24屆秋招「空缺崗位」大盤點 校招 | 阿里集團24屆校招補錄大盤點&#xff0…

全量知識系統問題及SmartChat給出的答復 之15 幣圈生態鏈

Q40. 今天聊聊關于幣圈和幣圈生態方面&#xff0c;尤其是在建立和保護各種幣圈生態鏈的問題。 主要包括各種主體、 各種權益 和 各種幣及其幣圈的 分類&#xff0c;包括 概念、關系和 鏈接和斷鏈的判斷根據等等&#xff0c; 是否有一個比較清晰的體系結構呢&#xff1f; 因為現…

java Springboot vue 健身房系統,簡單練手項目

該項目主要分為管理員和會員模塊 管理員具有&#xff1a;會員管理&#xff0c;器材管理,員工管理&#xff0c;健身課程管理 會員模塊&#xff0c;可以在線報名健身課程&#xff0c;查看自己課程 采用VUE前端開發和springboot后端開發&#xff0c;極簡代碼編寫&#xff0c;沒…

融資項目——登錄接口的開發

1. 首先創建登錄與用戶信息VO類。 Data ApiModel(description "登陸對象") public class LoginVO {ApiModelProperty("手機號")private String mobile;ApiModelProperty("密碼")private String password;ApiModelProperty("用戶類型"…

藍橋每日一題 (差分)3月3號

//3279改變數組元素 自己做TLE&#xff1a;奈何想不出怎么用差分 #include<bits/stdc.h> using namespace std; //3279 改變數組元素&#xff08;超時&#xff09; const int N2e510; vector<int>a; int t,n; int main() {cin>>t;while(t--){cin>>n;…

ubuntu20.04安裝docker及運行

ubuntu20.04安裝docker及運行 ubuntu環境版本 Ubuntu Focal 20.04 (LTS) 查看系統版本 rootubuntu20043:~# cat /proc/version Linux version 5.15.0-78-generic (builddlcy02-amd64-008) (gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) …

Vue(黑馬學習筆記)

Vue概述 通過我們學習的htmlcssjs已經能夠開發美觀的頁面了&#xff0c;但是開發的效率還有待提高&#xff0c;那么如何提高呢&#xff1f;我們先來分析下頁面的組成。一個完整的html頁面包括了視圖和數據&#xff0c;數據是通過請求從后臺獲取的那么意味著我們需要將后臺獲取…

通過XML調用CAPL腳本進行測試(新手向)

目錄 0 引言 1 XML簡介 2 通過XML調用CAPL腳本 0 引言 紀念一下今天這個特殊日子&#xff0c;四年出現一次的29號。 在CANoe中做自動化測試常用的編程方法有CAPL和XML兩種&#xff0c;二者各有各的特色&#xff0c;對于CAPL來說新手肯定是更熟悉一些&#xff0c;因為說到在C…

使用Go Validator在Go應用中有效驗證數據

作為一名開發者&#xff0c;確保Go應用中處理的數據是有效和準確的非常重要。Go Validator是一個開源的數據驗證庫&#xff0c;為Go結構體提供強大且易于使用的數據驗證功能。本篇文章將介紹Go Validator庫的主要特點以及如何在Go應用中使用它來有效驗證數據。 什么是Go Valid…

Vue開發實例(五)修改項目入口頁面布局

修改項目入口 一、創建新入口二、分析代碼&#xff0c;修改入口三、搭建項目主頁面布局1、Container 布局容器介紹2、創建布局3、布局器鋪滿屏幕4、創建Header頁面5、加入Aside、Main和Footer模塊 一、創建新入口 創建新的入口&#xff0c;取消原來的HelloWorld入口 參考代碼…

劍指offer刷題記錄Day2 07.數組中重復的數字 ---> 11.旋轉數組的最小數字

名人說&#xff1a;莫道桑榆晚&#xff0c;為霞尚滿天。——劉禹錫&#xff08;劉夢得&#xff0c;詩豪&#xff09; 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 目錄 1、重建二叉樹①代碼實現&#xff08;帶注釋&am…

【重溫設計模式】職責鏈模式及其Java示例

職責鏈模式的介紹 在開發過程中&#xff0c;我們經常會遇到這樣的問題&#xff1a;一個請求需要經過多個對象的處理&#xff0c;但是我們并不知道具體由哪個對象來處理&#xff0c;或者說&#xff0c;我們希望由接收到請求的對象自己去決定如何處理或者是將請求傳遞給下一個對…

CSS 選擇器的常見用法

這里CSS選擇器主要分為以下這幾種&#xff1a;1. 標簽選擇器 2. class選擇器 3. id選擇器 4. 復合選擇器 5. 通配符選擇器 CSS 選擇器的主要功能就是選中??指定的標簽元素. 選中了元素, 才可以設置元素的屬性. 1.標簽選擇器 <style>p{color: red;} </style> &…

表單控件上的事件

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>光標聚焦和失焦事件</title><style type"text/css">.text{color: red;font-size: 12px;}</style> </head> <bod…

【深度學習筆記】計算機視覺——錨框

錨框 目標檢測算法通常會在輸入圖像中采樣大量的區域&#xff0c;然后判斷這些區域中是否包含我們感興趣的目標&#xff0c;并調整區域邊界從而更準確地預測目標的真實邊界框&#xff08;ground-truth bounding box&#xff09;。 不同的模型使用的區域采樣方法可能不同。 這里…

吳恩達deeplearning.ai:正則化對于偏方差的影響制定用于性能評估的基準

以下內容有任何不理解可以翻看我之前的博客哦&#xff1a;吳恩達deeplearning.ai專欄 這節我們看看正則化系數 文章目錄 以線性回歸為例交叉驗證誤差對于確定 λ \lambda λ的作用 指定用于性能評估的基準語音識別的例子 以線性回歸為例 讓我們舉一個例子&#xff1a; 模型&am…

Outlook郵箱IMAP密碼怎么填寫?賬戶設置?

Outlook郵箱IMAP密碼是什么&#xff1f;Outlook如何設置IMAP&#xff1f; 許多用戶會選擇通過IMAP協議將郵箱與各種郵件客戶端進行連接。而在設置過程中&#xff0c;填寫IMAP密碼是必不可少的一步。那么&#xff0c;Outlook郵箱的IMAP密碼應該如何填寫呢&#xff1f;接下來&am…