Leetcode刷題之用隊列實現棧(C語言版)

Leetcode刷題之用隊列實現棧(C語言版)

  • 一、題目描述
  • 二、題目要求
  • 三、題目示例
  • 四、題目解析
    • Ⅰ、MyStack* myStackCreate
    • Ⅱ、void myStackPush(MyStack* obj, int x)
    • Ⅲ、int myStackPop(MyStack* obj)
    • Ⅳ、int myStackTop(MyStack* obj)
    • Ⅴ、bool myStackEmpty(MyStack* obj)
    • Ⅵ、void myStackFree(MyStack* obj)
  • 五、完整代碼

225、用隊列實現棧

一、題目描述

請你僅使用兩個隊列實現一個后入先出(LIFO)的棧,并支持普通棧的全部四種操作(push、top、pop 和 empty)。實現 MyStack 類:①、void push(int x) 將元素 x 壓入棧頂。
②、nt pop() 移除并返回棧頂元素。
③、int top() 返回棧頂元素。
④、boolean empty() 如果棧是空的,返回 true ;否則,返回 false 。

二、題目要求

Ⅰ、你只能使用隊列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 這些操作。
Ⅱ、你所使用的語言也許不支持隊列。 你可以使用 list (列表)或者 deque(雙端隊列)來模擬一個隊列 , 只要是標準的隊列操作即可。

三、題目示例

在這里插入圖片描述

四、題目解析

首先我們看到本題是用隊列實現棧。那么我們便要對棧和隊列的相關特性有一定的了解,例如棧是先進后出的,而隊列是先進先出的。如果有伙伴對這兩種數據結構有些遺忘的話,建議看一下博主之前的兩篇文章,分別是《數據結構——棧的詳細介紹》和《數據結構——看完這篇保證你學會隊列》。
我們想要解決這道題,首先便要實現一個完整的隊列,其中的接口包括初始化隊列,銷毀隊列,入隊,出隊等,其代碼如下:
在這里插入圖片描述

//定義數據類型
typedef int QueueDataType;
//定義隊列結構
typedef struct QueueNode
{struct QueueNode* next;QueueDataType Data;
}Qnode;//定義頭、尾指針
typedef struct Queue
{Qnode* phead;Qnode* ptail;int size;
}Queue;//初始化
void InitQueue(Queue* pq);
//銷毀
void DestoryQueue(Queue* pq);
//入隊
void PushQueue(Queue* pq, QueueDataType x);
//出隊
void PopQueue(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//獲取SIze
int SizeQueue(Queue* pq);
//獲取隊頭元素
QueueDataType QueueFront(Queue* pq);
//獲取隊尾元素
QueueDataType QueueBack(Queue* pq);void InitQueue(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//銷毀
void DestoryQueue(Queue* pq)
{assert(pq);Qnode* cur = pq->phead;while (cur){Qnode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
//入隊
void PushQueue(Queue* pq, QueueDataType x)
{assert(pq);Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));if (newnode == NULL){perror("malloc fail");return;}//賦值newnode->Data = x;newnode->next = NULL;//分情況討論if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//出隊
void PopQueue(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//一個節點if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}//多個節點else{//頭刪Qnode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;}
//判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//獲取SIze
int SizeQueue(Queue* pq)
{assert(pq);return pq->size;
}
//獲取隊頭元素
QueueDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->Data;
}
//獲取隊尾元素
QueueDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->Data;
}

構建好隊列的各種接口之后,我們需要在Mystack的結構體中創建兩個隊列變量。代碼如下:

typedef struct 
{Queue q1;Queue q2;
} MyStack;

Ⅰ、MyStack* myStackCreate

該接口,需要我們在內存中開辟空間,利用malloc函數,并且將q1和q2進行初始化。

MyStack* myStackCreate() 
{MyStack*obj=(MyStack*)malloc(sizeof(MyStack));if(obj==NULL){perror("malloc fail");return NULL;}InitQueue(&obj->q1);InitQueue(&obj->q2);return obj;}

Ⅱ、void myStackPush(MyStack* obj, int x)

如果兩個隊列都為空,那么任選一個進行入隊操作即可,后續入隊往有數據的隊列進行入隊操作即可。

void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&obj->q1)){PushQueue(&obj->q1,x);}else{PushQueue(&obj->q2,x);}
}

