关于堆栈

好久没来了,除除草,最近忙于完成数据挖掘的作业时候,没来得及学习数据结构,罪过。这几天有时间了,抓紧时间学习数据结构。温习了下之前写的程序,看堆栈的时候,灵机一动,我为什么非得一个一个得pop和push呢?主函数一次一次的调用好繁琐。我为什么不能设置一个和链表一样的结构,调用一次就可以push,pop好多个值。说干就干,立马动手改了程序。吶,如下。

//动态堆栈的创建
# include<stdio.h>
# include<stdlib.h>
//定义堆栈结构体
struct stack
{
    int data;
    struct stack *last;
 //   struct stack *p;
};
//堆栈push函数
//struct stack *top;//头指针为空;
int n=0;//n为计算堆栈里有几个元素
struct stack* push()
{
    struct stack *p1,*p2,*p3,*top;
   // struct stack *top=NULL;//头指针为空;
    p2=p1=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    top=NULL;//头指针为空
    scanf("%d",&p1->data);//给堆栈赋第一个值
    while(p1->data!=0)//当输入数值不为0时,堆栈累积
    {
         n++;
         if(n==1)
         p1->last=NULL;//之前在这出错了,写成p2->last了,不对,应该是p1,之后p1的值都会赋给p2
         else
         p1->last=p2;
         p2=p1;
         top=p2;
         printf("the stack‘s top is %d\nthe push number is %d\n",top,p2->data);
         p1=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
         scanf("%d",&p1->data);
    }
   return top;
}
//堆栈pop函数
struct stack* pop(struct stack *top)
{
    struct stack *p1,*p2;
    p1=top;//弹出的值
    while (p1->last!=NULL)
    {
         printf("\nnum:%ld,next:%ld",p1->data,p1->last);
         p1=p1->last;
         n--;
         if(p1->last==NULL)
            printf("\nnum:%ld,next:%ld",p1->data,p1->last);
      }
   // return(p1);
    //free(p2);
}
//主函数
void main()
{
    struct stack *p1,*p2,*p3,*p4,*top;
    top=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    top=push();
    printf("堆栈里总共有%d个数\n",n);
   // printf("the stack‘s top is %d\nthe push number is %d\n",top,p1->data);
   /* p3=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    p3=push();
    printf("堆栈里总共有%d个数\n",n);
    printf("the stack‘s top is %d\nthe push number is %d\n",top,p3->data);*/
   /* p4=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    p4=push();
    printf("堆栈里总共有%d个数\n",n);
    printf("the stack‘s top is %d\nthe push number is %d\n",top,p4->data);*/
    pop(top);
   // printf("堆栈里总共有%d个数\n",n);
   // printf("the stack‘s top is %d\nthe pop number is %d\n",top,p2->data);
}

然后晚上回宿舍的路上和同学讨论这个思路,被鄙视。说,“你见过一次push or pop好多个的堆栈函数吗?堆栈函数就是主函数一次次的调用,push or pop几个,就调用几次呗,没什么繁琐的”。醍醐灌顶,好像真的是这么回事。不过我这种思路改进了也可以用,根据需要push or pop几个数,微调push or pop子函数,也是可以哒。聪明反被聪明误。我重新写一下每次push or pop一个值的函数。这个事情告诉我们,改程序前要留底。。

还有一个注意点,不要随便设置全局变量!!!以后做工程万一其他人子函数里设置了和我这全局变量里一样的变量,那就太可怕了!

//然后晚上回宿舍的路上和同学讨论这个思路,被鄙视。说,“你见过一次push or pop
//好多个值的堆栈函数吗?堆栈函数就是主函数一次次的调用,push or pop几个,
//就调用几次呗,没什么繁琐的”。醍醐灌顶,好像真的是这么回事。
//不过我这种思路改进了也可以用,根据需要push or pop几个数,微调push or pop子函数,
//也是可以哒。
//聪明反被聪明误。我重新写一下每次push or pop一个值的函数。
//这个事情告诉我们,改程序前要留底。。

