什么是数据结构?

数据结构是什么?要了解数据结构,我们要先明白数据和结构,数据就是一些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 语言实现一个栈?​的更多相关文章

  1. 基于自定义的动态数组实现一个栈(Java语言)

    关于动态数组,参见我的上一篇关于动态数组的博文https://www.cnblogs.com/inu6/p/11717129.html 1.什么是栈? (1)只能从一端添加元素,也只能从一端取出元素, ...

  2. 数据结构C语言实现----清空、销毁一个栈

    代码如下: #include<stdio.h> #include<stdlib.h> typedef struct { char *base; char *top; int s ...

  3. (转)如何学好C语言,一个成功人士的心得!

    zidier111发表于 2013-1-26 08:59:05   今 天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生,都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了所 ...

  4. 怎样学好C语言,一个成功人士的心得!

    今天,我能够自称是一个混IT的人,并能以此谋生,将来大家能一次谋生,都要感谢两个人:克劳德.香农和约翰.冯.诺依曼,是他们发现了全部的数字化信息,不论是一段程序,一封email,一部电影都是用一连串的 ...

  5. 常见面试算法题JS实现-仅用递归函数和栈操作逆序一个栈

    前言: 因为JAVA和JS语言特性的不同,有些东西在JAVA中可能需要一些技巧和手段才能实现的复杂程序,但是在JS中可能就是天然存在的,所以这套书里面的题目不会全部用JS去实现一遍,因为可能JS的实现 ...

  6. 使用C语言实现一个虚拟机

    使用C语言实现一个虚拟机 2015-6-22 21:32| 发布者: joejoe0332| 查看: 2891| 评论: 0|原作者: leoxu, Serval, 社会主义好, lostTemple ...

  7. Part10-C语言环境初始化-栈初始化lesson1

    1.概念解析 ARM系统使用的是满栈! ARM采用降栈!!! 栈帧 每一个进程会有一个栈,该进程中的每一个函数会分割栈的一部分,那么每一个函数使用的那部分栈就叫做栈帧.那么所有栈帧组成了整个栈. 子函 ...

  8. Go语言是如何处理栈的

    转自:http://tonybai.com/2014/11/05/how-stacks-are-handled-in-go/ Go 1.4Beta1刚刚发布,在Go 1.4Beta1中,Go语言的st ...

  9. C语言实现顺序栈

    C语言实现顺序栈,顺便加深刻++i,++i的区别 #include <stdio.h>#include <stdlib.h>#define maxsize 100/*写在前面的 ...

随机推荐

  1. Python实现加密的RAR文件解压(密码已知)

    博主之前在网上找了很多资料,发现rarfile库不能直接调用,需要安装unrar模块,下面将详细介绍整个实现流程. 第一步:安装unrar模块,直接pip install unrar可能会找不到库,需 ...

  2. Linux:文件和用目录权限基础

    首先,用ls -i 查看文件的信息: 红框框起来的部分:-rw-r--r-- 一共是10位,第一位表示文件类型,-表示文件,d表示文件夹/目录:后面9位则表示权限 其中前三位是该文件/目录所属者的权限 ...

  3. Fragment时长统计那些事

    注:本文同步发布于微信公众号:stringwu的互联网杂谈 frament时长统计那些事 页面停留时长作为应用统计的北极星指标里的重要指标之一,统计用户在某个页面的停留时长则变得很重要.而Fragme ...

  4. warning: #1295-D: Deprecated declaration LED_Init - give arg types警告的解决办法

  5. Burp Suite抓包使用步骤

    Burp Suite抓包工具的操作步骤见安装步骤那篇博客 检查是否存在漏洞,就看拦截之后修改过的数据是否写进了数据库 举例一.上传文件 1.打开Burp.调整Proxy-Intercept-Inter ...

  6. hystrix文档翻译之开始使用

    获取包 使用maven获取包. <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId ...

  7. hystrix源码之hystrix请求变量

    HystrixRequestContext 请求的上线文实现,内部定义了一个静态变量ThreadLocal,每个线程可以获取自己的HystrixRequestContext对象.一个请求往往由一个to ...

  8. linux学习(十一)linux安装nginx

    一.前言 由于本地练手的小demo用的是vue+spring boot来玩的,所以部署的时候想着用Nginx来实现反向代理[即请求转发,解决前后端分离的跨域请求问题],既然要用,那么首先得在服务器上面 ...

  9. ARM架构下的Docker环境,OpenJDK官方没有8版本镜像,如何完美解决?

    为什么需要ARM架构下的OpenJDK8的Docker镜像? 对现有的Java应用,之前一直运行在x86处理器环境下,编译和运行都是JDK8,如今在树莓派的Docker环境运行(或者其他ARM架构电脑 ...

  10. 嘿!Mybatis

    简介 什么是Mybatis MyBatis 是一款优秀的持久层框架 它支持自定义 SQL.存储过程以及高级映射. MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作. My ...