Ⅲ、int myStackPop(MyStack* obj)

最為復雜的便是出棧了,我們的大體思路便是假定q1為空,q2不為空:如果結果相反,則調換一下二者的順序,我們將不為空的隊列進行出隊操作,并將其數據壓入為空的隊列,直到為空的隊列中只剩下一個數據,我們將這個數據定義為top,并對其進行出隊操作,最后將其進行返回。

 Queue*EmptyQ=&obj->q1;Queue*NonEmptyq=&obj->q2;if(!QueueEmpty(&obj->q1)){EmptyQ=&obj->q2;NonEmptyq=&obj->q1;}while(SizeQueue(NonEmptyq)>1){PushQueue(EmptyQ,QueueFront(NonEmptyq));PopQueue(NonEmptyq);}int top=QueueFront(NonEmptyq);PopQueue(NonEmptyq);return top;

Ⅳ、int myStackTop(MyStack* obj)

解決這個接口,我們首先需要找到不為空的那個隊列,然后調用其獲取隊尾數據的函數,最后將這個函數返回的結果返回即可。

int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}

Ⅴ、bool myStackEmpty(MyStack* obj)

我們需要保證我們的兩個隊列都為空,這樣才能夠保證我們創建的隊列為空。

bool myStackEmpty(MyStack* obj) 
{return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);    
}

Ⅵ、void myStackFree(MyStack* obj)

需要先對我們所創建的q1和q2隊列進行銷毀,然后再對ob進行free操作,以防止內存的泄漏。

void myStackFree(MyStack* obj) 
{DestoryQueue(&obj->q1);DestoryQueue(&obj->q2);free(obj);}

五、完整代碼

//定義數據類型
typedef int QueueDataType;
//定義隊列結構
typedef struct QueueNode
{struct QueueNode* next;QueueDataType Data;
}Qnode;//定義頭、尾指針
typedef struct Queue
{Qnode* phead;Qnode* ptail;int size;
}Queue;//初始化
void InitQueue(Queue* pq);
//銷毀
void DestoryQueue(Queue* pq);
//入隊
void PushQueue(Queue* pq, QueueDataType x);
//出隊
void PopQueue(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//獲取SIze
int SizeQueue(Queue* pq);
//獲取隊頭元素
QueueDataType QueueFront(Queue* pq);
//獲取隊尾元素
QueueDataType QueueBack(Queue* pq);void InitQueue(Queue* pq)
{assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}
//銷毀
void DestoryQueue(Queue* pq)
{assert(pq);Qnode* cur = pq->phead;while (cur){Qnode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}
//入隊
void PushQueue(Queue* pq, QueueDataType x)
{assert(pq);Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));if (newnode == NULL){perror("malloc fail");return;}//賦值newnode->Data = x;newnode->next = NULL;//分情況討論if (pq->ptail == NULL){assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else{pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}
//出隊
void PopQueue(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));//一個節點if (pq->phead->next == NULL){free(pq->phead);pq->phead = pq->ptail = NULL;}//多個節點else{//頭刪Qnode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;}
//判空
bool QueueEmpty(Queue* pq)
{assert(pq);return pq->size == 0;
}
//獲取SIze
int SizeQueue(Queue* pq)
{assert(pq);return pq->size;
}
//獲取隊頭元素
QueueDataType QueueFront(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->phead->Data;
}
//獲取隊尾元素
QueueDataType QueueBack(Queue* pq)
{assert(pq);assert(!QueueEmpty(pq));return pq->ptail->Data;
}typedef struct 
{Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() 
{MyStack*obj=(MyStack*)malloc(sizeof(MyStack));if(obj==NULL){perror("malloc fail");return NULL;}InitQueue(&obj->q1);InitQueue(&obj->q2);return obj;}void myStackPush(MyStack* obj, int x) 
{if(!QueueEmpty(&obj->q1)){PushQueue(&obj->q1,x);}else{PushQueue(&obj->q2,x);}
}int myStackPop(MyStack* obj)
{Queue*EmptyQ=&obj->q1;Queue*NonEmptyq=&obj->q2;if(!QueueEmpty(&obj->q1)){EmptyQ=&obj->q2;NonEmptyq=&obj->q1;}while(SizeQueue(NonEmptyq)>1){PushQueue(EmptyQ,QueueFront(NonEmptyq));PopQueue(NonEmptyq);}int top=QueueFront(NonEmptyq);PopQueue(NonEmptyq);return top;
}int myStackTop(MyStack* obj) 
{if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}bool myStackEmpty(MyStack* obj) 
{return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);    
}void myStackFree(MyStack* obj) 
{DestoryQueue(&obj->q1);DestoryQueue(&obj->q2);free(obj);}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/

