对栈的实现(顺序栈和链式栈)C语言

本文介绍了栈的两种实现方式——顺序栈和链式栈,分别基于静态顺序表和链表。详细阐述了函数结构体的声明和定义,并提供了相应的单元测试代码供读者参考和验证。

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

栈的实现

两种方法实现:

  • 顺序栈
    :基于静态顺序表
  • 链式栈
    :基于链表

    顺序栈

函数的结构体和声明

基于顺序表的栈,也就是用数组的增删查改
我们看结构体和声明
typedef char SeqType;

typedef struct SeqStack{
    size_t size;
    SeqType data[MAXREPOSITORY];
}SeqStack;

// 初始化。
void SeqStackInit(SeqStack *seq);

// 入栈。
void SeqStackPushStack(SeqStack *seq, SeqType value);

// 出栈。
void SeqStackPopStack(SeqStack *seq);

// 取栈顶元素。
int SeqStackFindTop(SeqStack *seq, SeqType *value);

// 销毁。
void SeqStackDestory(SeqStack *seq);

函数的定义

#include "SeqStack.h"

// 函数在初始化时候已经为其开辟空间所以这里是要初始化就行
// 初始化。
void SeqStackInit(SeqStack *seq)
{
    if (seq == NULL)
    {
        // 非法输入。
        return;
    }
    seq->size = 0;
}

// 这里的入栈就和顺序表的尾插一样,注意就是需要判断是否栈满
// 入栈。
void SeqStackPushStack(SeqStack *seq, SeqType value)
{
    if (seq == NULL)
    {
        return;
    }
    if (seq->size > MAXREPOSITORY)
    {
        return;
    }
    seq->data[seq->size] = value;
    ++seq->size;
}

// 打印栈。
void PrintSeqStack(SeqStack *seq)
{
    if (seq == NULL)
    {
        return;
    }
    printf("栈底->");
    size_t i = 0;
    for (; i<seq->size; ++i)
    {
        printf("[%c]->",seq->data[i]);
    }
    printf("栈顶\n");
}

// 出栈需要注意栈是否为空
// 出栈。
void SeqStackPopStack(SeqStack *seq)
{
    if (seq == NULL)
    {
        // 非法输入。
        return;
    }
    if (seq->size == 0)
    {
        // 空顺序表。
        return;
    }
    --seq->size;
}


// 取栈顶元素。
int SeqStackFindTop(SeqStack *seq, SeqType *value)
{
    if (seq == NULL)
    {
        return 0;
    }
    if (seq->size == 0)
    {
        printf("栈为空栈。");
        // 空栈。
        return 0;
    }
    *value = seq->data[seq->size-1];
    return 1;
}


// 销毁。
void SeqStackDestory(SeqStack *seq)
{
    if (seq == NULL)
    {
        return;
    }
    seq->size = 0;
}

以下是代码的单元测试

/////////////////////
//测试代码
/////////////////////

// 初始化
void TestSeqStackInit()
{
    PRINTSEQSTACKNAME;
    SeqStack seq;
    SeqStackInit(&seq);
}

// 入栈。
void TestSeqStackPushStack()
{
    PRINTSEQSTACKNAME;
    SeqStack seq;
    SeqStackInit(&seq);
    SeqStackPushStack(&seq, 'a');
    SeqStackPushStack(&seq, 'b');
    SeqStackPushStack(&seq, 'c');
    SeqStackPushStack(&seq, 'd');
    PrintSeqStack(&seq);
}

// 出栈。
void TestSeqStackPopStack()
{
    PRINTSEQSTACKNAME;
    SeqStack seq;
    SeqStackInit(&seq);
    SeqStackPushStack(&seq, 'a');
    SeqStackPushStack(&seq, 'b');
    SeqStackPushStack(&seq, 'c');
    SeqStackPushStack(&seq, 'd');
    PrintSeqStack(&seq);
    SeqStackPopStack(&seq);
    PrintSeqStack(&seq);
    SeqStackPopStack(&seq);
    SeqStackPopStack(&seq);
    SeqStackPopStack(&seq);
    PrintSeqStack(&seq);
    SeqStackPopStack(&seq);
    PrintSeqStack(&seq);
}

// 取栈顶元素。
void TestSeqStackFindTop()
{
    PRINTSEQSTACKNAME;
    SeqStack seq;
    SeqStackInit(&seq);
    SeqStackPushStack(&seq, 'a');
    SeqStackPushStack(&seq, 'b');
    SeqStackPushStack(&seq, 'c');
    SeqStackPushStack(&seq, 'd');
    PrintSeqStack(&seq);
    SeqType ret = SeqStackFindTop(&seq);
    printf("except d actual %c\n",ret);
}

int main()
{
    TestSeqStackInit();
    TestSeqStackPushStack();
    TestSeqStackPopStack();
    TestSeqStackFindTop();
    return 0;
}

链式栈

函数的结构体和声明