//动态堆栈的创建
# include<stdio.h>
# include<stdlib.h>
//定义堆栈结构体
struct stack
{
    int data;
    struct stack *last;
 //   struct stack *p;
};
//堆栈push函数
//struct stack *top;//头指针为空;
int n=0;//n为计算堆栈里有几个元素
struct stack* push()
{
    struct stack *p1,*p2,*p3,*top;
   // struct stack *top=NULL;//头指针为空;
    p2=p1=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    scanf("%d",&p1->data);//给堆栈赋第一个值
    p1->last=NULL;
    top=p1;
    n++;
   return top;
}
//堆栈pop函数
struct stack* pop(struct stack *top)
{
    struct stack *p1,*p2;
    if(top->data!=0)
   {
       p1=top;//弹出的值
       printf("\n弹出的值为num:%ld,则目前的top地址为:%ld",p1->data,p1->last);
       top=p1->last;
       n--;
   }
}
//主函数
void main()
{
    struct stack *p1,*p2,*p3,*p4,*top;
    top=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    top=push();
    printf("堆栈里总共有%d个数\n",n);
   // printf("the stack‘s top is %d\nthe push number is %d\n",top,p1->data);
    p3=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    p3=push();
    printf("堆栈里总共有%d个数\n",n);
    printf("the stack‘s top is %d\nthe push number is %d\n",top,p3->data);
   /* p4=(struct stack*)malloc(sizeof(struct stack));//申请动态存储区
    p4=push();
    printf("堆栈里总共有%d个数\n",n);
    printf("the stack‘s top is %d\nthe push number is %d\n",top,p4->data);*/
    pop(top);
   // printf("堆栈里总共有%d个数\n",n);
   // printf("the stack‘s top is %d\nthe pop number is %d\n",top,p2->data);
}

给大神看了,说我的程序可读性太差,让我看看人家写的程序。好吧。

#include <stdio.h>
#include <stdlib.h>

struct stack{
    int data;
    struct stack* last;
};

struct stack* push(struct stack* top)
{
    int data;
    if(top == NULL)
    {
        top = (struct stack*)malloc(sizeof(struct stack));
        printf("请输入数据");
        scanf("%d",&data);
        top->last = NULL;
        top->data = data;
        return top;
    }else{
        struct stack* insert = (struct stack*)malloc(sizeof(struct stack));
        printf("请输入数据");
        scanf("%d",&data);
        insert->data = data;
        insert->last = top;
        top = insert;
        return top;
    }
}

void output(struct stack* top) //显示目前堆栈内的值
{
    struct stack* top_temp;
    top_temp = top;
    printf("栈内数据从顶部到底部:");
    while(top_temp != NULL){
        printf("%d   ",top_temp->data);
        top_temp = top_temp->last;
    }
    printf("\n");
}
   struct stack* pop(struct stack* top)
   {
       if(top!=NULL)
       {
            struct stack* p1 = (struct stack*)malloc(sizeof(struct stack));
            p1=top;
            printf("弹出的值为%d\n",p1->data);
            top=p1->last;
       }
       else
       printf("当前堆栈为空\n");
   }
void main()
{
    struct stack* top = NULL;
    int i = 0;
    for(;i < 5; i++)
    {
        top = push(top);
        output(top);
    }
    for(i=0;i < 5; i++)
    {
        top = pop(top);
        output(top);
    }
}

嗯,对比之下,我的问题太明显了,程序不够简介明了,变量设置太乱,输出栏太机器化,输出的是给人看的,应该尽量看起来清楚明白,该有的文字要有,让人一目了然。还有人家只需要设置个for循环,就可以控制push和pop值的个数。我蠢了。相应的输出函数也只需要有一个,push or pop完之后都调用就好了。

前路漫漫,加油吧!

时间: 2024-10-14 12:01:50

关于堆栈的相关文章

PAT-l3-002堆栈

L3-002. 堆栈 大家都知道"堆栈"是一种"先进后出"的线性结构,基本操作有"入栈"(将新元素插入栈顶)和"出栈"(将栈顶元素的值返回并从堆栈中将其删除).现请你实现一种特殊的堆栈,它多了一种操作叫"查中值",即返回堆栈中所有元素的中值.对于N个元素,若N是偶数,则中值定义为第N/2个最小元:若N是奇数,则中值定义为第(N+1)/2个最小元. 输入格式: 输入第一行给出正整数N(<= 105).随

JVM学习(2)——技术文章里常说的堆,栈,堆栈到底是什么,从os的角度总结--转载http://www.cnblogs.com/kubixuesheng/p/5202561.html

