栈的链接存储——分析与实现

本文实现目标:

实现 step2/LnkStack.cpp 中的LS_IsEmptyLS_LengthLS_PushLS_PopLS_Top五个操作函数,以实现判断栈是否为空、求栈的长度、进栈、出栈以及获取栈顶元素等功能。

相关知识

链接存储的栈

栈的存储也可以采用链接存储的方式来实现。下面给出了一种基于链接存储的栈的实现方案:

如图 1 所示:该栈存储了 3 个元素 {56,77,15} ,其中 56 是栈顶元素。

这种实现方案中与栈相关的两个属性元素toplen介绍如下:

  • top: 指向栈顶结点的指针;
  • len: 栈中结点的个数。

特别说明:链接存储方式下,链表头结点作为栈顶结点,用指针top指向栈顶结点,栈结点个数由len给出。

基于toplen组织成的栈结构如下:

  1. struct LinkStack {
  2. LNode* top; // 栈顶指针
  3. int len; // 栈的长度
  4. };

为了讨论简单,我们假设栈元素的数据类型为整数:

  1. typedef int T; // 栈元素的数据类型

同时,每个结点的结构定义为:

  1. struct LNode {
  2. T data;
  3. LNode* next;
  4. };

据此,只要给定指向该结构的一指针ls,就可对栈进行出栈操作。

  • 进行出栈操作时,将指针top指向的当前栈顶元素 56 出栈,出栈后top指向下一个栈顶元素 77,这时的状态则如图 2 所示。

针对链式栈我们定义如下操作

  • 创建栈:创建一个链式栈。具体操作函数定义如下: LinkStack* LS_Create()

  • 释放栈:释放栈所占用的空间。具体操作函数定义如下: void LS_Free(LinkStack* ls)

  • 清空一个栈:将链式栈变为空栈。具体操作函数定义如下: void LS_MakeEmpty(LinkStack* ls)

  • 判断栈是否为空:若栈为空,则返回true,否则返回false。具体操作函数定义如下: bool LS_IsEmpty(LinkStack* ls)

  • 求栈的长度:获取链式栈的长度。具体操作函数定义如下: int LS_Length(LinkStack* ls)

  • 将元素 x 进栈:将 x 进栈,若满栈则无法进栈,具体操作函数定义如下: void LS_Push(LinkStack* ls, T x)

  • 出栈:出栈的元素放入 item 。若出栈成功(栈不为空),则返回true;否则(空栈),返回false。具体操作函数定义如下: bool LS_Pop(LinkStack* ls, T& item)

  • 获取栈顶元素:获取栈顶元素放入 item 中。若获取失败(空栈),则返回false,否则返回true。具体操作函数定义如下: bool LS_Top(LinkStack* ls, T& item)

  • 打印栈中元素:从栈顶到栈底打印各结点数据元素。具体操作函数定义如下: void LS_Print(LinkStack* ls)

下面给出C/C++语言实现的代码:

// 链接存储的栈实现文件

#include <stdio.h>
#include <stdlib.h>
#include "LnkStack.h"
/*创建栈*/
LinkStack* LS_Create()
{
    LinkStack* ls=(LinkStack*)malloc(sizeof(LinkStack));
    ls->top = NULL;
    ls->len = 0;
    return ls;
}

/*释放栈*/
void LS_Free(LinkStack* ls)
{
    LNode* curr = ls->top;
    while(curr) {
        LNode* next = curr->next;
        free(curr);
        curr=next;
    }
    free(ls);
}

/*将栈变为空栈*/
void LS_MakeEmpty(LinkStack* ls)
{
    LNode* curr = ls->top;
    while(curr) {
        LNode* next = curr->next;
        free(curr);
        curr=next;
    }
    ls->top = NULL;
    ls->len = 0;
}

/*判断栈是否为空*/
bool LS_IsEmpty(LinkStack* ls)
{
if (ls->top==NULL)
return true;
else
return false;

}

/*获取栈的长度*/
int LS_Length(LinkStack* ls)
{
int i;
i=ls->len;
return i;
   
}

/*将x进栈*/
void LS_Push(LinkStack* ls, T x)
{
LNode*temp=(LNode*)malloc(sizeof(struct LNode));
if(temp!=NULL){
    temp->data=x;
    temp->next=ls->top;

    ls->top=temp;
    ls->len=ls->len+1;
    }
}

/*出栈。出栈元素放入item;如果空栈,将返回false*/
bool LS_Pop(LinkStack* ls, T& item)
{
    LNode*temp;
if(ls->len==0)
return false;
else
{
    temp=ls->top;
    ls->top=temp->next;
    ls->len=ls->len-1;
    item=temp->data;
    return true;
}

}

/*读栈顶元素放入item。如果空栈,将返回false*/
bool LS_Top(LinkStack* ls, T& item)
{
if (ls->top==NULL)
return false;
else
item=ls->top->data;
}

