您好,登錄后才能下訂單哦!
本篇內容介紹了“C語言數據結構之棧與隊列怎么相互實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
題干要求:
細節分析:隊列是先進先出; 要實現的棧是先進后出。
解題思路:假設:先用一個隊列儲存數據 N 個,然后將前 N-1 個數據導入到另一個隊列,
此時,原始隊列中僅剩一個,是最后剩的數據,便可將其導出,這便是一次后進先出。
細節點:每次導出數據時,都需要一個隊列向另一個隊列傳入數據,因此輸入隊列和輸出隊列 需要輪換,要對其進行判定。
具體過程gif動態圖如下:
1.初始化棧:先初始化兩個隊列
//棧的結構是由兩個隊列構成 typedef struct Nystack{ Quetail q1; Quetail q2; } MyStack; //棧的初始化 MyStack* myStackCreate() { MyStack* Newstack = (MyStack*)malloc(sizeof(MyStack)); Que_Init(&Newstack->q1); Que_Init(&Newstack->q2); return Newstack; }
2. 插入數據
因為存儲數據的隊列不是固定的,因此在一個隊列有數據的前提下,就繼續向該隊列插入數據,
空的隊列負責在導出數據時進行輪轉。(哪個不空向哪個插入)
//插入數據 void myStackPush(MyStack* obj, int x) { //if((&obj->q1)->head == NULL) //法一:直接判斷是否為空 if(Que_Empty(&obj->q1)) //法二:后續函數的復用 Que_push(&obj->q2,x); else Que_push(&obj->q1,x); }
3.導出數據(實現先進后出)
第一步:將有數據的隊列中除最后進的數據,依次導入到另一個空隊列 ;
導入空隊列,刪除原隊列,保留最后數據。
第二布:將原隊列中最后一個數據導出 。
注:這里先假設了兩個隊列中,一個是原隊列和一個是空隊列,再進行判定,若與實際不符,則 交換 。
int myStackPop(MyStack* obj) { int temp = 0; //假設原隊列和空隊列 Quetail* existque = &obj->q1,*nullque = &obj->q2; if((&obj->q1)->head == NULL) //判斷與實際是否相符 { existque = nullque; nullque = &obj->q1; } for(;existque->head->Next;) //保留最后一個數據 { Que_push(nullque,existque->head->data); //向空隊列導入數據 Que_pop(existque); //刪除原隊列數據 } temp = existque->head->data; Que_pop(existque); //導出最后進的數據 return temp; }
4.查找棧頂數據
找到不空的隊列 >> 返回其隊尾的數據
int myStackTop(MyStack* obj) { if((&obj->q1)->head == NULL) { return (&obj->q2)->tail->data; } return (&obj->q1)->tail->data; }
5.判斷棧是否為空:
判斷兩個隊列是否均為空
bool myStackEmpty(MyStack* obj) { assert(obj); //法一:直接判斷 //if((&obj->q1)->head == NULL&& (&obj->q2)->head == NULL) //法二:復用隊列判空函數 if(Que_Empty(&(obj->q1))&&Que_Empty(&(obj->q2))) return true; return false; }
6.銷毀棧:
銷毀兩個隊列
void myStackFree(MyStack* obj) { Que_Destory(&obj->q1); Que_Destory(&obj->q2); free(obj); }
題干要求:
細節分析:這次是用兩個棧,實現先進先出 。
解題思路:首先,將兩個棧分為入口棧和出口棧,
其次,數據正序入口棧,由于棧是先進后出,因此將數據再逆序進入出口棧,
然后,此時數據再出口棧中是逆序,所以,便可以正序從出口棧中依次排出 。
1.初始化雙棧隊列
typedef struct { Stack T1; Stack T2; } MyQueue; MyQueue* myQueueCreate() { MyQueue *Q1; Q1 = (MyQueue*)malloc(sizeof(MyQueue)); Stack_init(&(Q1->T1)); // T1 做入口棧 Stack_init(&(Q1->T2)); // T2 做出口棧 return Q1; }
2.插入數據
void myQueuePush(MyQueue* obj, int x) { Stack_push(&obj->T1,x); //這里將棧 T1 作為入口棧 }
3.刪除數據(先進先出)
將入口棧數據記錄 >> 刪除入口棧數據 >> 導入出口棧 >> 從出口棧導出數據
int myQueuePop(MyQueue* obj) { if(Stack_Empty(&obj->T2)) //判斷是否為空 { int k = 0; for(;!Stack_Empty(&obj->T1);) { k = Stack_Top(&obj->T1); //記錄入口站數據 Stack_pop(&obj->T1); //刪除入口棧數據 Stack_push(&obj->T2,k); //導入出口棧 } } int temp = 0; temp = Stack_Top(&obj->T2); Stack_pop(&obj->T2); //從出口棧導出數據 return temp; //題干要求返回導出的值 }
4.查找隊列頭部數據
這里的頭部數據是正序的頭數據,因此要先將入口棧中的逆序數據導入出口棧,
變成正序,再返回出口棧的棧頂數據 。
int myQueuePeek(MyQueue* obj) { if(Stack_Empty(&obj->T2)) //判斷出口棧中是否有數據 { int k = 0; for(;!Stack_Empty(&obj->T1);) //向出口棧導入數據 { k = Stack_Top(&obj->T1); Stack_pop(&obj->T1); Stack_push(&obj->T2,k); } } return Stack_Top(&obj->T2); //返回出口棧棧頂數據 }
5.判斷隊列是否為空 及 銷毀隊列
//判斷隊列是否為空 bool myQueueEmpty(MyQueue* obj) { //判斷兩個棧是否均為空 return Stack_Empty(&obj->T1)&&Stack_Empty(&obj->T2); } //銷毀釋放隊列 void myQueueFree(MyQueue* obj) { Stack_pop(&obj->T1); Stack_pop(&obj->T2); free(obj); }
“C語言數據結構之棧與隊列怎么相互實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。