转载自---http://www.cnblogs.com/kubixuesheng/p/5202561.html 俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及到的知识点总结如下: 堆栈是栈 JVM栈和本地方法栈划分 Java中的堆,栈和c/c++中的堆,栈 数据结构层面的堆,栈 os层面的堆,栈 JVM的堆,栈和os如何对应 为啥方法的调用需要栈 属于月经问题了,正好碰上有人问我这类比较基础的知识,无奈我自觉回答不是有效果,现在深入浅出的总结下: 前一篇文章总结了:JV

delphi如何输出当前堆栈

想实现,输出当前运行的堆栈,有会的吗?给点思路 方法很多,参考: https://bitbucket.org/shadow_cs/delphi-leakcheck/ 的 https://bitbucket.org/shadow_cs/delphi-leakcheck/raw/25652a1e8909dd5e560dab50ec84f475da6ba803/Source/LeakCheck.Trace.DbgHelp.pas http://bbs.2ccc.com/topic.asp?topici

数据结构Java实现05----栈:顺序栈和链式堆栈

数据结构Java实现05----栈:顺序栈和链式堆栈 一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除操作. 先进后出:堆栈中允许进行插入和删除操作的一端称为栈顶,另一端称为栈底.堆栈的插入和删除操作通常称为进栈或入栈,堆栈的删除操作通常称为出栈或退栈. 备注:栈本身就是一个线性表,所以我们之前讨论过线性表的顺序存储和链式存储,对于栈来说,同样适

使用Stack堆栈集合大数据运算

使用Stack堆栈集合大数据运算 package com.sta.to; import java.util.Iterator; import java.util.Stack; public class DaMax { public void jiaFa(String value1, String value2) { /** * 更多资料欢迎浏览凯哥学堂官网:http://kaige123.com * @author 小沫 */ // 把字符串用toCharArray拆成字符 char[] c1

数据存储的常用结构 堆栈、队列、数组、链表

数据存储的常用结构有:堆栈.队列.数组.链表.我们分别来了解一下: 堆栈,采用该结构的集合,对元素的存取有如下的特点: 先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素).例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹. 栈的入口.出口的都是栈的顶端位置 压栈:就是存元素.即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置. 弹栈:就是取元素.即,把栈的顶端位置元素取出,栈中已有元素依次

6.6-2-数组与数据结构(用数组及其函数实现堆栈等数据结构)

9.5.6.1使用数组实现堆栈 实现栈 1. int array_push ( array array ,mixed var [,mixed.] ) 添加参数到数组尾部,key+1 ,返回数组元素个数 即使数组有字符串键名,添加的元素也始终是数字键. 使用array_push 函数和直接赋值的方式是一样的. 2.mixed array_pop ( array &array ) echo array_pop ( $lamp ) ; 返回最后一个元素PHP,并删除之,数组元素数量减一 实现队列 ar

堆栈的使用【ACM】

题目描述: 堆栈是一种基本的数据结构.堆栈具有两种基本操作方式,push 和 pop.Push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出.现在我们就来验证一下堆栈的使用. 输入: 对于每组测试数据,第一行是一个正整数 n,0<n<=10000(n=0 结束).而后的 n 行,每行的第一个字符可能是'P'或者'O'或者'A':如果是'P',后面还会跟着一个整数,表示把这个数据压入堆栈:如果是'O',表示将栈顶的值 pop 出来,如果堆栈中没有元素时,忽略本次操作:如果是'A',表示询问

在linux代码中打印函数调用的堆栈的方法

之前一直有这样的需求,当时问到,也没搜到方法,现在竟然既问到了,也搜到了,哎,世事真是不能强求啊! 在Linux内核调试中,经常用到的打印函数调用堆栈的方法非常简单,只需在需要查看堆栈的函数中加入: dump_stack();或 __backtrace();即可. dump_stack()在~/kernel/ lib/Dump_stack.c中定义 void dump_stack(void){ printk(KERN_NOTICE  "This architecture does not imp

GDB调试汇编堆栈

GDB调试汇编堆栈 准备工作 终端编译工具: 编译64位Linux版本32位的二进制文件,需要安装一个库,使用指令sudo apt-get install libc6-dev-i386 测试代码: test.c 分析过程 1.生成汇编代码:gcc -g gdbtest.c -o gdbtest -m32 2.调试:gdb test 3.设置断点,因为目的是分析而不是调试bug,所以我们将断点设置在main函数 4.开始gdb调试:r(un),如若想获取此时的汇编代码,可用指令:disassemb