日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

栈和队列基本操作

發布時間:2023/12/9 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈和队列基本操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

棧和隊列

  • 一、棧
    • 棧是什么
    • 棧的實現
    • 棧的基本操作
      • 棧類型的定義
      • 初始化棧
      • 檢查棧是否為滿
      • 入棧
      • 出棧
      • 獲取棧頂元素
      • 檢測棧是否為空
      • 測試函數
    • 完整代碼
      • Stack.h
      • Stack.c
      • main.c
  • 二、隊列
    • 隊列是什么
    • 隊列的實現
      • 隊列類型的定義
      • 申請一個節點
      • 初始化隊列
      • 隊尾入隊列
      • 隊頭出隊列
      • 獲取隊列頭部元素
      • 獲取隊列隊尾元素
      • 獲取隊列中有效元素個數
      • 檢測隊列是否為空
      • 銷毀隊列
      • 測試函數
    • 完整代碼
      • Queue.h
      • Queue.c
      • main.c
  • 三、環形隊列
    • 假溢出問題

一、棧

棧是什么

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

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

出棧:棧的刪除操作叫做出棧。出數據也在棧頂。

棧遵循先進后出原則

棧的實現

??棧的實現一般可以使用數組或者鏈表實現,相對而言數組的結構實現更優一些。因為數組在尾上插入數據的代價比較小。

棧的基本操作

棧類型的定義

