队列(纯C语言实现)
生活随笔
收集整理的這篇文章主要介紹了
队列(纯C语言实现)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
先進先出的線性表,從隊尾rear進,從隊頭front出
1.隊列的順序存儲結構及實現
補充:判斷循環隊列隊滿和隊空的三種方法
由于隊滿和對空時都有front==rear,所以需要另想方法來區分隊滿和隊空
方法一:通過length的大小來判斷
隊空的條件為length==0
隊滿的條件為length==MAXSIZE
方法二:少用一個元素空間
隊空的條件為front==rear
隊滿的條件為(rear+1)%MAXSIZE==front
方法三:設置一個標志變量flag
隊空時flag==0,隊不空時flag==1
隊空的條件為flag==0
隊滿的條件為front==rear&&flag==1
1.1 循環隊列的存儲結構
方法一:
typedef struct {ElemType data[MAXSIZE];int front; //指向隊頭元素int rear; //指向隊尾元素的下一個位置int length; }SqQueue;方法二:
typedef struct {ElemType data[MAXSIZE];int front; int rear; }SqQueue;方法三:
typedef struct {ElemType data[MAXSIZE];int front; int rear;int flag; }SqQueue;1.2 循環隊列的基本操作
1.初始化InitQueue(Q)
方法一:
Status InitQueue(SqQueue *Q) {Q->front=Q->rear=0;Q->length=0;return OK; }方法二:
Status InitQueue(SqQueue *Q) {Q->front=Q->rear=0;return OK; }方法三:
Status InitQueue(SqQueue *Q) {Q->front=Q->rear=0;Q->flag=0;return OK; }2.判斷是否隊空QueueEmpty(Q)
方法一:
Status QueueEmpty(SqQueue Q) {if(Q.length==0) return TRUE;else return ERROR; }方法二:
Status QueueEmpty(SqQueue Q) { if(Q.front==Q.rear)return TRUE;elsereturn FALSE; }方法三:
Status QueueEmpty(SqQueue Q) { if(Q.flag==0)return TRUE;elsereturn FALSE; }3.銷毀DestroyQueue(Q)
與清空ClearQueue(Q)相同
4.清空ClearQueue(Q)
方法一:
Status ClearQueue(SqQueue *Q) {Q->front=Q->rear=Q->length=0;return OK; }方法二:
Status ClearQueue(SqQueue *Q) {Q->front=Q->rear=0;return OK; }方法三:
Status ClearQueue(SqQueue *Q) {Q->front=Q->rear=Q->flag=0;return OK; }5.求長度QueueLength(Q)
方法一:
int QueueLength(SqQueue Q) {return Q.length; }方法二:
int QueueLength(SqQueue Q) {return (Q.rear-Q.front+MAXSIZE)%MAXSIZE; }方法三:(同方法二)
6.取隊頭元素GetHead(Q,e)
方法一:
Status GetHead(SqQueue Q,ElemType *e) {if(Q.length==0)return ERROR;*e=Q.data[Q.front];return OK; }方法二:
Status GetHead(SqQueue Q,ElemType *e) {if(Q.front==Q.rear)return ERROR;*e=Q.data[Q.front];return OK; }方法三:
Status GetHead(SqQueue Q,ElemType *e) {if(Q.flag==0)return ERROR;*e=Q.data[Q.front];return OK; }7.入隊列(插入隊尾)EnQueue(Q,e)
方法一:
Status EnQueue(SqQueue *Q,ElemType e) {if(Q->length==MAXSIZE)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE; //隊尾指針指向下一個位置 Q->length++;return OK; }方法二:
Status EnQueue(SqQueue *Q,ElemType e) {if ((Q->rear+1)%MAXSIZE == Q->front)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;return OK; }方法三:
Status EnQueue(SqQueue *Q,ElemType e) {if(Q->front==Q->rear&&Q->flag==1)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;Q->flag=1;return OK; }8.出隊列(刪除隊頭)DeQueue(Q,e)
方法一:
Status DeQueue(SqQueue *Q,ElemType *e) {if(Q->length==0) return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;Q->length--;return OK; }方法二:
Status DeQueue(SqQueue *Q,ElemType *e) {if (Q->front == Q->rear)return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;return OK; }方法三:
Status DeQueue(SqQueue *Q,ElemType *e) {if(Q->flag==0) return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;if(Q->front==Q->rear)Q->flag=0;return OK; }9.遍歷QueueTraverse(Q)
Status visit(ElemType e) {printf("%d ",e);return OK; }方法一:
Status QueueTraverse(SqQueue Q) {int i,t;t=Q.front;for(i=0;i<Q.length;i++){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK; }方法二:
Status QueueTraverse(SqQueue Q) { int t;t=Q.front;while(t!=Q.rear){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK; }方法三:
Status QueueTraverse(SqQueue Q) { int i,t;t=Q.front;for(i=0;i<QueueLength(Q);i++){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK; }1.3 循環隊列的綜合實例
#include<stdio.h>#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 15typedef int Status; typedef int ElemType;typedef struct {ElemType data[MAXSIZE];int front; int rear;int flag; //隊空時flag==0,隊不空時flag==1 }SqQueue;Status InitQueue(SqQueue *Q) {Q->front=Q->rear=0;Q->flag=0;return OK; }int QueueLength(SqQueue Q) {return (Q.rear-Q.front+MAXSIZE)%MAXSIZE; }Status visit(ElemType e) {printf("%d ",e);return OK; }Status QueueTraverse(SqQueue Q) { int i,t;t=Q.front;for(i=0;i<QueueLength(Q);i++){visit(Q.data[t]);t=(t+1)%MAXSIZE;}printf("\n");return OK; }Status EnQueue(SqQueue *Q,ElemType e) {if(Q->front==Q->rear&&Q->flag==1)return ERROR;Q->data[Q->rear]=e;Q->rear=(Q->rear+1)%MAXSIZE;Q->flag=1;return OK; }Status DeQueue(SqQueue *Q,ElemType *e) {if(Q->flag==0) return ERROR;*e=Q->data[Q->front];Q->front=(Q->front+1)%MAXSIZE;if(Q->front==Q->rear)Q->flag=0;return OK; }Status GetHead(SqQueue Q,ElemType *e) {if(Q.flag==0)return ERROR;*e=Q.data[Q.front];return OK; }Status QueueEmpty(SqQueue Q) { if(Q.flag==0)return TRUE;elsereturn FALSE; }void menu() {printf(" ********循環隊列功能菜單********** \n");printf(" 1.初始化 ");printf("2.輸出棧中各結點的值\n");printf(" 3.入隊列 ");printf("4.出隊列\n");printf(" 5.查看隊頭元素 ");printf("6.是否為空隊列\n");printf(" 7.退出\n"); }int main() {int i,n;int choice=0;SqQueue Q;ElemType e;InitQueue(&Q);menu();while(choice!=7){printf("請選擇功能:\n");scanf("%d",&choice);switch(choice){case 1: if(InitQueue(&Q)){printf("初始化成功\n");}break;case 2:if(QueueEmpty(Q)){printf("隊列為空!\n");}else{printf("遍歷結果如下:\n");QueueTraverse(Q); }break;case 3:printf("請輸入你要入隊列的元素:\n"); scanf("%d",&e);if(EnQueue(&Q,e)){printf("入隊列成功\n");}else{printf("隊列已滿,入隊列失敗\n");}break;case 4:if(DeQueue(&Q,&e)){printf("出隊列成功,出隊列元素為%d\n",e);}else{printf("隊列為空,出隊列失敗\n");}break;case 5:if(GetHead(Q,&e))printf("隊頭元素是%d\n",e);elseprintf("該隊列為空,無隊頭元素\n");break;case 6:if(QueueEmpty(Q)){printf("當前隊列為空\n");}else{printf("當前隊列不為空\n");}break;case 7:printf("******************END**********************\n");break;}}return 0; }2.隊列的鏈式存儲結構及實現
1.1 鏈隊列的存儲結構
有頭結點的鏈隊列
typedef struct QNode {ElemType data;struct QNode *next; }QNode; typedef struct {QNode *front,*rear;int length; }LinkQueue;1.2 鏈隊列的基本操作
1.初始化InitQueue(Q)
生成一個空的鏈隊列,front和rear都指向頭結點
Status InitQueue(LinkQueue *Q) {Q->front=Q->rear=(QNode*)malloc(sizeof(QNode)); //生成頭結點if(!Q->front)exit(OVERFLOW);Q->front->next=NULL;Q->length=0;return OK; }2.判斷是否隊空QueueEmpty(Q)
Status QueueEmpty(LinkQueue Q) { if(Q.length==0) //判斷條件也可以是Q.front==Q.rearreturn TRUE;elsereturn FALSE; }3.銷毀DestroyQueue(Q)
銷毀包括頭結點在內的所有節點,使front和rear指向NULL
Status DestroyQueue(LinkQueue *Q) {while(Q->front){Q->rear=Q->front->next;free(Q->front);Q->front=Q->rear;}Q->length=0;return OK; }4.清空ClearQueue(Q)
只保留一個頭結點
Status ClearQueue(LinkQueue *Q) {QNode *p,*q;Q->rear=Q->front;p=Q->front->next;Q->front->next=NULL;while(p){q=p;p=p->next;free(q);}Q->length=0;return OK; }5.求長度QueueLength(Q)
int QueueLength(LinkQueue Q) {return Q.length; }6.取隊頭元素GetHead(Q,e)
Status GetHead(LinkQueue Q,ElemType *e) { QNode *p;if(Q.length==0) //判斷條件也可以是Q.front==Q.rearreturn ERROR;p=Q.front->next;*e=p->data;return OK; }7.入隊列(插入隊尾)EnQueue(Q,e)
Status EnQueue(LinkQueue *Q,ElemType e) {QNode *p=(QNode *)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e;Q->rear->next=p;p->next=NULL;Q->rear=p; //修改rear指針 Q->length++;return OK; }8.出隊列(刪除隊頭)DeQueue(Q,e)
Status DeQueue(LinkQueue *Q,ElemType *e) {QNode *p;if(Q->length==0) //判斷條件也可以是Q->front==Q->rearreturn ERROR;p=Q->front->next;*e=p->data;Q->front->next=p->next;if(Q->rear==p) //若p結點是隊尾元素,則刪除p后變為空隊列,需將rear指向頭結點 Q->rear=Q->front;free(p);Q->length--;return OK; }9.遍歷QueueTraverse(Q)
Status visit(ElemType e) {printf("%d ",e);return OK; } Status QueueTraverse(LinkQueue Q) {QNode *p;p=Q.front->next;while(p){visit(p->data);p=p->next;}printf("\n");return OK; }1.3 鏈隊列的綜合實例
#include<stdio.h> #include<stdlib.h>#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 typedef int Status; typedef int ElemType;//先定義結點 typedef struct QNode {ElemType data;struct QNode *next; }QNode; //再定義鏈隊列 typedef struct {QNode *front,*rear;int length; }LinkQueue;//初始化:生成一個空的鏈隊列,front和rear都指向頭結點 Status InitQueue(LinkQueue *Q) {Q->front=Q->rear=(QNode*)malloc(sizeof(QNode)); //生成頭結點if(!Q->front)exit(OVERFLOW);Q->front->next=NULL;Q->length=0;return OK; }//清空:只保留一個頭結點,其余結點都釋放 Status ClearQueue(LinkQueue *Q) {QNode *p,*q;Q->rear=Q->front;p=Q->front->next;Q->front->next=NULL;while(p){q=p;p=p->next;free(q);}Q->length=0;return OK; }//輸出元素 Status visit(ElemType e) {printf("%d ",e);return OK; } //遍歷輸出 Status QueueTraverse(LinkQueue Q) {QNode *p;p=Q.front->next;while(p){visit(p->data);p=p->next;}printf("\n");return OK; }Status QueueEmpty(LinkQueue Q) { if(Q.length==0) //判斷條件也可以是Q.front==Q.rearreturn TRUE;elsereturn FALSE; }Status GetHead(LinkQueue Q,ElemType *e) { QNode *p;if(Q.length==0) //判斷條件也可以是Q.front==Q.rearreturn ERROR;p=Q.front->next;*e=p->data;return OK; }Status EnQueue(LinkQueue *Q,ElemType e) {QNode *p=(QNode *)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e;Q->rear->next=p;p->next=NULL;Q->rear=p; //修改rear指針 Q->length++;return OK; }Status DeQueue(LinkQueue *Q,ElemType *e) {QNode *p;if(Q->length==0) //判斷條件也可以是Q->front==Q->rearreturn ERROR;p=Q->front->next;*e=p->data;Q->front->next=p->next;if(Q->rear==p) //若p結點是隊尾元素,則刪除p后變為空隊列,需將rear指向頭結點 Q->rear=Q->front;free(p);Q->length--;return OK; }void menu() {printf(" ********鏈隊列功能菜單******** \n");printf(" 1.初始化 ");printf("2.輸出棧中各結點的值\n");printf(" 3.入隊列 ");printf("4.出隊列\n");printf(" 5.查看隊頭元素 ");printf("6.是否為空隊列\n");printf(" 7.退出\n"); }int main() {int choice=0;LinkQueue Q;ElemType e;InitQueue(&Q);menu();while(choice!=7){printf("請選擇功能:\n");scanf("%d",&choice);switch(choice){case 1: if(ClearQueue(&Q)){printf("初始化成功\n");}break;case 2:if(QueueEmpty(Q)){printf("隊列為空!\n");}else{printf("遍歷結果如下:\n");QueueTraverse(Q); }break;case 3:printf("請輸入你要入隊列的元素:\n"); scanf("%d",&e);if(EnQueue(&Q,e)){printf("入隊列成功\n");}break;case 4:if(DeQueue(&Q,&e)){printf("出隊列成功,出隊列元素為%d\n",e);}else{printf("隊列為空,出隊列失敗\n");}break;case 5:if(GetHead(Q,&e))printf("隊頭元素是%d\n",e);elseprintf("該隊列為空,無隊頭元素\n");break;case 6:if(QueueEmpty(Q)){printf("當前隊列為空\n");}else{printf("當前隊列不為空\n");}break;case 7:printf("******************END**********************\n");break;}}return 0; }總結
以上是生活随笔為你收集整理的队列(纯C语言实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Udacity数据分析(入门)-TMDb
- 下一篇: 使用pgd和fgsm方法进行攻击并使用m