排隊(duì)
一羹蚣、棧
- 定義:只允許
一端
進(jìn)行插入或者刪除操作的線性表 - 特點(diǎn):
LIFO后進(jìn)先出
忌愚,像是一疊盤子吊档,只能從上放判沟,從上取. - 實(shí)現(xiàn):
順序存儲(chǔ)實(shí)現(xiàn)
和鏈?zhǔn)酱鎯?chǔ)實(shí)現(xiàn)
1.順序存儲(chǔ)實(shí)現(xiàn)代碼
#include<stdio.h>
#define MAX_SIZE 10
typedef struct {
int data[MAX_SIZE];
int top;
}Stack;
/**
* 初始化棧.
* @return 指向棧的指針.
*/
Stack* initStack();
/**
* 壓棧.
* @param data 數(shù)據(jù).
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool push(int data,Stack* stack);
/**
* 出棧.
* @param data 數(shù)據(jù).
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
int pop(Stack* stack);
/**
* 已滿.
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool isFull(Stack* stack);
/**
* 已空.
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool isEmpty(Stack* stack);
/**
* 展示棧元素.
* @param stack 棧指針.
*/
void showStack(Stack* stack);
int main() {
Stack* stack = initStack();
push(1,stack);
push(2,stack);
push(3,stack);
push(4,stack);
push(5,stack);
pop(stack);
pop(stack);
pop(stack);
pop(stack);
pop(stack);
pop(stack);
}
Stack* initStack() {
static Stack stack;
for(int i =0;i < MAX_SIZE; i++) {
stack.data[i] = 0;
}
stack.top = -1;
return &stack;
}
bool push(int data,Stack* stack) {
if(isFull(stack)) {
return false;
}
stack->data[++stack->top] = data;
showStack(stack);
return true;
}
bool isFull(Stack* stack) {
if(stack->top == MAX_SIZE -1) {
puts("棧已滿");
return true;
}
return false;
}
bool isEmpty(Stack* stack) {
if(stack->top == -1){
return true;
}
return false;
}
void showStack(Stack* stack) {
for(int i = 0; i <= stack->top; i++) {
printf("%d ", stack->data[i]);
}
printf("\n");
}
int pop(Stack* stack){
if(isEmpty(stack)) {
puts("棧已空");
return false;
}
int popEle = stack->data[stack->top];
stack->data[stack->top--] = 0;
printf("popEle = %d\n",popEle);
showStack(stack);
return popEle;
}
2.帶頭結(jié)點(diǎn)鏈?zhǔn)酱鎯?chǔ)實(shí)現(xiàn).
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int data;
struct Node* next;
}Stack,Node;
/**
* 初始化棧.
* @return 指向棧的指針.
*/
Stack* initStack();
/**
* 壓棧.
* @param data 數(shù)據(jù).
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool push(int data,Stack* stack);
/**
* 出棧.
* @param data 數(shù)據(jù).
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
int pop(Stack* stack);
/**
* 已空.
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool isEmpty(Stack* stack);
/**
* 展示棧元素.
* @param stack 棧指針.
*/
void showStack(Stack* stack);
/**
* 獲取一個(gè)節(jié)點(diǎn).
* @param data 數(shù)據(jù).
* @return 節(jié)點(diǎn).
*/
Node* getNode(int data);
int main() {
Stack* stack = initStack();
push(1,stack);
push(2,stack);
push(3,stack);
push(4,stack);
push(5,stack);
pop(stack);
pop(stack);
pop(stack);
pop(stack);
pop(stack);
pop(stack);
}
Stack* initStack(){
return getNode(0);
}
Node* getNode(int data){
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
bool push(int data,Stack* stack) {
Stack* pointer = stack;
Node* node = getNode(data);
node->next = pointer->next;
pointer->next = node;
showStack(stack);
return true;
}
void showStack(Stack* stack) {
Stack* pointer = stack->next;
while(pointer != NULL) {
printf("%d ", pointer->data);
pointer = pointer->next;
}
printf("\n");
}
int pop(Stack* stack) {
if(isEmpty(stack)) {
return -1;
}
Node* freeNode = stack->next;
int popEle = freeNode->data;
stack->next = stack->next->next;
free(freeNode);
printf("popEle = %d\n",popEle);
showStack(stack);
return popEle;
}
bool isEmpty(Stack* stack){
if(stack->next == NULL) {
puts("棧已空");
return true;
}
return false;
}
3.感受
棧代碼寫起來要比線性表更加簡(jiǎn)單,以為畢竟棧是受限的線性表恶导,砍掉了一些操作而已浆竭。
二、隊(duì)列
- 定義: 只允許在一端進(jìn)行插入甲锡,在另一端進(jìn)行刪除的線性表
- 特點(diǎn):FIFO先進(jìn)先出.
- 實(shí)現(xiàn):
靜態(tài)存儲(chǔ)實(shí)現(xiàn)
兆蕉,動(dòng)態(tài)存儲(chǔ)實(shí)現(xiàn)
.
1.靜態(tài)存儲(chǔ)實(shí)現(xiàn)的循環(huán)隊(duì)列
#include<stdio.h>
#define MAX_SIZE 10
typedef struct Queue{
int data[MAX_SIZE];
int front;
int rear;
}Queue;
/**
* 初始化隊(duì)列.
* @return 隊(duì)列指針.
*/
Queue* initQueue();
/**
* 入隊(duì).
* @param data 數(shù)據(jù).
* @param queue 隊(duì)列指針.
* @return true 成功,false失敗.
*/
bool joinQueue(int data, Queue* queue);
/**
* 出隊(duì).
* @param data 數(shù)據(jù).
* @param queue 隊(duì)列指針.
* @return true 成功缤沦,false失敗.
*/
bool leaveQueue(Queue* queue);
/**
* 判斷隊(duì)列已滿.
* @param queue 隊(duì)列指針.
* @return true 成功虎韵,false失敗.
*/
bool isFull(Queue* queue);
/**
* 判斷空隊(duì)列.
* @param queue 隊(duì)列指針.
* @return true 成功,false失敗.
*/
bool isEmpty(Queue* queue);
/**
* 展示隊(duì)列.
* @param queue 隊(duì)列.
*/
void showQueue(Queue* queue);
int main() {
Queue* queue = initQueue();
joinQueue(1,queue);
joinQueue(2,queue);
joinQueue(3,queue);
joinQueue(4,queue);
joinQueue(5,queue);
joinQueue(6,queue);
joinQueue(7,queue);
joinQueue(8,queue);
joinQueue(9,queue);
joinQueue(10,queue);
leaveQueue(queue);
joinQueue(10,queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
return true;
}
Queue* initQueue() {
static Queue queue;
for(int i =0; i < MAX_SIZE; i++) {
queue.data[i] = 0;
}
queue.front = 0;
queue.rear = 0;
return & queue;
}
bool isFull(Queue* queue) {
if((queue->rear + 1) % MAX_SIZE == queue->front) {
puts("隊(duì)列已滿");
return true;
}
return false;
}
bool isEmpty(Queue* queue) {
if(queue->front == queue->rear) {
puts("隊(duì)列為空");
return true;
}
return false;
}
void showQueue(Queue* queue) {
int start = queue->front;
int end = queue->rear;
while(end != start){
printf("%d ",queue->data[start]);
start = (start + 1) % MAX_SIZE;
}
printf("\n");
}
bool leaveQueue(Queue* queue) {
if(isEmpty(queue)) {
return false;
}
int ele = queue->data[queue->front];
queue->front = (queue->front + 1) % MAX_SIZE;
printf("leave queue ele = %d\n",ele);
showQueue(queue);
return true;
}
bool joinQueue(int data, Queue* queue) {
if(isFull(queue)) {
return false;
}
queue->data[queue->rear] = data;
queue->rear = (queue->rear + 1) % MAX_SIZE;
showQueue(queue);
return true;
}
2.鏈?zhǔn)酱鎯?chǔ)實(shí)現(xiàn)的隊(duì)列.
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 10
typedef struct Node{
int data;
struct Node* prior;
struct Node* next;
}Node;
typedef struct Queue{
Node* front;
Node* rear;
}Queue;
/**
* 初始化隊(duì)列.
* @return 隊(duì)列指針.
*/
Queue* initQueue();
/**
* 獲取節(jié)點(diǎn).
* @param data 數(shù)據(jù).
* @return 節(jié)點(diǎn)指針.
*/
Node* getNode(int data);
/**
* 加入隊(duì)列.
* @param data 數(shù)據(jù).
* @param queue 隊(duì)列指針.
* @return true 成功缸废,false失敗.
*/
bool joinQueue(int data,Queue* queue);
/**
* 離開隊(duì)列.
* @param queue 隊(duì)列指針.
* @return true 成功包蓝,false失敗.
*/
bool leaveQueue(Queue* queue);
/**
* 展示隊(duì)列.
* @param queue 隊(duì)列指針.
*/
void showQueue(Queue* queue);
int main() {
Queue* queue = initQueue();
joinQueue(1,queue);
joinQueue(2,queue);
joinQueue(3,queue);
joinQueue(4,queue);
joinQueue(5,queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
leaveQueue(queue);
}
Queue* initQueue() {
static Queue queue;
Node* node = getNode(0);
node->next = node;
node->prior = node;
queue.front = node;
queue.rear = node;
return &queue;
}
Node* getNode(int data) {
Node* node = (Node*)malloc(sizeof(Node));
node->prior = NULL;
node->next = NULL;
node->data = data;
return node;
}
bool joinQueue(int data,Queue* queue){
Node* node = getNode(data);
Node* pointer = queue->rear;
pointer->next = node;
node->prior = pointer;
node->next = queue->front;
pointer->prior = node;
queue->rear = node;
showQueue(queue);
return true;
}
void showQueue(Queue* queue) {
Node* pointer = queue->front->next;
while(pointer != queue->rear) {
printf("%d ",pointer->data);
pointer = pointer->next;
}
printf("%d\n",pointer->data);
}
bool leaveQueue(Queue* queue) {
if(queue->front == queue->rear) {
puts("隊(duì)列已空\(chéng)n");
return false;
}
Node* freeNode = queue->front;
queue->front = queue->front->next;
queue->front->prior = queue->rear;
queue->rear->next = queue->front;
int ele = queue->front->data;
free(freeNode);
printf("leave queue ele = %d\n",ele);
if(queue->front != queue->rear) {
showQueue(queue);
return true;
}
puts("隊(duì)列已空");
return true;
}
三驶社、棧的應(yīng)用
- 中綴表達(dá)式轉(zhuǎn)后綴
思想:
用棧存儲(chǔ)尚未確定運(yùn)算順序的運(yùn)算符和界限符.
待優(yōu)化:
因?yàn)槭褂玫氖亲址麛?shù)組所以,目前只處理單個(gè)字符數(shù)字'0’,'1'...'9'测萎,多位數(shù)情況'10'尚不能處理亡电。代碼著重體現(xiàn)了中綴轉(zhuǎn)后綴表達(dá)式的思想。
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
char data;
struct Node* next;
}Stack,Node;
/**
* 初始化棧.
* @return 指向棧的指針.
*/
Stack* initStack();
/**
* 壓棧.
* @param data 數(shù)據(jù).
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool push(char data,Stack* stack);
/**
* 出棧.
* @param data 數(shù)據(jù).
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
char pop(Stack* stack);
/**
* 已空.
* @param stack 棧指針.
* @return true 成功,false失敗.
*/
bool isEmpty(Stack* stack);
/**
* 展示棧元素.
* @param stack 棧指針.
*/
void showStack(Stack* stack);
/**
* 獲取一個(gè)節(jié)點(diǎn).
* @param data 數(shù)據(jù).
* @return 節(jié)點(diǎn).
*/
Node* getNode(char data);
/**
* 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式.
* @param stack 棧.
* @return 字符串.
*/
char * nifixToPostFix(Stack* stack);
int main() {
Stack* stack = initStack();
char* result = nifixToPostFix(stack);
puts(result);
}
Stack* initStack(){
return getNode(' ');
}
Node* getNode(char data){
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
bool push(char data,Stack* stack) {
Stack* pointer = stack;
Node* node = getNode(data);
node->next = pointer->next;
pointer->next = node;
showStack(stack);
return true;
}
void showStack(Stack* stack) {
Stack* pointer = stack->next;
while(pointer != NULL) {
printf("%d ", pointer->data);
pointer = pointer->next;
}
printf("\n");
}
char pop(Stack* stack) {
if(isEmpty(stack)) {
return '#';
}
Node* freeNode = stack->next;
char popEle = freeNode->data;
stack->next = stack->next->next;
free(freeNode);
printf("popEle = %d\n",popEle);
showStack(stack);
return popEle;
}
bool isEmpty(Stack* stack){
if(stack->next == NULL) {
puts("棧已空");
return true;
}
return false;
}
// 使用棧存儲(chǔ)暫時(shí)不能確定順序的運(yùn)算符.
char * nifixToPostFix(Stack* stack) {
char input[1024];
char postFixExpression[1024];
char* inputPointer = input;
char* pointer = postFixExpression;
char* string = postFixExpression;
puts("請(qǐng)輸入表達(dá)式");
gets(input);
while(*inputPointer){
// 操作數(shù)直接加入后綴表達(dá)式.
char aim = *inputPointer;
if(aim >= '0' && aim <='9') {
*pointer = aim;
pointer++;
}
//遇到‘(’界限符,直接入棧.
if(aim == '(') {
push(aim, stack);
}
// 遇到界限符‘)’硅瞧,說明之前肯定有‘(’在棧中份乒,彈出棧中所有的運(yùn)算符
// 并加入后綴表達(dá)式,直到遇到‘(’注意左括號(hào)不加入表達(dá)式.
if(aim == ')') {
char popEle = pop(stack);
while(popEle != '#') {
if(popEle == '('){
break;
}
*pointer = popEle;
pointer++;
popEle = pop(stack);
}
}
//遇到運(yùn)算符腕唧,彈出高于或者等于當(dāng)前運(yùn)算符優(yōu)先級(jí)的棧中運(yùn)算符
//遇到椈蛳剑空或者(結(jié)束,并將當(dāng)前運(yùn)算符加入棧中.
if(aim == '+' || aim == '-') {
//所有的運(yùn)算符都曼度大于等于優(yōu)先級(jí)顧直接彈出.
char popEle = pop(stack);
while(true) {
if(popEle == '#') {
break;
}
if(popEle == '(' ){
push(popEle, stack);
break;
}
*pointer = popEle;
pointer++;
popEle = pop(stack);
}
push(aim, stack);
}
if(aim == '*' || aim == '/') {
char popEle = pop(stack);
while(popEle == '*' || popEle =='/') {
*pointer = popEle;
pointer++;
popEle = pop(stack);
}
if(popEle == '+' || popEle == '-') {
push(popEle, stack);
}
push(aim, stack);
}
inputPointer++;
}
// 最后將隊(duì)列中的全部運(yùn)算符彈出并加入后綴表達(dá)式.
char popEle = pop(stack);
while(popEle != '#') {
*pointer = popEle;
pointer++;
popEle = pop(stack);
}
*pointer = '\0';
return string;
}
- 后綴表達(dá)式求值
思想:
用棧存儲(chǔ)運(yùn)算數(shù),遍歷表達(dá)式遇到運(yùn)算符直接彈出兩個(gè)運(yùn)算數(shù)進(jìn)行計(jì)算并壓棧枣接,重復(fù)操作颂暇,直到棧中還剩最后一個(gè)運(yùn)算數(shù),這就是結(jié)果但惶。
int calculatePostFix(char* expression,Stack* stack) {
char* pointer = expression;
while(*pointer) {
char aim = *pointer;
if(aim >='0' && aim <= '9') {
push(aim - '0',stack);
}
if(aim == '+' ||aim == '-'||aim == '*'||aim == '/'){
int num1 = pop(stack);
int num2 = pop(stack);
int pushEle;
switch(aim){
case '+':{
pushEle = num2 + num1;
break;
}
case '-':{
pushEle = num2 - num1;
break;
}
case '*':{
pushEle = num2 * num1;
break;
}
case '/':{
pushEle = num2 / num1;
break;
}
}
push(pushEle, stack);
}
pointer++;
}
return pop(stack);
}
- 函數(shù)調(diào)用棧
- 遞歸
四耳鸯、隊(duì)列的應(yīng)用
樹的層序遍歷.
圖的廣度優(yōu)先遍歷.
多個(gè)進(jìn)程爭(zhēng)搶有限系統(tǒng)資源,F(xiàn)CFS(先來先服務(wù)).