浅析数据结构中栈与C实现

来源:互联网 发布:阿里云ssh登录 编辑:程序博客网 时间:2024/05/17 23:17

最近在搞摄像头驱动,o()︿︶)o 唉,别提有多烦发火,一堆寄存器就有人受的了……特么这不是单片机的开发,这是内核驱动开发……抓狂



今天放松一下,我们来看看数据结构中的栈,这节的知识点可以说是数据结构中最容易上手的知识点了,其实比起链表,其实链表也有栈和队列的模型,链表的头插其实就是后进先出,链表的尾插其实就是先进先出,这不就是栈和队列吗,哈哈,不知道学习数据结构的时候有没有意识到这一点,但是栈和队列和链表还是有所区别的,我们来看看。


首先了解一下,什么是栈?

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

栈可以用来在函数调用的时候存储断点,做递归时要用到栈!最著名的实例便是汉诺塔,汉诺塔可以用递归来实现。


栈的生长方向是从高地址到低地址。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。

注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部。严格说来,栈帧底部栈底是不同的概念;ESP所指的栈帧顶部和系统栈的顶部是同一个位置。

在操作系统中,每一个线程都有一个栈,但是每个应用程序通常都只有一个堆,当然在为不同类型分配内存的时候使用多个堆并不是不可能。

那栈有什么特点?

1.  和堆一样存储在计算机 RAM中。

2.  在栈上创建变量的时候会扩展,并且会自动回收。

3.  相比堆而言在栈上分配要快的多。

4.  用数据结构中的栈实现。

5.  存储局部数据,返回地址,用做参数传递。

6.  当用栈过多时可导致栈溢出(无穷次(大量的)的递归调用,或者大量的内存分配)。

7.  在栈上的数据可以直接访问(不是非要使用指针访问)。

8.  如果你在编译之前精确的知道你需要分配数据的大小并且不是太大的时候,可以使用栈。

9.  当你程序启动时决定栈的容量上限。

 

栈的算法主要由以下步骤构建而成:

1进栈PUSH)算法

①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);

②置TOP=TOP+1(栈指针1,指向进栈地址);

S(TOP)=X,结束(X为新进栈的元素);

2.退栈(POP)算法

①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈,空则下溢;不空则作②)

X=S(TOP),(退栈后的元素赋给X):

TOP=TOP-1,结束(栈指针1,指向栈顶)。

 

说了这么多。以上是我对栈的理解,其实栈如果挖深一点,其实也是很深的,最精华的东西还是会跟指针结合到一起。先不研究太深的东西,我们还是直接上代码,看看到底是怎么回事,我的代码就依照栈的算法来实现:

#include <stdio.h>#include <string.h>int stack[20];int max = 20;           int top = 0;//设置栈//栈的初始化 void stack_init(void){memset(stack, 0, max); top = 0;}//判断栈是不是满了 int is_full(void){return top == max;}//入栈 int stack_push(int data){if(is_full()){return -1;}stack[top] = data;top ++;return 0;}//判断栈是否为空 int is_empty(void){return top == 0;}//出栈 int stack_pop(void){if(is_empty())return -1;top --;return stack[top];}//判断是不是在栈顶 int stack_top(void){return stack[top - 1];}int main(void){stack_init();  //初始化栈 int i;for(i = 0; i < 20; i++){stack_push(i);  //将0-19这20个数入栈 }printf("top = %d\n", stack_top());  //打印出栈顶的元素 for(i = 0; i < 20; i++){printf("val = %d\n", stack_pop());  //出栈 }}
运行结果:



我们从运行结果中看出,栈顶的元素是19,栈是后进先出,所以0是最先进的,那么最后出,19是最后进的,所以最先出,所以你会看到,我们的栈的生长方向即是从高处往低处走。

好了,今天打了下酱油,就到这里,准备早早睡觉!以后早早起床上班,才能早早的下班争取多点时间出来学习。下期播报:数据结构中的队列。

我的QQ空间博客: http://user.qzone.qq.com/826148759/appstore?via=QZ.DERECT.APPCENTER




2 0
原创粉丝点击