函数结构体和链表节点的实现相同。

typedef char LinkType;

typedef struct LinkNode{
    LinkType data;
    struct LinkNode *next;
}LinkNode;

// 我采用的是带有单链表实现的栈
// 初始化。带头不带环单链表。
void LinkStackInit(LinkNode *head);

// 入栈。
void LinkStackPushStack(LinkNode *head, LinkType value);

// 出栈。
void LinkStackPopStack(LinkNode *head);

// 取栈顶元素。
int LinkStackFindTop(LinkNode *head, LinkType *value);

// 销毁。
void LinkStackDestory(LinkNode *head);

函数的定义

#include"LinkStack.h"


// 初始化。带头不带环单链表。
void LinkStackInit(LinkNode *head)
{
    if (head == NULL)
    {
        return;
    }
    head->next = NULL;
}

// 创建节点。
LinkNode *CreatNode(LinkType value)
{
    LinkNode *new_node = (LinkNode*)malloc(sizeof(LinkNode));
    if (new_node == NULL)
    {
        // 申请内存失败。
        return NULL;
    }
    new_node->data = value;
    new_node->next = NULL;
    return new_node;
}

// 这里可以看出直接在head后面插节点
// 入栈。
void LinkStackPushStack(LinkNode *head, LinkType value)
{
    if (head == NULL)
    {
        return;
    }
    LinkNode *new_node = CreatNode(value);
    if (new_node == NULL)
    {
        printf("内存申请失败。");
        // 返回值为NULL。
        return;
    }
    LinkNode *next = head->next;
    head->next = new_node;
    new_node->next = next;
}

// 出栈。
void LinkStackPopStack(LinkNode *head)
{
    if (head == NULL)
    {
        return;
    }
    if (head->next == NULL)
    {
        // 空栈。
        return;
    }
    LinkNode *delete = head->next;
    head->next = delete->next;
    free(delete);
}

// 这里要注意带头单链表取栈顶元素,是head的next节点。
// 取栈顶元素。
int LinkStackFindTop(LinkNode *head, LinkType *value)
{
    if (head == NULL)
    {
        return -1;
    }
    if (head->next == NULL)
    {
        return 0;
    }
    *value =  head->next->data;
    return 1;
}

// 销毁要遍历一个一个节点的释放。
// 销毁。
void LinkStackDestory(LinkNode *head)
{
    if (head == NULL)
    {
        return;
    }
    LinkNode *cur = head->next;
    while (cur != NULL)
    {
        LinkNode *next = cur->next;
        head->next = next;
        free(cur);
        cur = next;
    }
}

链式栈的单元测试

/////////////
//测试代码 
/////////////
#define LINKSTACKNAME printf("\n=========%s========\n",__FUNCTION__)
// 打印。
void PrintLinkStack(LinkNode *head)
{
    if (head == NULL)
    {
        return;
    }
    printf("(TOP)head->");
    LinkNode *cur = head->next;
    while (cur != NULL)
    {
        printf("[%c]->",cur->data);
        cur = cur->next;
    }
    printf("BOTTOM\n");
}

// 初始化。
void TestLinkStackInit()
{
    LINKSTACKNAME;
    LinkNode head;
    LinkStackInit(&head);
}

// 入栈。
void TestLinkStackPushStack()
{
    LINKSTACKNAME;
    LinkNode head;
    LinkStackInit(&head);
    LinkStackPushStack(&head,'a');
    LinkStackPushStack(&head,'b');
    LinkStackPushStack(&head,'c');
    LinkStackPushStack(&head,'d');
    PrintLinkStack(&head);
}

// 出栈。
void TestLinkStackPopStack()
{
    LINKSTACKNAME;
    LinkNode head;
    LinkStackInit(&head);
    LinkStackPushStack(&head,'a');
    LinkStackPushStack(&head,'b');
    LinkStackPushStack(&head,'c');
    LinkStackPushStack(&head,'d');
    PrintLinkStack(&head);
    LinkStackPopStack(&head);
    PrintLinkStack(&head);
    LinkStackPopStack(&head);
    LinkStackPopStack(&head);
    PrintLinkStack(&head);
    LinkStackPopStack(&head);
    PrintLinkStack(&head);
    LinkStackPopStack(&head);
    PrintLinkStack(&head);
}

// 销毁。
void TestLinkStackDestory()
{
    LINKSTACKNAME;
    LinkNode head;
    LinkStackInit(&head);
    LinkStackPushStack(&head,'a');
    LinkStackPushStack(&head,'b');
    LinkStackPushStack(&head,'c');
    LinkStackPushStack(&head,'d');
    PrintLinkStack(&head);
    LinkStackDestory(&head);
    PrintLinkStack(&head);
}

int main()
{
    TestLinkStackInit();
    TestLinkStackPushStack();
    TestLinkStackPopStack();
    TestLinkStackDestory();
    return 0;
}

如有错误,还望指正。谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值