在這里插入圖片描述

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

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

相關文章

文件夾重命名:徹底擺脫數字困擾,批量修改文件夾名去除數字

在日常生活和工作中,經常會遇到需要修改文件夾名稱的情況。有時候是因為文件夾名稱中包含了數字,有時候是因為文件夾名稱不符合規范。無論出于什么原因,修改文件夾名稱都是一件非常繁瑣的事情。尤其是需要修改大量文件夾名稱時,手…

Jenkins 整合 Docker 自動化部署

Docker 安裝 Jenkins 配置自動化部署 1. Docker 安裝 Jenkins 1.1 拉取鏡像文件 docker pull jenkins/jenkins1.2 創建掛載文件目錄 mkdir -p $HOME/jenkins_home1.3 啟動容器 docker run -d -p 8080:8080 -v $HOME/jenkins_home:/var/jenkins_home --name jenkins jenkin…

CentOS rpm安裝Nginx和配置

CentOS rpm安裝Nginx和配置 官方下載地址: http://nginx.org/en/download.html 介紹 Nginx(“engine x”)是一款由俄羅斯的程序設計師Igor Sysoev所開發高性能的 Web和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 代理服務器。 rpm包安裝 #安裝nginx&#xff0c…

k8s部署的java服務查看連接nacos緩存的配置文件

一、問題描述 k8s部署的java服務,使用nacos中的配置文件,需要在緩存中查看該服務具體是使用到了哪些配置文件 二、解決 參考文檔: https://nacos.io/zh-cn/docs/system-configurations.html 文檔描述如下: 進入java服務容器進入用戶目錄下的nacos&a…

4-Docker命令之docker version

1.docker version介紹 docker version命令是用于查看docker容器的版本信息 2.docker version用法 docker version [參數] [root@centos79 ~]# docker version --helpUsage: docker version [OPTIONS]Show the Docker version informationOptions:-f, --format string Fo…

Android 12.0 mt6771新增分區功能實現四

1.前言 在12.0的系統rom開發中,在對某些特殊模塊中關于數據的存儲方面等需要新增分區來保存, 所以就需要在系統分區新增分區,接下來就來實現這個功能,看第四部分的新增分區的實現過程 2.mt6771新增分區功能實現四的核心類 device/mediatek/mt6771/ueventd.mt6771.rcdevice…

Java枚舉詳解

一、什么是枚舉類型 枚舉類型是一種特殊的數據類型,用于定義一組固定的命名常量。枚舉類型提供了一種更強大、更安全和更易讀的方式來表示一組相關的常量。 在Java中,枚舉類型是通過使用enum關鍵字來定義的。枚舉類型可以包含一個或多個枚舉常量&#xf…

常見狀態碼總結

常見狀態碼總結 2xx 200 OK:表示服務器成功處理了客戶端的請求,并返回所請求的數據。這是最常見的狀態碼,表示一切正常。201 Created:表示服務器成功處理了客戶端的 POST 請求,并在服務器上創建了新的資源。204 No C…

vue005——vue組件入門(非單文件組件和單文件組件)

一、非單文件組件 1.1、單文件組件的使用 1.1.1、局部注冊 1、第一步&#xff1a;創建school組件 2、第二步&#xff1a;注冊組件&#xff08;局部注冊&#xff09; 3、第三步&#xff1a;使用組件&#xff08;編寫組件標簽&#xff09; <!DOCTYPE html> <html>…

設計模式—里氏替換原則

1.概念 里氏代換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之一。 里氏代換原則中說&#xff0c;任何基類可以出現的地方&#xff0c;子類一定可以出現。 LSP是繼承復用的基石&#xff0c;只有當衍生類可以替換掉基類&#xff0c;軟件單位的功能不受到影…