/*从栈顶到栈底打印各结点数据*/
void LS_Print(LinkStack* ls)
{
    if (ls->len==0){ 
        printf("The stack: Empty!");
        return;
    }
    printf("The stack (from top to bottom):");
    LNode* curr=ls->top;
    while(curr) {
        printf(" %d", curr->data);
         
        curr=curr->next;
    }
   // printf("\n");
}

通过以上代码,我们可以实现对于链接存储的栈的一系列基本操作,并可以以此为基础去解决一些相关的实际问题。

欢迎大家留言评论指出一些地方的改进方法!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 好的,本关任务是要实现 step2/lnkstack.cpp 中的五个操作函数,分别是:ls_isempty、ls_length、ls_push、ls_pop和ls_top。这些函数可以用来判断是否为空、求长度、进、出以及获取顶元素等功能。 ### 回答2: 近年来,随着计算机科学技术的不断发展,数据结构已经成为计算机科学中不可或缺的重要内容。在数据结构中,是一种基本的数据结构,它具有先进后出(Last-In-First-Out, LIFO)的特点。在这样的背景下,本关任务是实现 step2/lnkstack.cpp 中的ls_isempty、ls_length、ls_push、ls_pop和ls_top五个操作函数,用于判断是否为空、求长度、进、出以及获取顶元素等功能。 首先,我们需要实现ls_isempty函数,该函数用于判断是否为空。在这个函数中,我们需要通过顶指针top是否为NULL来判断是否为空。如果top为NULL,则表示为空,否则不为空。 其次,我们需要实现ls_length函数,该函数用于求长度。在这个函数中,我们需要使用一个计数器count,每当有元素进时count加1,每当有元素出时count减1,最终得到长度。 接下来,我们需要实现ls_push函数,该函数用于将元素进。在这个函数中,我们需要先创建一个新的节点,然后将该节点插入到顶位置。 然后,我们需要实现ls_pop函数,该函数用于将元素出。在这个函数中,我们需要先判断是否为空,如果不为空,则弹出顶元素,返回该元素的值,并释放该节点所占用的空间。 最后,我们需要实现ls_top函数,该函数用于获取顶元素。在这个函数中,我们需要先判断是否为空,如果不为空,则返回顶元素的值。 通过实现以上五个操作函数,我们就能够实现的基本功能,包括判断是否为空、求长度、进、出以及获取顶元素等功能。在实现这些函数的过程中,需要注意算法的效率和正确性,同时保证代码的可读性和可维护性。 ### 回答3: 在实现 step2/lnkstack.cpp 中的ls_isempty、ls_length、ls_push、ls_pop和ls_top这五个操作函数之前,我们需要先了解的基本概念和操作。 是一种线性数据结构,它的特点是后进先出(Last In First Out,简称 LIFO)。的操作包括进(Push)、出(Pop)、顶元素(Top)、长度(Length)和判断是否为空(IsEmpty)等。在实际应用中,被广泛用于表达式求值、递归函数、计算系统中的内存管理以及操作系统的进程调度等。 实现方式有很多种,比较常见的是数组和链表。在本次任务中我们使用链表实现。ls_isempty、ls_length、ls_push、ls_pop和ls_top这五个操作函数的作用分别是判断是否为空、获取长度、进、出以及获取顶元素。 在实现这些函数前,我们需要先定义链表节点和链表结构体。链表节点包括数据域和指向下一个节点的指针域。链表结构体包括头指针和链表长度。以下是定义链表节点和链表结构体的代码: ```c++ typedef struct node { int data; struct node* next; } Node; typedef struct linkstack { Node* top; int length; } LinkStack; ``` 接下来我们分别讲解这五个操作函数的实现: 1. ls_isempty 判断是否为空,只需要判断头指针是否为 NULL 即可。 ```c++ bool ls_isempty(LinkStack* stack) { return stack->top == NULL; } ``` 2. ls_length 获取长度,只需要返回链表长度即可。 ```c++ int ls_length(LinkStack* stack) { return stack->length; } ``` 3. ls_push 进,我们可以在链表头部插入一个节点即可。 ```c++ void ls_push(LinkStack* stack, int data) { Node* newnode = (Node*)malloc(sizeof(Node)); newnode->data = data; newnode->next = stack->top; stack->top = newnode; stack->length++; } ``` 4. ls_pop 出,我们需要先判断是否为空。若不为空,则取出顶节点,并更新头指针。注意要释放原来的节点内存。 ```c++ bool ls_pop(LinkStack* stack, int* data) { if (ls_isempty(stack)) { return false; } else { Node* temp = stack->top; *data = temp->data; stack->top = temp->next; stack->length--; free(temp); return true; } } ``` 5. ls_top 获取顶元素,只需要返回头指针节点的数据即可。 ```c++ bool ls_top(LinkStack* stack, int* data) { if (ls_isempty(stack)) { return false; } else { *data = stack->top->data; return true; } } ``` 综上,通过以上的代码实现,我们可以在链表实现这一数据结构实现其中的基本操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少年与白日梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值