如何轻松使用 C 语言实现一个栈?
什么是数据结构?
数据结构是什么?要了解数据结构,我们要先明白数据和结构,数据就是一些int char 这样的变量,这些就是数据,如果你是一个篮球爱好者,那么你的球鞋就是你的数据,结构就是怎么把这些数据排列组合,怎么把数据摆放好才能方便你找到这些数据,把数据和结构合在一起理解就是所谓的数据结构,简单点,就是处理数据的方式方法。
平时在家里面,你有没有随便摆放自己的鞋子,然后要找鞋子的时候要花费非常多是时间,可能你老婆也很生气,每天都乱摆鞋子导致她打扫卫生非常麻烦,然后有一天,你买了一个非常酷的鞋架,有了这个鞋架之后,你的鞋子终于有家了,这个鞋架就是起到处理鞋子的作用了。
什么是栈?
栈可以理解为数据结构中的一种,这种数据结构的特点是先进去的人「数据」后出来,就像下面的图片一样,如果栈是一个洞,人「数据」只能从洞的一个口进去,然后出来也只能从一个口出来,而且洞的宽度就只能容纳一个人「数据」,好了,那先进去的那个人「数据」最傻逼了,一定要等后面进来的人「数据」都先出去了才能出去。
用 C 语言实现一个栈
我写代码是很水的,之前有一个同学写了一个栈让我检查,我看了下,好像我写代码的能力比他厉害一些,代码比较简单,然后讲一下几个比较重要的函数,希望大家在面试的时候,随手就甩出一个栈“砸死”面试官,哈哈。
#include "stdio.h"
#include "stdlib.h"
struct List{
int data;
struct List * next;
};
struct Stack{
struct List *head;
int size;
};
struct Stack * StackInit(void)
{
struct Stack *stack = NULL;
stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->head = (struct List *)malloc(sizeof(struct List));
stack->head->next = NULL;
stack->size = 0;
return stack;
}
int StackPush(struct Stack *stack,int data)
{
struct List *tmp = (struct List *)malloc(sizeof(struct List));
tmp->data = data;
tmp->next = stack->head->next;
stack->head->next = tmp;
stack->size++;
//printf("push:%d \n",data);
return 0;
}
int IsStackEmpty(struct Stack *stack)
{
/*如果头指针指向下一个为空,说明栈为空*/
if(stack->head->next == NULL)
return 1;
else
return 0;
}
int StackPop(struct Stack *stack,int *data)
{
struct List *tmp = NULL;
if(IsStackEmpty(stack))
return -1;
tmp = stack->head->next;
*data = tmp->data;
stack->head->next = tmp->next;
stack->size--;
free(tmp);
//printf("pop:%d \n",*data);
return 0;
}
int main(void)
{
int i = 0;
struct Stack *stack = NULL;
stack = StackInit();
for(i = 0;i<5;i++)
{
StackPush(stack,i);
}
for(i = 0;i<5;i++)
{
int data = 0;
StackPop(stack,&data);
printf("%d ",data);
}
printf("\n");
return 0;
}
1- 栈头部
栈头部,也就是栈顶指针,我们用指针单链表实现一个栈,一定要知道这个栈顶的指针,有头就有栈,没有头,这个栈也就跨了。
struct Stack *stack = NULL;
stack = StackInit();
这个就是定义一个栈,也就是malloc出来一个内存,专门存这个栈顶的。
2- 出栈
出栈的方法跟我之前说的差不多,只不过出栈代码上需要做判断。
int StackPop(struct Stack *stack,int *data)
{
struct List *tmp = NULL;
if(IsStackEmpty(stack))
return -1;
tmp = stack->head->next;
*data = tmp->data;
stack->head->next = tmp->next;
stack->size--;
free(tmp);
//printf("pop:%d \n",*data);
return 0;
}
先判断这个栈是不是空的,是不是空的判断方法就是通过判断head->next的指针是否为空。
然后把head->next 这个位置的数据取出来,取出来后,再把head->next的指针指向 取出来这个位置 的next 位置。
然后再记得free掉。就Ok了。
3- 入栈
入栈的操作和出栈的操作刚好相反,就是改变一下位置和指针的指向。
int StackPush(struct Stack *stack,int data)
{
struct List *tmp = (struct List *)malloc(sizeof(struct List));
tmp->data = data;
tmp->next = stack->head->next;
stack->head->next = tmp;
stack->size++;
//printf("push:%d \n",data);
return 0;
}
用数组来实现一个栈
数组本身是一种数据结构,使用数组实现一个栈也是非常简单方便的,大家请看。
#include "stdio.h"
#include "stdlib.h"
/*栈的大小*/
#define LENGHT (100)
struct Stack{
int stack_array[LENGHT];
unsigned int size;//栈动态长度
};
struct Stack * StackInit(void)
{
struct Stack *stack = NULL;
stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->size = 0;
return stack;
}
int StackPush(struct Stack *stack,int data)
{
if(stack->size >= LENGHT)
{
printf("stack is full\n");
return (-1);
}
stack->stack_array[stack->size] = data;
stack->size++;
//printf("push:%d size:%d\n",data,stack->size);
return 0;
}
int IsStackEmpty(struct Stack *stack)
{
/*如果头指针指向下一个为空,说明栈为空*/
if(stack->size == 0)
return 1;
else
return 0;
}
int StackPop(struct Stack *stack,int *data)
{
stack->size--;
if(IsStackEmpty(stack))
return -1;
*data = stack->stack_array[stack->size];
//printf("pop:%d size:%d\n",*data,stack->size);
return 0;
}
int main(void)
{
int i = 0;
struct Stack *stack = NULL;
stack = StackInit();
for(i = 0;i<20;i++)
{
StackPush(stack,i);
}
for(i = 0;i<21;i++)
{
int data = 0;
StackPop(stack,&data);
printf("%d \n",data);
}
printf("\n");
return 0;
}
总结
既然有栈,就会有和栈不一样的数据结构,有一种数据结构叫做队列,栈的数据结构特点是先进后出,队列的数据结构特点是先进先出,有点意思,栈和队列做驱动的同学很少需要自己写代码实现,正常情况下都是SDK集成了方法,直接调用接口就好了,但是写应用的同学,经常要自己实现一个栈或者队列,特别是大企业面试,这些算是非常基础的题目,最好是闭着眼睛就能写出来的那种。
如果你想快速掌握C/C++编程,小编推荐我的C语言/C++编程学习基地【点击进入】!
都是学编程小伙伴们,带你入个门还是简简单单啦,一起学习,一起加油~
涉及:编程入门、游戏编程、windows编程、Linux编程、Qt、黑客等等......
如何轻松使用 C 语言实现一个栈?的更多相关文章
- 基于自定义的动态数组实现一个栈(Java语言)
关于动态数组,参见我的上一篇关于动态数组的博文https://www.cnblogs.com/inu6/p/11717129.html 1.什么是栈? (1)只能从一端添加元素,也只能从一端取出元素, ...
- 数据结构C语言实现----清空、销毁一个栈
代码如下: #include<stdio.h> #include<stdlib.h> typedef struct { char *base; char *top; int s ...
- (转)如何学好C语言,一个成功人士的心得!
zidier111发表于 2013-1-26 08:59:05 今 天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生,都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了所 ...
- 怎样学好C语言,一个成功人士的心得!
今天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生,都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了全部的数字化信息,不论是一段程序,一封email,一部电影都是用一连串的 ...
- 常见面试算法题JS实现-仅用递归函数和栈操作逆序一个栈
前言: 因为JAVA和JS语言特性的不同,有些东西在JAVA中可能需要一些技巧和手段才能实现的复杂程序,但是在JS中可能就是天然存在的,所以这套书里面的题目不会全部用JS去实现一遍,因为可能JS的实现 ...
- 使用C语言实现一个虚拟机
使用C语言实现一个虚拟机 2015-6-22 21:32| 发布者: joejoe0332| 查看: 2891| 评论: 0|原作者: leoxu, Serval, 社会主义好, lostTemple ...
- Part10-C语言环境初始化-栈初始化lesson1
1.概念解析 ARM系统使用的是满栈! ARM采用降栈!!! 栈帧 每一个进程会有一个栈,该进程中的每一个函数会分割栈的一部分,那么每一个函数使用的那部分栈就叫做栈帧.那么所有栈帧组成了整个栈. 子函 ...
- Go语言是如何处理栈的
转自:http://tonybai.com/2014/11/05/how-stacks-are-handled-in-go/ Go 1.4Beta1刚刚发布,在Go 1.4Beta1中,Go语言的st ...
- C语言实现顺序栈
C语言实现顺序栈,顺便加深刻++i,++i的区别 #include <stdio.h>#include <stdlib.h>#define maxsize 100/*写在前面的 ...
随机推荐
- Java多线程类FutureTask源码阅读以及浅析
FutureTask是一个具体的实现类,实现了RunnableFuture接口,RunnableFuture分别继承了Runnable和Future接口,因此FutureTask类既可以被线程执行,又 ...
- Vue 侦听器 watch
1. 侦听器 watch Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性 当属性发生改变时,自动触发属性对应的侦听器. 当需要在数据变化时执行异步或开销较大的操作时,这 ...
- 面向对象--有参数的__init__方法
有参数的__init__()方法 class Hero(object): """定义了一个英雄类,可以移动和攻击""" def __init ...
- jmeter(一)
一.首先是下载:下载地址为:http://jmeter.apache.org/download_jmeter.cgi选择Binaries下的相应压缩包.ps:jmeter是开源项目,一般这种开源项目B ...
- 第18课 - make 中的路径搜索(下)
第18课 - make 中的路径搜索(下) 1. 问题一 当 VPATH 和 vpath 同时出现,make 会如何处理? 工程项目的目录结构如下图所示,src1 和 src2 中都包含了 func. ...
- [剑指Offer]55-题目一:二叉树的深度 题目二:平衡二叉树
题目一 题目 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 题解 递归. 代码 class TreeNode { int v ...
- hystrix熔断器之metrics
Metric概述 HystrixCommands和HystrixObservableCommands执行过程中,会产生执行的数据,这些数据对于观察调用的性能表现非常有用. 命令产生数据后,Metric ...
- asp.net core 从 3.1 到 5.0
asp.net core 从 3.1 到 5.0 Intro 就在前几天,微软宣布了 .NET5 发布了 RC1 版本,这也意味着 .NET5 的开发基本稳定了,正式发布之前,不会再新增新的 Feat ...
- 【思维】The Four Dimensions of Thinking :长线思维的力量
"经历过这些苦难之后,我拥抱了一种新的人生哲学,就是更多地关注在那些长期可以获得复利的小收获上,而不是那种频繁的短跑冲刺和精力消耗". 斯坦福教授,著名的心理学家Philip Zi ...
- Oracle学习(十七)数据库锁在分布式系统里的应用(老板,乐观锁了解一下?~)
一.引言 随着业务量的增加,单机部署已经无法满足日常需求了,我们可能会把代码部署到多台服务器上去来进行服务的扩容,也就是负载均衡,那在这种场景下,怎么能实现锁的概念呢? 那么我们知道如果是一台主机部署 ...