数据结构栈ADT和队列ADT

本文介绍了数据结构中的栈和队列抽象数据类型(ADT),包括栈的链表和数组实现,以及队列的数组和链表实现。栈遵循LIFO(后进先出)原则,常用操作为Push和Pop;队列则采用FIFO(先进先出)原则,基本操作为Enqueue和Dequeue。两种数据结构在链表和数组实现中都能达到O(1)的运行时间效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.3.1 栈模型

栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫栈顶(top)。对栈的基本操作有Push(进栈)和Pop(出栈),前者相当于插入,后者则是删除最后插入的元素。最后插入的元素可以通过使用Top例程在执行Pop之前进行检查。对空栈进行的Pop或Top一般被认为是栈ADT的错误。另一方面,当运行Push时空间用尽是一个实现错误,但不是ADT错误。

栈有时又叫做LIFO(Last in first out)(后进先出)表。

图3-38表示在进行若干操作后的一个抽象的栈。一般的模型是,存在某个元素位于栈顶,而该元素是唯一的可见元素。

栈的链表实现

栈的第一种实现方法是使用单链表。我们通过在表前端插入来实现Push,通过删除表前端元素实现Pop。Top操作只是检测表前端元素并返回它的值。有时Pop操作和Top操作合二为一。缺点是对malloc和free的调用开销太大。

//stack.h
#ifndef STACK_H_
#define STACK_H_
 
typedef struct
{
    char str[10];
    int numb;
}Item;
 
typedef struct node
{
    Item item;
    struct node* next;
} Node;
 
typedef struct
{
    Node* head;
}Stack;
 
/* 初始化栈         */
void STACKinit(Stack* pq);
 
/* 在头部添加栈     */
bool PushStack(Item a, Stack* pq);
 
/* 在头部推出栈     */
void PopStack(Stack* pq);
 
/* 遍历栈,输出栈的项*/
void Output(const Stack* pq);
 
#endif
 
//stack.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"STACK.h"
 
void STACKinit(Stack* pq)
{
    pq->head = NULL;
}
 
bool PushStack(Item a, Stack* pq)
{
    Node* New;
    Node* pp = pq->head;
 
    New = (Node*)malloc(sizeof(Node));
    if (New == NULL)
    {
        printf("没分配内存\n");
        return false;
    }
 
    New->item = a;
    
    if (a.numb == 0)   //判断是否为第一项,是的话New->next = NULL;
    {
        pq->head = New;
        New->next = NULL;
    }
    else
    {
        New->next = pq->head;
        pq->head = New;
    }
 
    return true;
}
 
void PopStack(Stack* pq)
{
    Node* old;
    old = pq->head;
    pq->head = pq->head->next;
    free(old);
}
 
void Output(const Stack* pq)
{
    if (pq->head == NULL)
    {
        printf("空栈!\n");
        return;
    }
 
    Node* pp = pq->head;
    printf("栈中的项:\n");
    while (pp != NULL)
    {
        printf("%s\n", pp->item.str);
        pp = pp->next;
    }
    printf("项数:%d\n", pq->head->item.numb);
}
//main.c
#include<stdio.h>
#include<string.h>
#include"STACK.h"
 
int main(void)
{
    Stack stack;
    Item strn;
    int i = 0;
    
    STACKinit(&stack);
 
    printf("输入0,退出 | 输入*:推出栈 | 输入l,查看栈\n");
 
    while (1)
    {
        strn.numb = i;
        scanf_s("%s", strn.str, 9);
        if (strcmp(strn.str, "0") == 0)
        {
            break;
        }
        else if (strcmp(strn.str, "l") == 0)
        {
            strn.numb = i;
            Output(&stack);
            continue;
        }
 
        if (strcmp(strn.str, "*") != 0)
        {
            i++;
            strn.numb = i;
            PushStack(strn, &stack);
            printf("推入成功!\n);
        }    
        else
        {
            i--;
            PopStack(&stack);
            printf("推出成功!\n);
        }
    }
 
    puts("Bye!");
 
    return 0;
}

栈的数组实现

需要提前声明数组的大小。

//stack.h
#ifndef _STACK_H
#define _STACK_H

#define N 10
typedef int data_type;

//顺序栈
typedef struct stack
{
    data_type arr[N]; //顺序连续大小固定
    int top; //top ==-1;空.top == N-1;满  top 表示栈顶的位置

}Stack;

enum op
{
    FULL = -3,
    EMPTY,
    NOEXIT,
    OK

};

//创建栈
//返回值:Stack * 顺序存储的首地址
S
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值