C语言---栈和队列

严格来说,栈和队列都属于线性表

"一对一"

栈:"先进后出"

队列: "先进先出"

  1. 栈只能从一端存取,另一端是封闭的

  2. 在栈中,不论是存还是取,都必须遵循"先进后出"的原则

==>栈是一种只能从表的一端存取数据,且遵循"先进后出"原则的线性存储结构

进栈和出栈

进栈:将数据存储到栈里面去

出栈:将数据从栈中间取出来

栈的实现方法

栈:有点"特殊"的线性存储结构

  1. 顺序表==>顺序栈 (顺序存储结构)

  2. 链表==>链栈 (链式存储结构)

顺序栈

#include <stdio.h> 
// ** 元素进栈 
// 参数: 存储结构,栈顶指针,数据 
// 返回值: 栈顶指针 
int pushElem(int* arr, int top, int val) 
{ 
    arr[++top] = val; 
    return top; 
}
// ** 元素出栈 
// 参数: 存储结构,栈顶指针 
// 返回值: 栈顶指针 
int popElem(int* arr, int top) 
{ 
    // 先判断 
    if (top <= -1) 
    { 
        printf("空栈!\n"); 
        return -1; 
    }
    printf("元素%d出栈\n",arr[top]); 
    top--; // 原来的数据还在 
    return top; 
}
​
int main() 
{ 
    // 数组 
    int a[100]; 
    // top指针(下标) 
    int top = -1; 
    // 入栈 
    top = pushElem(a, top, 1); 
    top = pushElem(a, top, 2); 
    top = pushElem(a, top, 3); 
    top = pushElem(a, top, 4);
    top = pushElem(a, top, 5); 
    // 出栈 
    top = popElem(a, top); 
    top = popElem(a, top); 
    top = popElem(a, top); 
    top = popElem(a, top); 
    top = popElem(a, top); 
    return 0; 
}

链栈

一般会将链表的头部作为栈顶,尾部作为栈底

#include <stdio.h> 
#include <stdlib.h> 
// 节点 
typedef struct Node 
{ 
    int data; 
    struct Node* pnext; 
}Node; 
// **添加元素 
// 参数: 头指针,数据 
// 返回值: 头指针 
Node* push(Node* stack, int a) 
{ 
    // 1 申请内存 
    Node* NewNode = (Node*)malloc(sizeof(Node)); 
    // 2 初始化节点的数据域 
    NewNode->data = a; 
    // 3 把新的节点作为新的头节点 
    NewNode->pnext = stack; 
    // 4 头指针指向新的头节点 
    stack = NewNode; 
    // 5 返回头指针 
    return stack; 
}
// **删除元素 
// 参数: 头指针 
// 返回值: 头指针 
Node* pop(Node* stack) 
{ 
    // 判断是否为空 
    if (stack) 
    { 
        // 临时指针保存栈顶(头指针) 
        Node* p = stack; 
        // 头指针后移 
        stack = stack->pnext; 
        // 打印一下数据
        printf("弹出原来栈顶元素:%d ", p->data); 
        // 再次判断一下是否到了栈底 
        if (stack) 
        { 
            printf("现在栈顶元素:%d\n", stack->data); 
        }
        else 
        { 
            printf("栈已经空了!\n"); 
        }
        // 释放节点 
        free(p); 
        p->pnext = NULL; 
    }
    else 
    { 
        printf("是一个空栈!\n"); 
    }
    return stack; 
}
​
int main() 
{ 
    Node* stack = NULL; 
    // 入栈 
    stack = push(stack, 1); 
    stack = push(stack, 2); 
    stack = push(stack, 3); 
    stack = push(stack, 4); 
    stack = push(stack, 5); 
    // 出栈 
    stack = pop(stack); 
    stack = pop(stack); 
    stack = pop(stack); 
    stack = pop(stack); 
    stack = pop(stack); 
    return 0; 
}

队列

队列的两端都"开口",要求:只能从一端进入队列,从另一端出队列

队头和队尾

队头: 数据出队列的一端

队尾: 数据进入队列的一端

队列的实现方法

  1. 顺序表==>顺序队列

  2. 链表==>链队列

顺序队列

#include <stdio.h> 
// **入队 
// 参数: 存储结构,队尾,数据 
// 返回值: 队尾 
int enQueue(int* a, int rear, int data) 
{ 
    // rear: 即将添加数据的位置 
    a[rear] = data; 
    rear++; 
    return rear; 
}
// **出队 
// 参数: 存储结构,队头,队尾 
// 返回值: 无 
void deQueue(int* a, int front, int rear) 
{ 
    // 如果 front == rear,表示队列为空 
    while (front != rear) 
    { 
        printf("出队元素:%d\n", a[front]); 
        front++;
    } 
}
​
int main() 
{ 
    // 数组 
    int a[100]; 
    // 队头和队尾 
    int front, rear; 
    // 当队列中没有元素的时候,队头和队尾是同一个地方 
    front = rear = 0; 
    // 入队 
    rear = enQueue(a, rear, 1); 
    rear = enQueue(a, rear, 2); 
    rear = enQueue(a, rear, 3); 
    rear = enQueue(a, rear, 4); 
    rear = enQueue(a, rear, 5); 
    // 出队 
    deQueue(a, front, rear); 
    return 0; 
}

缺点明显,应当改善

栈队列

#include <stdio.h> 
#include <stdlib.h> 
// 节点 
typedef struct QNode 
{ 
    int data; 
    struct QNode* next; 
}QNode; 
​
// 创建队列(头节点) 
QNode* initQueue()
{ 
    // 创建头节点 
    QNode* queue = (QNode*)malloc(sizeof(QNode)); 
    // 给值 
    queue->data = 0; // 这句可以不写 
    queue->next = NULL; 
    return queue; 
}
​
// 入队 
QNode* enQueue(QNode* rear, int data) 
{ 
    // 1 做一个新的节点 
    QNode* NewNode = (QNode*)malloc(sizeof(QNode)); 
    NewNode->data = data; 
    NewNode->next = NULL; 
    // 2 使用尾插法添加 
    rear->next = NewNode; 
    rear = NewNode; 
    return rear; 
}
// 出队 
QNode* deQueue(QNode* top, QNode* rear) 
{ 
    if (top->next == NULL) 
    { 
        printf("队列为空!\n"); 
        return rear; 
    }
    // 创建临时指针 
    QNode* p = top->next; 
    // 显示数据 
    printf("%d ", p->data); 
    // 断头,换头 p->next可能为NULL 
    top->next = p->next; 
    // 判断(是否即将只剩下一个节点) 
    if (rear == p) 
    { 
        rear = top; 
    }
    // 释放 
    free(p); 
    return rear; 
}
​
int main() 
{ 
    QNode* queue, *top, *rear; 
    queue = top = rear = initQueue(); 
    // 入队 
    rear = enQueue(rear, 1); 
    rear = enQueue(rear, 2); 
    rear = enQueue(rear, 3); 
    rear = enQueue(rear, 4);
    rear = enQueue(rear, 5); 
    // 出队 
    rear = deQueue(top, rear); 
    rear = deQueue(top, rear); 
    rear = deQueue(top, rear); 
    rear = deQueue(top, rear); 
    rear = deQueue(top, rear); 
    rear = deQueue(top, rear); 
    return 0; 
}
  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值