棧和隊列--數據結構初階(2)(C/C++)

文章目錄

  • 前言
  • 理論部分
    • 棧的模擬實現
    • STL中的棧容器
    • 隊列的模擬實現
    • STL中的隊列容器
  • 作業部分

前言

這期的話會給大家講解棧和隊列的模擬實現和在STL中棧和隊列怎么用的一些知識和習題部分(這部分側重于理論知識,習題倒還是不難)

理論部分

棧的模擬實現


typedef int  STDataType;typedef struct Stack
{STDataType* a;//這里的a想表示的是數組int top;//表示數組a當前的容量int capacity;
}ST;void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){perror("malloc fail");return;}ps->capacity = 4;ps->top = 0;  
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity){STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity*2);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//拓展:bool里面如果return的是數字的話,會隱式轉換STDataType STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}
注意:這樣寫的話,此時的棧頂的下標是top-1
stPush那里一般用ps->top == ps->capacity
top那里是還沒存元素的
開空間完記得檢查是否開辟成功
盡量不要用while(st.top!=0去代替while(!STEmpty(&st))),數據結構最好封裝起來
注意STTop最后那里是ps->a[ps->top-1]
這個代碼有個問題:封裝時一般要typedef類型,這里搞了但是沒去用(讓以后要改類型時只用改一次)

STL中的棧容器

stack容器(棧)
頭文件:#include<stack>
創建:stack<T>st;//st是變量名,可以改;T是任意類型的數據
size empty 
push:進棧
pop:出棧
top:返回棧頂元素,但是不會刪除棧頂元素(先進后出)

隊列的模擬實現

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef char QDatatype;typedef struct QueueNode
{struct QueueNode* next;QDatatype data;
}QNode;typedef struct Queue
{QNode* head;QNode* tail;int size;
}Queue;void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDatatype x);
void QueuePop(Queue* pq);
int QueueSize(Queue* pq);
bool QueueEmpty(Queue* pq);
QDatatype QueueFront(Queue* pq);
QDatatype QueueBack(Queue* pq);void QueueInit(Queue* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}void QueueDestroy(Queue* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDatatype x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc fail");return;}newnode->data = x;newnode->next = NULL;if (pq->head == NULL){assert(pq->tail == NULL);pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = newnode;}pq->size++;
}void QueuePop(Queue* pq)
{assert(pq);assert(pq->head != NULL);if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}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;
}
結構體定義那里可以像這樣在結構體里面用自己的指針
結構體1里面套結構體2的話,定義結構體1后不用單獨手動再為結構體1中的結構體2開辟
跟定義int指針,想變成數組需要malloc區分
注意:assert檢查的是結果為0,就會報錯

STL中的隊列容器

queue(隊列):
頭文件:#include<queue>
創建:queue<T>q;//q是變量名,T是任意類型的數據
size empty push pop
front:返回隊頭元素,但不會刪除
back:返回隊尾元素,但不會刪除
不可以用clear來直接清除隊列pop刪除的是隊頭

作業部分

力扣 有效的括號

力扣 有效的括號
注意點:右括號數量不等于左括號這個特殊情況不要忘了
感悟:像這種如果匹配的話要繼續走,不匹配的話要干啥的if里面寫不匹配的條件會好些代碼實現:
typedef struct Stack
{char*a;int top;int capacity;}void  STInit(){a = (char*)malloc(sizeof(char)*4);capacity = 4;top = 0;}void STPush(char*ps,char x){assert(ps);if(ps->top == ps->capacity){a = (char*)malloc(sizeof(char)*ps->capacity*2);capacity*=2;}ps->a[ps->top] = x;ps->top++;}void STPop(char*ps,char x){assert(ps);ps->top--;}bool isValid(char* s) {struct Stack;&a = &s;}
if如果判斷條件多的話可以像下面這樣寫,這樣寫不用續行符
而且if后面只跟一個語句的話,一般跟if寫同一行上

在這里插入圖片描述

企業中的話,能初始化的盡量還是要初始化一下,競賽一般不用

力扣 用棧實現隊列

題目: 力扣 用棧實現隊列
相比用隊列實現棧可以優化的地方是:可以有個棧專門入棧,一個棧專門出棧,出棧的空了再把另一個棧倒過來代碼實現:
class MyQueue {
public:stack<int>q1;stack<int>q2;int count1 = 0;//用q1來存入棧,q2來搞出棧void push(int x) {q1.push(x);}int pop() {if(!q2.empty()){int m =   q2.top();q2.pop();return m;}else{while(q1.size()){int k = q1.top();q2.push(k); q1.pop();}int n = q2.top();q2.pop();return n;}}int peek() {if(!q2.empty()){return q2.top();}else {while(q1.size()){q2.push(q1.top()); q1.pop();}return q2.top();}}bool empty() {if(q1.empty()&&q2.empty())return true;else{return false;}}
};

力扣 設計循環隊列

題目:力扣 設計循環隊列
這里用鏈表模擬隊列不好(因為要找尾)所以用數組來模擬
想讓數組也能循環的話,就要時不時讓他對k取模(插入,刪除過程中也要)
由這個題引申出來的知識有:
1.malloc了幾次,后續也要free幾次,雖然說不free也可以通過,但是要是在面試中就是減分項,比如下面這種malloc的方式

在這里插入圖片描述
在這里插入圖片描述


代碼實現:typedef struct {int*a;int front;int rear;int k;} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue*obj  = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));obj->front = obj->rear = 0;obj->k = k;obj->a = (int*)malloc(sizeof(int)*(k+1));return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->front == obj->rear;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear+1)%(obj->k+1) == obj->front;//這里的作用是讓rear在數組末時可以返回到0那去以及防止是空
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj))    return false;obj->a[obj->rear] = value;obj->rear = ((++obj->rear))%(obj->k+1);return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj))  return false;obj->front = (++obj->front)%(obj->k+1);return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->a[(obj->rear-1+obj->k+1)%(obj->k+1)];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}
隊列和棧都屬于線性數據結構   循環隊列也是線性數據結構

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

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

相關文章

RNN的理解

對于RNN的理解 import torch import torch.nn as nn import torch.nn.functional as F# 手動實現一個簡單的RNN class RNN(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(RNN, self).__init__()# 定義權重矩陣和偏置項self.hidden_size hidden…

二叉查找樹和B樹

二叉查找樹&#xff08;Binary Search Tree, BST&#xff09;和 B 樹&#xff08;B-tree&#xff09;都是用于組織和管理數據的數據結構&#xff0c;但它們在結構、應用場景和性能方面有顯著區別。 二叉查找樹&#xff08;Binary Search Tree, BST&#xff09; 特點&#xff1…

一段式端到端自動駕駛:VAD:Vectorized Scene Representation for Efficient Autonomous Driving

論文地址&#xff1a;https://github.com/hustvl/VAD 代碼地址&#xff1a;https://arxiv.org/pdf/2303.12077 1. 摘要 自動駕駛需要對周圍環境進行全面理解&#xff0c;以實現可靠的軌跡規劃。以往的方法依賴于密集的柵格化場景表示&#xff08;如&#xff1a;占據圖、語義…

OpenCV訓練題

一、創建一個 PyQt 應用程序&#xff0c;該應用程序能夠&#xff1a; 使用 OpenCV 加載一張圖像。在 PyQt 的窗口中顯示這張圖像。提供四個按鈕&#xff08;QPushButton&#xff09;&#xff1a; 一個用于將圖像轉換為灰度圖一個用于將圖像恢復為原始彩色圖一個用于將圖像進行…

opencv函數展示4

一、形態學操作函數 1.基本形態學操作 &#xff08;1&#xff09;cv2.getStructuringElement() &#xff08;2&#xff09;cv2.erode() &#xff08;3&#xff09;cv2.dilate() 2.高級形態學操作 &#xff08;1&#xff09;cv2.morphologyEx() 二、直方圖處理函數 1.直方圖…

iPhone 13P 換超容電池,一年實記的“電池循環次數-容量“柱狀圖

繼上一篇 iPhone 13P 更換"移植電芯"和"超容電池"&#x1f50b;體驗&#xff0c;詳細記錄了如何更換這兩種電池&#xff0c;以及各自的優略勢對比。 一晃一年過去&#xff0c;時間真快&#xff0c;這次分享下記錄了使用超容電池的 “循環次數 - 容量(mAh)…

基于 pnpm + Monorepo + Turbo + 無界微前端 + Vite 的企業級前端工程實踐

基于 pnpm Monorepo Turbo 無界微前端 Vite 的企業級前端工程實踐 一、技術演進&#xff1a;為什么引入 Vite&#xff1f; 在微前端與 Monorepo 架構落地后&#xff0c;構建性能成為新的優化重點&#xff1a; Webpack 構建瓶頸&#xff1a;復雜配置導致開發啟動慢&#…

(五)機器學習---決策樹和隨機森林

在分類問題中還有一個常用算法&#xff1a;就是決策樹。本文將會對決策樹和隨機森林進行介紹。 目錄 一.決策樹的基本原理 &#xff08;1&#xff09;決策樹 &#xff08;2&#xff09;決策樹的構建過程 &#xff08;3&#xff09;決策樹特征選擇 &#xff08;4&#xff0…

Vue3使用AntvG6寫拓撲圖,可添加修改刪除節點和邊

