栈的两种实现

本文介绍了两种栈的实现方式:一种是使用顺序表实现栈,通过动态调整数组大小来适应入栈和出栈操作;另一种是使用单链表实现栈,利用头插法进行入栈操作并实现了基本的栈操作如出栈、获取栈顶元素等。
顺序表实现栈

#include <stdio.h>
#include <stdlib.h>
//顺序表实现栈
#define TEST_HEAD printf("\n======%s======\n", __FUNCTION__);

#define DEFAULT_SZ 5

typedef char DataType;

typedef struct seqStack
{
    DataType *data;
    int size;//当前栈的大小
    int capacity;//栈的总大小
} seqstack;

//栈的初始化
void StackInit(seqstack *pStack)
{
    if(pStack == NULL)
    {
        //非法输入
        return ;
    }
    //开辟空间
    pStack->data = (DataType *)malloc(DEFAULT_SZ * sizeof(DataType));
    if(pStack->data == NULL)
    {
        perror("malloc error");
        exit(EXIT_FAILURE);
    }
    pStack->size = 0;
    pStack->capacity = DEFAULT_SZ;
}

//入栈--即在顺序表尾部插入元素
void StackPush(seqstack *pStack, DataType data)
{
    if(pStack == NULL)
    {
        //非法输入
        return ;
    }
    if(pStack->capacity == pStack->size)
    {
        //顺序表已满,需要扩容
        DataType *ptr = NULL;
        ptr = (DataType *)realloc(pStack->data, sizeof(DataType) * (pStack->capacity) * 2 + 1);
        if(ptr == NULL)
        {
            perror("malloc error");
            exit(EXIT_FAILURE);
        }
        pStack->data = ptr;
        pStack->capacity = (pStack->capacity) * 2 + 1;
    }
    pStack->data[pStack->size] = data;
    ++pStack->size;
}

//出栈
void StackPop(seqstack *pStack)
{
    if(pStack == NULL)
    {
        //非法输入
        return ;
    }
    if(pStack->size == 0)
    {
        printf("栈已经为空\n");
        return ;
    }
    --pStack->size;
}

//取栈顶元素
DataType StackGetTop(seqstack *pStack)
{
    if(pStack == NULL)
    {
        //非法输入
        return -1;
    }
    return pStack->data[(pStack->size) - 1];
}

//打印栈
void StackPrint(seqstack *pStack, char *msg)
{
    printf("[%s]\n", msg);
    if(pStack == NULL)
    {
        printf("栈不存在\n");
        return ;
    }
    if(pStack->size == 0)
    {
        printf("空栈\n");
        return ;
    }
    int i = 0;
    for(i = (pStack->size) - 1; i >= 0; --i)
    {
        printf("[%c]\n", pStack->data[i]);
    }
}


//清空栈
void StackEmpty(seqstack *pStack)
{
    if(pStack == NULL)
        return ;
    (pStack)->size = 0;
    (pStack)->capacity = 0;
    free((pStack)->data);
    (pStack)->data = NULL;
}

//销毁栈
void StackDestory(seqstack **pStack)
{
    StackEmpty(*pStack);
    *pStack = NULL;
}

////////////////////////////
//测试函数
////////////////////////////

void TestStack()
{
    TEST_HEAD;
    seqstack *myStack;
    StackInit(myStack);
    StackPush(myStack, 'a');
    StackPush(myStack, 'a');
    StackPush(myStack, 'a');
    StackPush(myStack, 'a');
    StackPush(myStack, 'a');
    StackPrint(myStack, "入栈5个元素");
    DataType ret = StackGetTop(myStack);
    StackPrint(myStack, "取栈顶元素");
    printf("expect [e], actual [%c]\n", ret);
    StackPop(myStack);
    StackPop(myStack);
    StackPrint(myStack, "出栈两次");
    StackPop(myStack);
    StackPop(myStack);
    StackPop(myStack);
    StackPrint(myStack, "再出栈三次");
    StackPop(myStack);
    StackPrint(myStack, "尝试对空栈出栈");
    StackPush(myStack, 'a');
    StackPush(myStack, 'b');
    StackPush(myStack, 'c');
    StackPush(myStack, 'd');
    StackPush(myStack, 'e');
    StackPrint(myStack, "入栈5个元素");
    StackPush(myStack, 'z');
    StackPush(myStack, 'x');
    StackPush(myStack, 'y');
    StackPrint(myStack, "再入栈3个元素");
    StackEmpty(myStack);
    StackPrint(myStack, "清空栈");
    StackPush(myStack, 'z');
    StackPush(myStack, 'x');
    StackPush(myStack, 'y');
    StackPrint(myStack, "再入栈3个元素");
    StackDestory(&myStack);
    StackPrint(myStack, "销毁栈");
}

