github仓库:https://github.com/EanoJiang/Data-structures-and-algorithms
栈与队列
栈(stack)
类比成一摞盘子,最上面的盘子就是栈顶,最下面的就是栈底。把元素添加到栈顶是入栈,删除栈顶就是出栈。
“先入后出"
顺序实现
栈的结构
- #define MAXSIZE 100
- typedef int ElemType;
- typedef struct {
- ElemType data[MAXSIZE];
- int top;
- } Stack;
复制代码 栈的初始化
- // 初始化栈
- void initStack(Stack *s) {
- s->top = -1;
- }
复制代码 栈的常用操作
入栈
- //入栈
- int push(Stack *s, ElemType e){
- if(s->top == MAXSIZE-1){
- printf("栈满\n");
- return 0;
- }
- s->top++;
- //从栈顶入栈
- s->data[s->top] = e;
- return 1;
- }
复制代码 出栈
- //出栈
- ElemType pop(Stack *s,ElemType *e){
- if(s->top == -1){
- printf("栈空\n");
- return 0;
- }
- *e = s->data[s->top];
- s->top--;
- return *e;
- }
复制代码 查看栈顶元素
- //查看栈顶元素
- ElemType getTop(Stack *s,ElemType *e){
- if(s->top == -1){
- printf("栈空\n");
- return 0;
- }
- *e = s->data[s->top];
- return *e;
- }
复制代码- int main(){
- Stack s;
- initStack(&s);
- push(&s,1);
- push(&s,2);
- push(&s,3);
- ElemType elem;
- getTop(&s,&elem);
- printf("栈顶元素:%d\n",elem);
- pop(&s,&elem);
- printf("出栈元素:%d\n",elem);
- printf("栈顶元素:%d\n",getTop(&s,&elem));
- return 0;
- }
复制代码 顺序表_动态分配
- #include #include #define MAXSIZE 100typedef int ElemType;typedef struct { ElemType *data; int top;} Stack;// 初始化栈Stack* initStack() { Stack *s = (Stack*)malloc(sizeof(Stack)); s->data = (ElemType*)malloc(MAXSIZE * sizeof(ElemType)); s->top = -1; return s;}//入栈
- int push(Stack *s, ElemType e){
- if(s->top == MAXSIZE-1){
- printf("栈满\n");
- return 0;
- }
- s->top++;
- //从栈顶入栈
- s->data[s->top] = e;
- return 1;
- }//出栈
- ElemType pop(Stack *s,ElemType *e){
- if(s->top == -1){
- printf("栈空\n");
- return 0;
- }
- *e = s->data[s->top];
- s->top--;
- return *e;
- }//查看栈顶元素
- ElemType getTop(Stack *s,ElemType *e){
- if(s->top == -1){
- printf("栈空\n");
- return 0;
- }
- *e = s->data[s->top];
- return *e;
- }int main(){ Stack *s = initStack(); push(s,1); push(s,2); push(s,3); ElemType elem; getTop(s,&elem); printf("栈顶元素:%d\n",elem); pop(s,&elem); printf("出栈元素:%d\n",elem); printf("栈顶元素:%d\n",getTop(s,&elem)); free(s->data); free(s); return 0;}
复制代码 链式实现
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- typedef int ElemType;
- typedef struct Stack{
- ElemType data;
- struct Stack *next;
- }Stack;
- Stack* initStack(){
- Stack *s = (Stack*)malloc(sizeof(Stack));
- s->next = NULL;
- return s;
- }
- //判断栈是否为空
- bool isEmpty(Stack *s){
- return s->next == NULL;
- }
- //入栈
- //头插法
- int push(Stack *s, ElemType e){
- Stack *p = (Stack*)malloc(sizeof(Stack));
- p->data = e;
- p->next = s->next;
- s->next = p;
- return 1;
- }
- //出栈
- //删去头结点的next
- ElemType pop(Stack *s, ElemType *e){
- if(s->next == NULL){
- printf("栈为空!\n");
- return 0;
- }
- *e = s->next->data;
- Stack *p = s->next;
- s->next = p->next;
- free(p);
- return *e;
- }
- //获取栈顶元素
- ElemType getTop(Stack *s){
- if(s->next == NULL){
- printf("栈为空!\n");
- return 0;
- }
-
- return s->next->data;
- }
- int main(){
- Stack *s = initStack();
- push(s,1);
- push(s,2);
- push(s,3);
- printf("栈顶元素:%d\n",getTop(s));
- ElemType elem;
- pop(s,&elem);
- printf("出栈元素:%d\n",elem);
- printf("栈顶元素:%d\n",getTop(s));
- free(s);
- return 0;
-
- }
复制代码 队列(queue)
先入先出
入队:队尾入队
出队:队首出队
顺序实现
队列结构
- #define MAXSIZE 100
- typedef int ElemType;
- typedef struct{
- ElemType data[MAXSIZE];
- int front, rear;
- }Queue;
复制代码 初始化
- int initQueue(){
- Queue *q = (Queue*)malloc(sizeof(Queue));
- if(q == NULL){
- return -1;
- }
- q->front = 0;
- q->rear = 0;
- return q;
- }
复制代码 判断是否为空
- bool isEmpty(Queue *q){
- return q->front == q->rear;
- }
复制代码 出队
- //出队
- //从队首出队
- ElemType pop(Queue *q,ElemType *e){
- if(isEmpty(q)){
- printf("队列为空!\n");
- return -1;
- }
- *e = q->data[q->front];
- q->front++;
- return *e;
- }
复制代码 入队
- //队首是空
- bool frontIsEmpty(Queue *q){
- if(q->front == 0){
- printf("队首不空\n");
- return 0;
- }
- //队首索引不为0,说明前面有空的位置,需要挪过去
- else{
- int step = q->front;
- for(int i = q->front;i <= q->rear;i++){
- q->data[i-step] = q->data[i];
- }
- q->front = 0;
- q->rear = q->rear - step;
- return 1;
- }
-
- }
- //入队
- //从队尾入队
- int push(Queue *q, ElemType e){
- //队尾到头的情况下,队首不空,说明队列已满
- if(q->rear == MAXSIZE-1 && !frontIsEmpty(q)){
- printf("队列已满!\n");
- return 0;
- }
- q->data[q->rear] = e;
- q->rear++;
- return 1;
- }
复制代码 获取队首元素
- //获取队首元素
- ElemType getFront(Queue *q){
- if(isEmpty(q)){
- printf("队列为空!\n");
- return -1;
- }
- return q->data[q->front];
- }
复制代码- int main(){
- Queue* q = initQueue();
- push(q,1);
- push(q,2);
- push(q,3);
- push(q,4);
- printf("队首元素为:%d\n",getFront(q));
- ElemType e;
- pop(q,&e);
- printf("出队元素为:%d\n",e);
- pop(q,&e);
- printf("出队元素为:%d\n",e);
- return 0;
- }
复制代码 顺序实现_动态内存分配
只有结构体和初始化的区别,其他都一样- typedef struct
- {
- ElemType *data;
- ElemType front, rear;
- } Queue;
- Queue *initQueue()
- {
- Queue *q = (Queue *)malloc(sizeof(Queue));
- q->data = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
- q->front = 0;
- q->rear = 0;
- return q;
- }
复制代码 循环队列
- #include #include #include // 最大容量#define MAXSIZE 4typedef int ElemType;typedef struct
- {
- ElemType *data;
- ElemType front, rear;
- } Queue;
- Queue *initQueue()
- {
- Queue *q = (Queue *)malloc(sizeof(Queue));
- q->data = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
- q->front = 0;
- q->rear = 0;
- return q;
- }int count = 0;bool isEmpty(Queue *q){ return count == 0 && q->rear == q->front;}// 入队// 从队尾入队int push(Queue *q, ElemType e){ // 队列满的时候,rear+1 == MAXSIZE,因为rear和front都是从0开始计数的 if (count == MAXSIZE && (q->rear + 1) % MAXSIZE == q->front) { printf("队列已满!\n"); return -1; } q->data[q->rear] = e; //更新rear索引 q->rear = (q->rear + 1) % MAXSIZE; count++; printf("当前的元素个数为:%d\n",count); return 1;}// 出队// 从队首出队ElemType pop(Queue *q, ElemType *e){ if (isEmpty(q)) { printf("队列为空!\n"); return -1; } *e = q->data[q->front]; //更新front索引 q->front = (q->front + 1) % MAXSIZE; count--; printf("当前的元素个数为:%d\n",count); return *e;}// 获取队首元素ElemType getFront(Queue *q){ if (isEmpty(q)) { printf("队列为空!\n"); return -1; } return q->data[q->front];}int main()
- {
- Queue *q = initQueue();
- push(q, 1);
- push(q, 2);
- push(q, 3);
- push(q, 4);
- printf("队首元素为:%d\n", getFront(q));
- ElemType e;
- pop(q, &e);
- printf("出队元素为:%d\n", e);
- pop(q, &e);
- printf("出队元素为:%d\n", e);
- return 0;
- }
复制代码 定义一个count变量用来记录当前元素的总个数,防止循环队列总是存不满的情况
也就是下面的情况:
rear总是指向队尾的下一个索引,那么满队列判断的时候1==1,满了,但实际没满,所以再加一个变量count的判断
链式实现
队列结构
- // 最大容量
- typedef int ElemType;
- // 队列节点
- typedef struct QueueNode
- {
- ElemType data;
- struct QueueNode *next;
- } QueueNode;
- // 队列
- typedef struct{
- QueueNode *front;
- QueueNode *rear;
- }Queue;
复制代码 初始化
- Queue* initQueue()
- {
- QueueNode *qNode = (QueueNode *)malloc(sizeof(QueueNode));
- qNode->data = 0;
- qNode->next = NULL;
- Queue *q = (Queue *)malloc(sizeof(Queue));
- q->front = qNode;
- q->rear = qNode;
- return q;
- }
复制代码 队列是否空
- // 队列是否为空
- bool isEmpty(Queue *q)
- {
- return q->rear == q->front;
- }
复制代码 入队
尾插法
- // 入队
- // 从队尾入队
- // 尾插法
- int push(Queue *q, ElemType e)
- {
- QueueNode *qNode = (QueueNode *)malloc(sizeof(QueueNode));
- qNode->data = e;
- qNode->next = NULL;
- //插在尾节点的next
- q->rear->next = qNode;
- q->rear = qNode;
- return 1;
- }
复制代码 出队
- // 出队
- // 从队首出队
- ElemType pop(Queue *q, ElemType *e)
- {
- QueueNode *qnode = q->front->next;
- *e = qnode->data;
- q->front->next = qnode->next;
- if(q->rear == qnode){
- q->rear = q->front;
- }
- free(qnode);
- return *e;
- }
复制代码 队首元素
- // 获取队首元素
- ElemType getFront(Queue *q)
- {
- if (isEmpty(q))
- {
- printf("队列为空!\n");
- return -1;
- }
- return q->front->next->data;
- }
复制代码- int main()
- {
- Queue *q = initQueue();
- push(q, 1);
- push(q, 2);
- push(q, 3);
- push(q, 4);
- printf("队首元素为:%d\n", getFront(q));
- ElemType e;
- pop(q, &e);
- printf("出队元素为:%d\n", e);
- pop(q, &e);
- printf("出队元素为:%d\n", e);
- return 0;
- }
复制代码 双端队列
习题1
选c
习题2
选d
习题3
选c
习题4
4个
dcbae
dcbea
dceba
decba
习题5
入队更新:
front指向队头
rear = (rear+1)%MAXSIZE
下面对每个选项进行验证,注意初始为空队列,front==rear:
a. rear递增后为1,错误
d.rear递增后为0,正确
选d
习题6
只有3不可能,n-1
习题7
选a
循环队列,队空条件: front == rear, 队满条件: front == (rear+1)%MAXSIZE
习题8
队列
98
7654
32
1
选c
习题9
入栈次序不能决定出栈顺序,栈不能两端操作,选c
习题10
注意栈顶位置
5 8 3 2(top) 2+3
8 3 2 5(top) 5-2
3 2 5 3(top) 3*5
2 5 3 15(top)
习题11
选c
习题12
选d
总结
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |