数据结构概述<3>栈

栈是一种重要的数据结构,其实质也是线性表的一种。但是它只支持两种操作:插入和删除。并且,栈的特点是后进先出,也就是说,栈的操作永远在顶部,插入和删除操作只在栈的顶部进行,所以先插入的栈会堆在底下,而后插入的栈会在栈顶,进行删除的时候,是从栈顶开始,所以新插入的元素反而能优先被删除,我们称之为后进先出。而这种插入和删除操作,在栈的用语里,叫做推进(push)和弹出(pop)。

举个例子来说,栈的操作有点像一个老师收上来的作业,先交的作业放在下面,后交的作业放在上面,老师在批阅的时候,总是先从上面的作业开始,于是先交的作业总是要晚一点才能被看到。

在C语言的应用中,总是习惯将各函数的实现代码放置在一个源文件中,而将这些函数需要提供给客户的接口声明放置在另一个单独的头文件中。这样客户只需要包含该头文件,就能调用对应的接口(当然,编译的时候需要与实现代码一起编译)。

在栈的实现中,我们在头文件stack.h中放置四个函数声明,也就是客户程序想使用栈时需要调用的接口。内容如下:

//stack.h
void stack_init(int);
int stack_empty(void);
void stack_push(int);
int stack_pop(void);

对应的实现代码放在stack.c中,这是栈的具体实现。在这里,我们介绍两种实现方式:数组和链表。并分别保存在stack1.c和stack2.c中。用数组的方式实现栈,非常简单直观,用数组下标即可访问,但是不能动态申请内存空间,这样就不太灵活,在这部分实现中,没有给出满栈时的处理方法,实际使用的时候肯定是要注意的。用链表的方式实现栈,可以灵活分配内存,栈的大小没有限制(当然,不能超过总内存大小),但是对每个元素,需要额外分配指针域空间,对于数量很大的栈来说,可能要考虑空间的浪费。代码如下:

//stack1.c
#include <stdlib.h>
static int *s;
static int N;

void stack_init(int maxN)
{
	s = malloc(maxN * sizeof(int));
	N = 0;
}
int stack_empty(void)
{
	return N == 0;
}
void stack_push(int item)
{
	s[N++] = item;
}
int stack_pop(void)
{
	return s[--N];
}
#include <stdlib.h>

typedef struct stacknode* link;
struct stacknode {
	int item;
	link next;
};
static link head;

link NEW(int item,link next)
{
	link x = malloc(sizeof *x);
	x->item = item;
	x->next = next;
	return x;
}
void stack_init(int maxN)
{
	head = NULL;
}
int stack_empty()
{
	return head == NULL;
}
void stack_push(int item)
{
	head = NEW(item,head);
}
int stack_pop()
{
	int item = head->item;
	link t = head->next;
	free(head);
	head = t;
	return item;
}

以上是栈的具体实现,介绍了两种实现方式:基于数组的和基于链表的。关于链表的概念,请参照上两篇博客:

链表的基本概念

链表的简单应用

有了栈的实现,我们在使用栈的时候,只需要包含头文件“stack.h”,既能调用栈的四个接口了,而不需要关注它的实现具体是什么样子的。原本我使用的是数组的实现,并用它写了一个将十进制数转换成八进制数的应用程序(下面马上要介绍),后来觉得这种实现不好,于是将它改为链表的实现,但是这个时候,我的客户程序,也就是用链表四个接口写的十进制转换成八进制的程序,不需要任何改动。这就是将接口和实现分开放置的好处。

下面给出一个栈的简单应用,将一个十进制数转换成八进制数,并且显示。代码如下:

//stackmain.c
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
#define MAXSIZE 100

int main()
{
	int i,n;
	scanf("%d",&n);
	stack_init(MAXSIZE);
	while (n) {
		stack_push(n % 8);
		n = n / 8;
	}
	while (!stack_empty()) {
		i = stack_pop();
		printf("%d",i);
	}
	printf("\n");
}

如果在linux下编译的话,可以用cc stack1.c stackmain.c  或者是 cc stack2.c stackmain.c即可。

时间: 2024-10-13 15:22:44

数据结构概述<3>栈的相关文章

数据结构概述&lt;4&gt;队列

