数据结构--栈

一、定义

    栈是限制在一端进行插入操作和删除操作的线性表 , 
    允许进行操作的一端称为“栈顶”, 另一固定端称为“栈底”, 
    当栈中没有元素时称为“空栈”。

逻辑结构:线性结构

存储结构:顺序存储、链式存储

特点:先进后出(FILO)

在这里插入图片描述

二、顺序栈

将栈采用顺序存储,它是顺序表的一种, 具有顺序表同样的存储结构, 由数组定义, 配合用数组下标表示的栈顶指针top( 相对指针)
完成各种操作。
其结构体定义如下:

    typedef int data_t;
    typedef struct seqstack
 	{
        data_t buf[N];//数据
		int top;//栈顶指针        
	}

顺序栈的基本操作函数如下:

/*===============================================
*   文件名称:stack.c
*   创 建 者:xm     
*   创建日期:2022年07月30日
*   描    述:
================================================*/
#include "stack.h"
//创建栈
Seqstack *create_seqstack()
{
    Seqstack *s =(Seqstack *)malloc(sizeof(Seqstack));
    if(NULL==s)
    {
        printf("malloc falied\n");
        return NULL;
    }
    memset(s->buf,0,sizeof(data_t)*N);
    s->top=-1;
    return s;
}
//判断是否为空栈
int seqtack_is_full(Seqstack *s)
{
    if(s->top==N-1)return 1;
    else return 0;

}
//栈是否已满
int seqtack_is_empty(Seqstack *s)
{
    if(s->top==-1)return 1;
    else return 0;

}
//压栈
void seqstack_push(Seqstack *s,data_t data)
{
    if(seqtack_is_full(s)==1)
    {
        printf("full!\n");
        return;
    }
    s->top++;
    s->buf[s->top]=data;
}
//弹栈
void seqstack_pop(Seqstack *s,data_t *data)
{
    if(seqtack_is_empty(s)==1)
    {
        printf("full!\n");
        return;
    }
    *data=s->buf[s->top];
    s->top--;

}
//测试,将一个十进制数转为二进制输出
void seqstack_test(Seqstack *s,int num)
{
	int bit;
	while(num)
	{
		bit=num%2;
		seqstack_push(s,bit);
		num=num/2;
	}
	while(s->top!=-1)
	{
		seqstack_pop(s,&bit);
		printf("%d ",bit);
	}
	printf("\n");
}

头文件如下:

/*===============================================
*   文件名称:stack.h
*   创 建 者:xm     
*   创建日期:2022年07月30日
*   描    述:
================================================*/
#ifndef _STACK_
#define _STACK_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 64
    typedef int data_t;
    typedef struct seqstack
 	{
        	data_t buf[N];
		int top;//栈顶指针        
	}Seqstack;
Seqstack *create_seqstack();
int seqtack_is_full(Seqstack *s);
int seqtack_is_empty(Seqstack *s);
void seqstack_push(Seqstack *s,data_t data);
void seqstack_pop(Seqstack *s,data_t *data);
void seqstack_test(Seqstack *s,int num);

#endif

主函数测试:

#include "stack.h"    
int main(int argc, char *argv[])
{ 
	Seqstack *s=create_seqstack();
    printf("输入一个整数\n");
    scanf("%d",&data);
    printf("转为二进制:\n");
    seqstack_test(s,data);
    return 0;
}

三、链栈

采用链式存储的栈称为链栈,链栈的优点是提高空间利用率,且不存在栈满上溢的情况。通常采用单链表实现,并规定所有操作都是在单链表的表头进行。
其结点结构体定义:

typedef struct linkstack
{
    data_t data;//数据
    struct linkstack *next;//指针域
}Linkstack;

相关操作函数:

/*===============================================
*   文件名称:linkstack.c
*   创 建 者:xm     
*   创建日期:2022年07月30日
*   描    述:
================================================*/
#include "linkstack.h"
//创建栈
Linkstack *create_linkstack()
{
	Linkstack *s=(Linkstack *)malloc(sizeof(Linkstack));
	if(NULL==s)
	{	
		printf("malloc error!\n");
		return NULL;
	}
	s->data=-1;
	s->next=NULL;	
	return s;
}
//判空
int linktack_is_empty(Linkstack *s)
{
	if(s->next==NULL)return 1;
	else return 0;
}
//压栈
void linkstack_push(Linkstack *s,data_t data)
{
	Linkstack *p=(Linkstack *)malloc(sizeof(Linkstack));
	if(NULL==p)
	{	
		printf("malloc error!\n");
		return;
	}
	p->data=data;
	p->next=s->next;
	s->next=p;
}
//出栈
void linkstack_pop(Linkstack *s,data_t *data)
{	
	if(linktack_is_empty(s)==1)
	{
		printf("stack is empty\n");
		return ;
	}
	Linkstack *p=s->next;
	*data=p->data;
	s->next=p->next;
	free(p);
	p=NULL;	
}

头文件:

/*===============================================
*   文件名称:linkstack.h
*   创 建 者:xm     
*   创建日期:2022年07月30日
*   描    述:
================================================*/
#ifndef _LINKSTACK_
#define _LINKSTACK_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 64
typedef int data_t;
typedef struct linkstack
{
    data_t data;//数据域
	struct linkstack *next;//指针域        
}Linkstack;

Linkstack *create_linkstack();
int linktack_is_empty(Linkstack *s);
void linkstack_push(Linkstack *s,data_t data);
void linkstack_pop(Linkstack *s,data_t *data);
int linkstack_work(Linkstack *s,int num);

#endif
主函数测试:
/*===============================================
*   文件名称:main.c
*   创 建 者:     
*   创建日期:2022年07月30日
*   描    述:
================================================*/
#include "stack.h"
#include "linkstack.h"
int main(int argc, char *argv[])
{ 
    Linkstack *s=create_linkstack();
    int data=1,n=10;
    while(n--)
    {
        linkstack_push(s,n);
    }
    while(s->next!=NULL)
    {
        linkstack_pop(s,&data);
        printf("data=%d\n",data);
    }

    return 0;
} 

总结:顺序栈与链栈在时间复杂度上相同,在空间性能上,顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题,但它的优势是存取时定位很方便。而链栈则要求每个元素都有指针域,这同时也增加了一些内存开销,但对于栈的长度无限制。
所以如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值