npm安裝antv/g6 npm install antv/g6 --save 上代碼 <template><div id"tpt1" ref"container" style"width: 100%;height: 100%;"></div> </template><script setup>import { Renderer as SVGRenderer } from …

Arduino編譯和燒錄STM32——基于J-link SWD模式

一、安裝Stm32 Arduino支持 在arduino中添加stm32的開發板地址&#xff1a;https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json 安裝stm32開發板支持 二、安裝STM32CubeProgrammer 從stm32網站中安裝&#xff1a;https://ww…

智慧城市氣象中臺架構:多源天氣API網關聚合方案

在開發與天氣相關的應用時&#xff0c;獲取準確的天氣信息是一個關鍵需求。萬維易源提供的“天氣預報查詢”API為開發者提供了一個高效、便捷的工具&#xff0c;可以通過簡單的接口調用查詢全國范圍內的天氣信息。本文將詳細介紹如何使用該API&#xff0c;以及其核心功能和調用…

Vue 組件化開發

引言 在當今的 Web 開發領域&#xff0c;構建一個功能豐富且用戶體驗良好的博客是許多開發者的目標。Vue.js 作為一款輕量級且高效的 JavaScript 框架&#xff0c;其組件化開發的特性為我們提供了一種優雅的解決方案。通過將博客拆分成多個獨立的組件&#xff0c;我們可以提高代…

Deno 統一 Node 和 npm,既是 JS 運行時,又是包管理器

Deno 是一個現代的、一體化的、零配置的 JavaScript 運行時、工具鏈&#xff0c;專為 JavaScript 和 TypeScript 開發設計。目前已有數十萬開發者在使用 Deno&#xff0c;其代碼倉庫是 GitHub 上 star 數第二高的 Rust 項目。 Stars 數102620Forks 數5553 主要特點 內置安全性…

應用篇02-鏡頭標定(上)

本節主要介紹相機的標定方法&#xff0c;包括其內、外參數的求解&#xff0c;以及如何使用HALCON標定助手實現標定。 計算機視覺——相機標定(Camera Calibration)_攝像機標定-CSDN博客 1. 原理 本節介紹與相機標定相關的理論知識&#xff0c;不一定全&#xff0c;可以參考相…

PG CTE 遞歸 SQL 翻譯為 達夢版本

文章目錄 PG SQLDM SQL總結 PG SQL with recursive result as (select res_id,phy_res_code,res_name from tbl_res where parent_res_id (select res_id from tbl_res where phy_res_code org96000#20211203155858) and res_type_id 1 union all select t1.res_id, t1.p…

C# Where 泛型約束

在C#中&#xff0c;Where關鍵字主要有兩種用途 1、在泛型約束中限制類型參數 2、在LINQ查詢中篩選數據 本文主要介紹where關鍵字在在泛型約束中的使用 泛型定義中的 where 子句指定對用作泛型類型、方法、委托或本地函數中類型參數的參數類型的約束。通過使用 where 關鍵字和…

《MySQL:MySQL表的約束-主鍵/復合主鍵/唯一鍵/外鍵》

表的約束&#xff1a;表中一定要有各種約束&#xff0c;通過約束&#xff0c;讓未來插入數據庫表中的數據是符合預期的。約束本質是通過技術手段&#xff0c;倒逼程序員插入正確的數據。即&#xff0c;站在mysql的視角&#xff0c;凡是插入進來的數據&#xff0c;都是符合數據約…

Qt 創建QWidget的界面庫(DLL)

【1】新建一個qt庫項目 【2】在項目目錄圖標上右擊&#xff0c;選擇Add New... 【3】選擇模版&#xff1a;Qt->Qt設計師界面類&#xff0c;選擇Widget&#xff0c;填寫界面類的名稱、.h .cpp .ui名稱 【4】創建C調用接口&#xff08;默認是創建C調用接口&#xff09; #ifnd…

汽車免拆診斷案例 | 2011款雪鐵龍世嘉車刮水器偶爾自動工作

故障現象 一輛2011款雪鐵龍世嘉車&#xff0c;搭載1.6 L 發動機&#xff0c;累計行駛里程約為19.8萬km。車主反映&#xff0c;該車刮水器偶爾會自動工作&#xff0c;且前照燈偶爾會自動點亮。 故障診斷 接車后試車發現&#xff0c;除了上述故障現象以外&#xff0c;當用遙控器…

【Linux】NAT、代理服務、內網穿透

NAT、代理服務、內網穿透 一. NAT1. NAT 技術2. NAT IP 轉換過程3. NAPT 技術4. NAT 技術的缺陷 二. 代理服務器1. 正向代理2. 反向代理3. NAT 和代理服務器 內網穿透內網打洞 一. NAT NAT&#xff08;Network Address Translation&#xff0c;網絡地址轉換&#xff09;技術&a…