int main()
{
    TestStack();
    printf("\n\n\n");
    printf("\n\n\n");
    printf("\n\n\n");
    printf("\n\n\n");
    return 0;
}

这里写图片描述


单链表实现栈

//单链表实现栈
#include <stdio.h>
#include <stdlib.h>

typedef char DataType;

typedef struct linkStack
{
    DataType data;
    struct linkStack *next;
} linkStack;

//初始化
void linkStackInit(linkStack **head)
{
    *head = NULL;
}

//创建新结点
linkStack *CreatNode(DataType data)
{
    linkStack *new_node = (linkStack *)malloc(sizeof(DataType));
    new_node->data = data;
    return new_node;
}

//入栈(头插, 要改变头指针的指向)
void linkStackPush(linkStack **head, DataType data)
{
    if(head == NULL)
    {
        return ;
    }

    linkStack *new_node = CreatNode(data);
    if(*head == NULL)
    {
        //空链表
        *head = new_node;
        new_node->next = NULL;
        return ;
    }
    linkStack *temp = *head;
    new_node->next = temp;
    *head = new_node;
}

//出栈(头删, 也要修改头指针的指向)
void linkStackPop(linkStack **head)
{
    if(head == NULL)
    {
        //非法输入
        return ;
    }
    if(*head == NULL)
    {
        //空链表
        return ;
    }
    linkStack *temp = *head;
    *head = temp->next;
    free(temp);
}

//取栈顶元素
DataType linkStackGetTop(linkStack *head)
{
    if(head == NULL)
        return 0;
    linkStack *temp = head;
    return temp->data;
}

//打印栈
void linkStackPrint(linkStack *head, char *msg)
{
    printf("\n[%s]\n", msg);
    if(head == NULL)
    {
        return ;
    }

    linkStack *temp = head;
    while(temp != NULL)
    {
        printf("[%c|%9p]\n", temp->data, temp->next);
        temp = temp->next;
    }
}

//销毁栈
void linkStackDestory(linkStack **head)
{
    if(head == NULL)
    {
        //栈已经不存在了
        return ;
    }
    if(*head == NULL)
    {
        //空栈
        head = NULL;
        return ;
    }
    linkStack *temp = *head;
    linkStack *cur = NULL;
    while(temp != NULL)
    {
        cur = temp->next;
        free(temp);
        temp = cur;
    }
    *head = NULL;
    head = NULL;
}


////////////////////////////
//测试函数
////////////////////////////

void TestLinkStack()
{
    linkStack *myStack;
    linkStackInit(&myStack);
    linkStackPush(&myStack, 'a');
    linkStackPush(&myStack, 'b');
    linkStackPush(&myStack, 'c');
    linkStackPush(&myStack, 'd');
    linkStackPrint(myStack, "入栈4个元素");
    DataType ret = linkStackGetTop(myStack);
    linkStackPrint(myStack, "取栈顶元素");
    printf("ret expect [d], actual [%c]\n", ret);
    linkStackPop(&myStack);
    linkStackPrint(myStack, "出栈一次");
    linkStackPop(&myStack);
    linkStackPop(&myStack);
    linkStackPop(&myStack);
    linkStackPrint(myStack, "再出栈三次");
    linkStackPop(&myStack);
    linkStackPrint(myStack, "尝试对空栈出栈");
    linkStackPush(&myStack, 'a');
    linkStackPush(&myStack, 'b');
    linkStackPush(&myStack, 'c');
    linkStackPush(&myStack, 'd');
    linkStackPrint(myStack, "入栈4个元素");
    linkStackDestory(&myStack);
    linkStackPrint(myStack, "销毁栈");
}



int main()
{
    TestLinkStack();
    printf("\n\n\n");
    printf("\n\n\n");
    printf("\n\n\n");
    printf("\n\n\n");
    return 0;
}


这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值