队列也是一种比较常用的数据结构,和栈不同的地方在于它是先进先出的,就像我们平时的排队一样. 由于队列和栈非常相似,就不详细讲述概念了,可以参考上一篇博客数据结构概述<3>栈. 和栈一样,在这里直接给出队列的接口(queue.h),以及接口的数组实现(queue1.c)和链表实现(queue2.c).分别如下: //queue.h void queue_init(int); int queue_empty(); void queue_put(int); int queue_get(); //qu

数据结构快速回顾——栈

堆栈,也可直接称栈,是一种特殊的串行形式的数据结构,它的特殊之处在于只能允许在链结串行或阵列的一端进行加入资料和输出资料的运算.另外堆栈也可以用一维阵列或连结串行的形式来完成. 1 #define STACK_INIT_SIZE 100 2 #define STACKINCREMENT 10 3 4 typedef struct 5 { int* top; 6 int* base; 7 int stacksize; 8 }SqStack; 9 10 int InitStack(SqStack &

javascript数据结构与算法---栈

在上一遍博客介绍了下列表,列表是最简单的一种结构,但是如果要处理一些比较复杂的结构,列表显得太简陋了,所以我们需要某种和列表类似但是更复杂的数据结构---栈.栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样操作很快,而且容易实现. 一:对栈的操作. 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端陈为栈顶.比如餐馆里面洗盘子,只能先洗最上面的盘子,盘子洗完后,也只能螺到这一摞盘子的最上面.栈被称为 "后入先出"(LIFO)的数据结构. 由于栈具有后入先出的特点

数据结构-概述(1)

数据结构是计算机存储.组织数据的方式.数据结构是指相互之间存在一种或多种特定关系的数据元素的集合.通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率. 数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关. 通常有下列四类基本的结构: ⑴集合结构.该结构的数据元素间的关系是"属于同一个集合". ⑵线性结构.该结构的数据元素之间存在着一对一的关系. ⑶树型结构.该结构的数据元素之间存在着一对多的关系

数据结构实验之栈:进制转换

            数据结构实验之栈:进制转换 输入一个十进制整数,将其转换成对应的R(2<=R<=9)进制数,并输出. 输入 第一行输入需要转换的十进制数:第二行输入R. 输出 输出转换所得的R进制数. 模板: while(n!=0) { mod = n%r; q[i++] = mod;//i初始化为0 n/=r; }  

数据结构实验之栈:行编辑器

数据结构实验之栈:行编辑器 题目描述 一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区. 由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的.较好的做 法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区.允许用户输入出差错,并在发现有误时可以及时更正.例如,当用户发现刚 刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无效: 如果发现当前

SDUT OJ 1479 数据结构实验之栈:行编辑器

数据结构实验之栈:行编辑器 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区. 由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的.较好的做 法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区.允许用户输入出差错,并在发现有误时可以及时更正.例如,当

数据结构与算法--栈、队列(队列)

Hello,everybody.我们又见面了.今天我们来学习一下队列这个数据结构,let's Go,开始我们的征程吧. 首先,举两个生活中的常见例子.相信大家,在用电脑工作娱乐时,都会碰到这样的现象.当我们点击程序或进行其他操作时,电脑处于死机状态.正当我们准备Reset时,它突然像打了鸡血似的,突然把刚才我们的操作,按顺序执行了一遍.之所以会出现这个现象,是因为操作系统的多个程序,需要通过一个管道输出,而按先后顺序排队造成的. 还有有个例子,在我们打客服热线时,有时会出现等待的现象.当其他客户

7、蛤蟆的数据结构笔记之七栈的应用之数制转换

7.蛤蟆的数据结构笔记之七栈的应用之数制转换 本篇名言:"人生意义的大小,不在乎外界的变迁,而在乎内心的经验." 上面两篇中我们实现了链栈和链队列,接下去哦我们看看实际中栈的应用场景.本次来看下栈在数制转换的作用. 欢迎转载,转载请标明出处: 1.  原理介绍 十进制N和其他进制数的转换时计算机实现计算的基本问题.简单算法如下: N=(N div d )x d + N modd 2.  实现 2.1         定义结构体 定义堆栈的结构体 typedef struct { int