c数据结构 -- 栈与队列
栈和队列
·栈和队列是两种常用的、重要的数据结构
·栈和队列是限定插入和删除只能在表的“端点”进行的线性表
栈
只能在队尾插入,只能在队尾删除 -- 后进后出
表尾称为栈顶;表头称为栈底
插入元素到栈顶(即表尾)的操作,称为入栈
从栈顶删除最后一个元素的操作,称为出栈
注意:函数调用的流程就是入栈和出栈的实现,遵循后调用的先返回
队列
只能在队尾插入,只能在对队头删除 -- 先进先出
顺序栈的实现:
#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define MAXSIZE 100 typedef struct Stack{ // 顺序栈,存储类型为int int *base; // 指向底部 int *top; // 指向顶部 int length; }Stack; typedef Stack *SqStack; int initStack(SqStack *s); int isEmpty(SqStack s); int showStack(SqStack s); int push(SqStack *s,int num); int pop(SqStack *s); // 顺序栈的算法 int main(void){ SqStack s = (SqStack)malloc(sizeof(Stack)); initStack(&s); printf("顺序栈为空:%d \n",isEmpty(s)); printf("顺序栈长度:%d \n",getLength(s)); push(&s,1); push(&s,2); push(&s,3); pop(&s); showStack(s); } // 遍历栈 int showStack(SqStack s){ while(s->top > s->base){ printf("值:%d \n", *(s->top-1)); s->top--; } return OK; } // 入栈 int push (SqStack *s,int num){ // 判断是否上溢 if( getLength(*s) >= (*s)->length ) { printf("上溢 \n"); return ERROR; } *(*s)->top++ = num; return OK; } // 出栈 int pop(SqStack *s){ // 判断是否下溢 if(getLength(*s) <= 0){ printf("下溢 \n"); return ERROR; } (*s)->top--; //free(temp); return OK; } // 求长度 int getLength(SqStack s) { int length = s->top - s->base; // 指针相减,结果为值的个数 return length; } // 判断是否为空 int isEmpty(SqStack s){ if(s->top == s->base){ return OK; }else{ return ERROR; } } // 构造一个空栈 int initStack(SqStack *s){ (*s)->base = (int*)malloc(sizeof(int)); if(!(*s)->base){ return ERROR; // 内存分配失败 } (*s)->top = (*s)->base; // 栈顶指针等于栈底指针 (*s)->length = MAXSIZE; return OK; }
链栈的实现:
#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define MAXSIZE 100 typedef struct Stack{ // 链栈,存储类型为int int x; struct Stack *next; // 指向的是最后一个元素,入栈出栈都是它 if != NULL }Stack; typedef Stack *SqStack; int initStack(SqStack *s); int isEmpty(SqStack s); int showStack(SqStack s); int push(SqStack *s,int num); int pop(SqStack *s); // 链栈的算法 int main(void){ SqStack s = (SqStack)malloc(sizeof(Stack)); initStack(&s); printf("链栈为空:%d \n",isEmpty(s)); printf("链栈长度:%d \n",getLength(s)); push(&s,1); push(&s,2); push(&s,3); pop(&s); showStack(s); } // 遍历栈 int showStack(SqStack s){ while(s) { printf("值:%d \n", s->x); s = s->next; } return OK; } // 入栈 int push (SqStack *s,int num){ SqStack temp = (SqStack)malloc(sizeof(Stack)); temp->x = num; temp->next = (*s); // 精髓之处 (*s) = temp; // !!! 指针的运用 return OK; } // 出栈 int pop(SqStack *s){ // 判断是否下溢 if(!(*s)){ printf("下溢 \n"); return ERROR; } SqStack temp = *s; (*s) = (*s)->next; free(temp); // 释放内存 return OK; } // 求长度 int getLength(SqStack s) { int length = 0; while(s){ length++; s = s->next; } return length; } // 判断是否为空 int isEmpty(SqStack s){ if(!s){ return OK; }else{ return ERROR; } } // 构造一个空栈 int initStack(SqStack *s){ // 构建一个空栈,栈顶指针置为空 *s = NULL; return OK; }
循环顺序队列的实现:
#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define MAXSIZE 100 // 最大队列长度 // 建立顺序队列类型 typedef struct{ int a[MAXSIZE]; int front; // 队头 int rear; // 队尾 }SqQueue; // 展示 void display(SqQueue sq) { int i=sq.front; if(sq.front==sq.rear) { printf("none\n"); return ; } while(i!=sq.rear) { printf("%5d",sq.a[i]); i++; i=i%MAXSIZE; } printf("\n"); } // 队列的初始化 int init(SqQueue *q){ q->front = 0; q->rear = 0; } // 入队 void insert(SqQueue *sq,int x) { if((sq->rear+1)%MAXSIZE==sq->front) { printf("full\n"); return ; } sq->a[sq->rear]=x; sq->rear=(sq->rear+1)%MAXSIZE; printf("front = %d\n",sq->front); printf("rear = %d\n",sq->rear); } // 出队 void del(SqQueue *sq) { if(sq->front==sq->rear) { printf("none\n"); return ; } sq->front=(sq->front+1)%MAXSIZE; printf("front = %d\n",sq->front); printf("rear = %d\n",sq->rear); } int main(void){ SqQueue q; init(&q); insert(&q,3); insert(&q,4); del(&q); insert(&q,5); insert(&q,6); display(q); }