typedef int STDataType; typedef struct Stack {STDataType* a;int top; // 棧頂int capacity; // 容量 int size;}Stack;

初始化棧

void StackInit(Stack* ps) {assert(ps);ps->a=(STDataType*)malloc(sizeof(STDataType)*5); if(NULL==ps->a){assert(0);return;}ps->capacity=5;ps->size=0; }

檢查棧是否為滿

void CheckStack(Stack* ps) {assert(ps);if(ps->capacity==ps->size){//1.申請空間int newcapacity=ps->capacity*2;STDataType *temp=(STDataType*)malloc(sizeof(STDataType)*newcapacity);if(temp==NULL){assert(0);return;}//2.拷貝元素memcpy(temp,ps->a,sizeof(STDataType)*ps->size);//3.釋放舊空間free(ps->a);//4.使用新空間 ps->a=temp;ps->capacity=newcapacity;} }

入棧

void StackPush(Stack* ps, STDataType data) {assert(ps);CheckStack(ps);ps->a[ps->size]=data;ps->size++; }

出棧

void StackPop(Stack* ps) {assert(ps);if(!StackEmpty(ps)){ps->size--;}return; }

獲取棧頂元素

STDataType StackTop(Stack* ps) {assert(ps);return ps->a[ps->size-1]; }// 獲取棧中有效元素個數 int StackSize(Stack* ps) {assert(ps);return ps->size; }

檢測棧是否為空

int StackEmpty(Stack* ps) {assert(ps);return 0==ps->size; }// 銷毀棧 void StackDestroy(Stack* ps) {assert(ps);if(ps->a){free(ps->a);ps->a=NULL;ps->capacity=0;ps->size=0;} }

測試函數

void TestStack() {Stack s;StackInit(&s);StackPush(&s,1);StackPush(&s,2);StackPush(&s,3);StackPush(&s,4);StackPush(&s,5);StackPush(&s,6);StackPush(&s,7);printf("%d\n",StackTop(&s));printf("%d\n",StackSize(&s));StackPop(&s);StackPop(&s);StackPop(&s);printf("%d\n",StackTop(&s));printf("%d\n",StackSize(&s));StackDestroy(&s); }

完整代碼

Stack.h

typedef int STDataType; typedef struct Stack {STDataType* a;int top; // 棧頂int capacity; // 容量 int size;}Stack; // 初始化棧 void StackInit(Stack* ps); //檢查棧是否為慢void CheckStack(Stack* ps);// 入棧 void StackPush(Stack* ps, STDataType data); // 出棧 void StackPop(Stack* ps); // 獲取棧頂元素 STDataType StackTop(Stack* ps); // 獲取棧中有效元素個數 int StackSize(Stack* ps); // 檢測棧是否為空,如果為空返回非零結果,如果不為空返回0 int StackEmpty(Stack* ps); // 銷毀棧 void StackDestroy(Stack* ps);void TestStack();

Stack.c

#include "Stack.h"#include<stdio.h> #include<malloc.h> #include<assert.h> #include<string.h>// 初始化棧 void StackInit(Stack* ps) {assert(ps);ps->a=(STDataType*)malloc(sizeof(STDataType)*5); if(NULL==ps->a){assert(0);return;}ps->capacity=5;ps->size=0; }// 檢查棧是否滿void CheckStack(Stack* ps) {assert(ps);if(ps->capacity==ps->size){//1.申請空間int newcapacity=ps->capacity*2;STDataType *temp=(STDataType*)malloc(sizeof(STDataType)*newcapacity);if(temp==NULL){assert(0);return;}//2.拷貝元素memcpy(temp,ps->a,sizeof(STDataType)*ps->size);//3.釋放舊空間free(ps->a);//4.使用新空間 ps->a=temp;ps->capacity=newcapacity;} }// 入棧 void StackPush(Stack* ps, STDataType data) {assert(ps);CheckStack(ps);ps->a[ps->size]=data;ps->size++; }// 出棧 void StackPop(Stack* ps) {assert(ps);if(!StackEmpty(ps)){ps->size--;}return; }// 獲取棧頂元素 STDataType StackTop(Stack* ps) {assert(ps);return ps->a[ps->size-1]; }// 獲取棧中有效元素個數 int StackSize(Stack* ps) {assert(ps);return ps->size; }// 檢測棧是否為空,如果為空返回非零結果,如果不為空返回0 int StackEmpty(Stack* ps) {assert(ps);return 0==ps->size; }// 銷毀棧 void StackDestroy(Stack* ps) {assert(ps);if(ps->a){free(ps->a);ps->a=NULL;ps->capacity=0;ps->size=0;} } void TestStack() {Stack s;StackInit(&s);StackPush(&s,1);StackPush(&s,2);StackPush(&s,3);StackPush(&s,4);StackPush(&s,5);StackPush(&s,6);StackPush(&s,7);printf("%d\n",StackTop(&s));printf("%d\n",StackSize(&s));StackPop(&s);StackPop(&s);StackPop(&s);printf("%d\n",StackTop(&s));printf("%d\n",StackSize(&s));StackDestroy(&s); }

main.c

#include "Stack.h"int main() {TestStack();return 0; }

二、隊列

隊列是什么

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

隊列的實現

??隊列也可以數組和鏈表的結構實現,使用鏈表的結構實現更優一些,因為如果使用數組的結構,出隊列在數組頭上出數據,效率會比較低。

隊列類型的定義

typedef int QDataType;typedef struct QNode { struct QNode* next; QDataType data; }QNode; // 隊列的結構 typedef struct Queue { QNode* front; QNode* rear; int size;}Queue;

申請一個節點

QNode* buyQNode(QDataType data) {QNode *newnode=(QNode*)malloc(sizeof(QNode));if(NULL==newnode){assert(0);return NULL;}newnode->data=data;newnode->next=NULL;return newnode; }

初始化隊列

void QueueInit(Queue* q) {assert(q);q->front=q->rear=NULL;q->size=0;}

隊尾入隊列

void QueuePush(Queue* q, QDataType data) {assert(q);QNode *newnode=buyQNode(data);if(NULL==q->front){q->front=newnode; }else{q->rear->next=newnode; }q->rear=newnode;q->size++; }

隊頭出隊列

void QueuePop(Queue* q) {assert(q);if(QueueEmpty(q)){return;}else{QNode *delndoe=q->front;q->front=delndoe->next;free(delndoe);if(NULL==q->front){q->rear=NULL;}}q->size--; }

獲取隊列頭部元素

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

獲取隊列隊尾元素

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

獲取隊列中有效元素個數

int QueueSize(Queue* q) {assert(!QueueEmpty(q));return q->size; }

檢測隊列是否為空

int QueueEmpty(Queue* q) {assert(q);return NULL==q->front; }

銷毀隊列

void QueueDestroy(Queue* q) {assert(q);QNode *cur=q->front;while(cur){q->front=cur->next;free(cur);cur=q->front;}q->rear=NULL;q->size=0; }

測試函數

void TestQueue() {Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);printf("%d\n", QueueFront(&q));printf("%d\n", QueueBack(&q));printf("%d\n", QueueSize(&q));QueuePop(&q);QueuePop(&q);QueuePop(&q);printf("%d\n", QueueFront(&q));printf("%d\n", QueueBack(&q));printf("%d\n", QueueSize(&q));QueuePop(&q);QueuePop(&q);QueuePop(&q);if(QueueEmpty(&q)){printf("隊列已經為空\n");}else{printf("隊列不為空\n");}QueueDestroy(&q); }

完整代碼

Queue.h

//鏈式結構:表示隊列 typedef int QDataType;typedef struct QNode { struct QNode* next; QDataType data; }QNode; // 隊列的結構 typedef struct Queue { QNode* front; QNode* rear; int size;}Queue; // 初始化隊列 void QueueInit(Queue* q); // 隊尾入隊列 void QueuePush(Queue* q, QDataType data); // 隊頭出隊列 void QueuePop(Queue* q); // 獲取隊列頭部元素 QDataType QueueFront(Queue* q); // 獲取隊列隊尾元素 QDataType QueueBack(Queue* q); // 獲取隊列中有效元素個數 int QueueSize(Queue* q); // 檢測隊列是否為空,如果為空返回非零結果,如果非空返回0 int QueueEmpty(Queue* q); // 銷毀隊列 void QueueDestroy(Queue* q);///void TestQueue();

Queue.c

#include"Queue.h"#include<stdio.h> #include<assert.h> #include<malloc.h>//申請一個節點 QNode* buyQNode(QDataType data) {QNode *newnode=(QNode*)malloc(sizeof(QNode));if(NULL==newnode){assert(0);return NULL;}newnode->data=data;newnode->next=NULL;return newnode; }//初始化隊列 void QueueInit(Queue* q) {assert(q);q->front=q->rear=NULL;q->size=0;} // 隊尾入隊列 void QueuePush(Queue* q, QDataType data) {assert(q);QNode *newnode=buyQNode(data);if(NULL==q->front){q->front=newnode; }else{q->rear->next=newnode; }q->rear=newnode;q->size++; } // 隊頭出隊列 void QueuePop(Queue* q) {assert(q);if(QueueEmpty(q)){return;}else{QNode *delndoe=q->front;q->front=delndoe->next;free(delndoe);if(NULL==q->front){q->rear=NULL;}}q->size--; } // 獲取隊列頭部元素 QDataType QueueFront(Queue* q) {assert(!QueueEmpty(q));return q->front->data; } // 獲取隊列隊尾元素 QDataType QueueBack(Queue* q) {assert(!QueueEmpty(q));return q->rear->data; } // 獲取隊列中有效元素個數 int QueueSize(Queue* q) {assert(!QueueEmpty(q));return q->size; } // 檢測隊列是否為空,如果為空返回非零結果,如果非空返回0 int QueueEmpty(Queue* q) {assert(q);return NULL==q->front; } // 銷毀隊列 void QueueDestroy(Queue* q) {assert(q);QNode *cur=q->front;while(cur){q->front=cur->next;free(cur);cur=q->front;}q->rear=NULL;q->size=0; }/ void TestQueue() {Queue q;QueueInit(&q);QueuePush(&q, 1);QueuePush(&q, 2);QueuePush(&q, 3);QueuePush(&q, 4);QueuePush(&q, 5);printf("%d\n", QueueFront(&q));printf("%d\n", QueueBack(&q));printf("%d\n", QueueSize(&q));QueuePop(&q);QueuePop(&q);QueuePop(&q);printf("%d\n", QueueFront(&q));printf("%d\n", QueueBack(&q));printf("%d\n", QueueSize(&q));QueuePop(&q);QueuePop(&q);QueuePop(&q);if(QueueEmpty(&q)){printf("隊列已經為空\n");}else{printf("隊列不為空\n");}QueueDestroy(&q); }

main.c

#include"Queue.h"int main() {TestQueue();return 0; }

三、環形隊列

假溢出問題

??正常順序隊列若進行插入和刪除,會使前部分的空間浪費,從而造成假溢出的情況。

??未解決假溢出的問題,大佬們提出了一種叫做環形隊列的結構,環形隊列可以使用數組實現,也可以使用循環鏈表實現。

??判斷循環隊列是否為空或者滿的問題,通常用(rear-front+N)%N的方法判斷是否為滿或空。

總結

以上是生活随笔為你收集整理的栈和队列基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。