什么是数据结构?

数据结构是什么?要了解数据结构,我们要先明白数据和结构,数据就是一些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. apply用法

    result.push.apply(result, document.getElementsByTagName(tag)); 但是,这里为什么要用apply呢? 因为document.getEleme ...

  2. 【原创】Linux虚拟化KVM-Qemu分析(三)之KVM源码(1)

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...

  3. django之admin配置

    要在admin内显示的表,在admin中进行注册,然后在登录admin后台,才可以对表进行操作例如:from django.contrib import adminfrom app01 import ...

  4. python3 for

    当range中只有一个参数时,此参数表示终点,但不包括.(从0开始) 当range中有两个参数时,分别表示起点和终点.(左闭但不包括终点) 当range中有三个参数时,分别表示起点和终点,和步长,意思 ...

  5. 吴恩达《深度学习》-第五门课 序列模型(Sequence Models)-第一周 循环序列模型(Recurrent Neural Networks) -课程笔记

    第一周 循环序列模型(Recurrent Neural Networks) 1.1 为什么选择序列模型?(Why Sequence Models?) 1.2 数学符号(Notation) 这个输入数据 ...

  6. HTTP 【值得你看个究竟】

    我是一名程序员,我的主要编程语言是 Python,我更是一名 Web 开发人员,所以我必须要了解 HTTP,所以本篇文章就来带你从 HTTP 入门到进阶,看完让你有一种恍然大悟.醍醐灌顶的感觉. 认识 ...

  7. spring boot 源码之SpringBootExceptionReporter

    SpringBootExceptionReporter 用户自定义异常处理回调接口. public interface SpringBootExceptionReporter { boolean re ...

  8. Win10安装Ubuntu子系统

    相信我,这是最后一次折腾系统了qaq,以后一定开始认真用Linux编程 跟的一个博客安装,传送门:Win10安装Ubuntu子系统及图形化界面详细教程 文章是2019的,加上我装的是Ubuntu 20 ...

  9. 详细分析 Java 中实现多线程的方法有几种?(从本质上出发)

    详细分析 Java 中实现多线程的方法有几种?(从本质上出发) 正确的说法(从本质上出发) 实现多线程的官方正确方法: 2 种. Oracle 官网的文档说明 方法小结 方法一: 实现 Runnabl ...

  10. Tomcat 8.5安装

    安装 打开Tomcat官网:http://tomcat.apache.org/,下载tar.gz压缩文件,下载后文件名是apache-tomcat- 8.5.23.tar.gz.使用root用户安装, ...