Spring注解方式整合第三方框架

目錄 Spring整合MyBatis 原有xml方式整合配置如下 注解方式&#xff1a; Import可以導入如下三種類 第三方框架是指由其他開發者或團隊開發的軟件模塊或庫&#xff0c;供開發者在自己的應用程序中使用。這些框架通常提供了一系列已經封裝好的功能或工具&#xff0c;可節省開…

使用flask返回json格式的數據

Flask Flask是一個使用Python編寫的輕量級Web框架&#xff0c;它的設計理念是保持簡單、靈活和易擴展。它的核心是Werkzeug和Jinja2&#xff0c;并且它本身只提供了非常基礎的Web框架功能&#xff0c;例如路由和請求處理等。 使用Flask可以快速創建一個Web應用程序&#xff0c;…

跳躍游戲Ⅱ[中等]

優質博文&#xff1a;IT-BLOG-CN 一、題目 給定一個長度為n的0索引整數數組nums。初始位置為nums[0]。每個元素nums[i]表示從索引i向前跳轉的最大長度。換句話說&#xff0c;如果你在nums[i]處&#xff0c;你可以跳轉到任意nums[i j]處: 0 < j < nums[i] i j < n …

【Python 訓練營】N_8 打印阿姆斯特朗數

題目 輸入一個數&#xff0c;判斷是否為阿姆斯特朗數&#xff0c;阿姆斯特朗數指一個n位正整數等于其各位數字的n次方之和。其中n為3時是水仙花數。 分析 利用循環&#xff0c;獲取數的長度&#xff0c;根據長度和定義&#xff0c;拆分出來運算 答案 while True:n int(in…

【Python 訓練營】N_7 打印水仙花數

題目 打印出1000以內所有的"水仙花數"&#xff0c;所謂"水仙花數"是指一個三位數&#xff0c;其各位數字立方和等于該數本身。例如&#xff1a;153是一個"水仙花數"&#xff0c;因為1531的三次方&#xff0b;5的三次方&#xff0b;3的三次方。 …

數學啟發式

學習資料&#xff1a; 優化求解器 | Gurobi 數學啟發式算法&#xff1a;參數類型與案例實現 數學啟發式算法 | 可行性泵 (Feasibility Pump)算法精講&#xff1a;一份讓您滿意的【理論介紹編程實現數值實驗】學習筆記(PythonGurobi實現) 大佬到底是大佬&#xff01;這些資料太…

Mac Ubuntu雙系統解決WiFi和WiFi 5G網絡不可用問題

文章目錄 設備信息1. Ubuntu WiFi不可用解決方式查看Mac的網卡型號根據網卡型號搜索獲取到的解決方法查看WiFi名字問題參考鏈接 2. 解決WiFi重啟后失效問題打開終端創建.sh腳本文件編輯腳本文件復制粘貼腳本修改腳本權限創建并編輯systemd service文件復制粘貼下文到systemd se…

Typescript怎樣對URL參數進行編碼?

URL中的參數需要進行編碼&#xff08;URL encoding&#xff09;是為了確保傳輸的參數不包含特殊字符&#xff0c;同時確保數據的可靠性和安全性。 特殊字符如空格、&、?等在URL中有特殊含義&#xff0c;如果直接包含在參數值中&#xff0c;可能會導致解析錯誤或者安全問題…

只考數據結構,計算機評級C+,成都信息工程大學考情分析

成都信息工程大學(C) 考研難度&#xff08;☆☆&#xff09; 內容&#xff1a;23考情概況&#xff08;擬錄取和復試分析&#xff09;、院校概況、24專業目錄、23復試詳情、各專業考情分析、各科目考情分析。 正文1715字&#xff0c;預計閱讀&#xff1a;3分鐘 2023考情概況 …

Java實現求最大值

1 問題 接收用戶輸入的3個整數&#xff0c;如何將最大值作為結果輸出。 2 方法 采用“截圖文字代碼”的方式描述。 引入輸入包調用main()函數&#xff0c;提示并接收用戶輸入的3個整數&#xff0c;并交由變量a b c來保存。對接收的3個數據進行比較&#xff0c;先比較a和b&#…