精华内容
下载资源
问答
  • 1.栈有两种写法,一种是以数组为躯干的顺序栈,一种是以链表为躯干的链式栈。 1.1栈的操作 1.1.1 出栈pop()函数 允许栈出,栈出之后,顶数据有移除操作。 时间复杂度o(1) 1.1.2 入栈push()函数 入栈,入栈之后...

    1.栈有两种写法,一种是以数组为躯干的顺序栈,一种是以链表为躯干的链式栈。

    1.1栈的操作

    1.1.1 出栈pop()函数

    允许栈出,栈出之后,顶数据有移除操作。

    时间复杂度o(1)

    1.1.2 入栈push()函数

    入栈,入栈之后,前一个数据网后呀。

    时间复杂度o(1)

    1.1.3 顶数据获取:peek()函数

    不会做数据的移除。

    时间复杂度o(1)

    1.1.4 判空函数len()

    当用于遍历的时候,需要知道判空的终止节点。

     

    1.1.5 元素获取:search(int index)

    获取节点的某个元素。

    时间复杂度o(1);

     

    2.我们来实现一个顺序栈

    我们已经知道了上述方法,还是得建立一个继承体系。

    先写一个接口叫IStack

    public interface IStack<T> {
    
        void push(T t);
        T pop();
        T peek();
        T search(int index);
        int len();
    }
    

    然后实现这个接口

    package com.stack.order;
    
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Objects;
    
    public class OrderLinkStack<T> implements IStack<T>{
    
    
        public OrderLinkStack(int index){
    
            tArray = (T[])new Object[index];
    
        }
        T[] tArray;
        int pointer = 0;
    
    
        @Override
        public void push(T t) {
            tArray[pointer] = t;
            pointer++;
        }
    
        @Override
        public T pop() {
            return tArray[--pointer];
        }
    
        @Override
        public T peek() {
            return tArray[pointer - 1];
        }
    
        @Override
        public T search(int index) {
            return tArray[index];
        }
    
        @Override
        public int len() {
            return pointer;
        }
    
    }
    

    我们写一个Int类型的栈

    public class IntOrderLinkStack extends OrderLinkStack<Integer> {
        public IntOrderLinkStack(int index) {
            super(index);
        }
    }
    

    然后测试这个栈

    测试结果

    3.数组栈的问题

    不能自动扩容,有个容量峰值。这点不太好。当然,这也是种访问机制。search的时候,时间复杂度为o(1)这一点就相当爽了。

    展开全文
  • 思路:利用短除法的原理以及栈先进后出的特点,先构建好一个顺序栈,这里我用的是数组,把每一次整除的余数压进栈里,然后再把栈里的数据依次取出,输出的便是对应进制的结果,需要注意的是十六进制比较特殊,得判断...

    题目:利用顺序栈实现将任意10进制数转换成对应的二进制,八进制,16进制输出

    思路:利用短除法的原理以及栈先进后出的特点,先构建好一个顺序栈,这里我用的是数组,把每一次整除的余数压进栈里,然后再把栈里的数据依次取出,输出的便是对应进制的结果,需要注意的是十六进制比较特,得判断输出字母的情况

    代码如下:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define N 50
    enum bool{false,true};	//定义枚举型辅助判断
    struct stack		//用一个结构体来定义栈
    {
    	int inter[N];	//存放栈真实数据的数组
    	int top;		//栈顶元素
    };
    struct stack *S_init()		//栈的初始化
    {
    	struct stack *S = malloc(sizeof(struct stack));
    	if(S == NULL)					//判断内存分配
    	{
    		printf("内存分配失败\n");
    		return NULL;
    	}
    	bzero(S,sizeof(struct stack));	//清空结构体
    	S->top = -1;		//初始化top
    	return S;
    }
    enum bool stack_empty(struct stack *S)	//判断栈是否为空
    {
    	if(S->top == -1)
    		return true;
    	else 
    	return false;
    }
    enum bool stack_full(struct stack *S)	//判断栈是否满了
    {
    	if(S->top == N-1)
    		return true;
    	else
    		return false;
    }
    enum bool stack_push(struct stack *S,int x)	//入栈(插入新元素)
    {
    	if(!stack_full(S))	//栈不满时插入
    	{
    		S->inter[++S->top] = x;
    		return true;
    	}
    	else
    	{
    		printf("栈已满,无法入栈!\n");
    		return false;
    	}
    }
    int stack_pop(struct stack *S)//退栈
    {
    	if(!stack_empty(S))		//栈不为空的时候,取出栈顶元素
    	{
    		if(S->inter[S->top] == 10)//判断十六进制时每一位输出字母的情况
    			printf("A");
    		else if(S->inter[S->top] == 11)
    			printf("B");
    		else if(S->inter[S->top] == 12)
    			printf("C");
    		else if(S->inter[S->top] == 13)
    			printf("D");
    		else if(S->inter[S->top] == 14)
    			printf("E");
    		else if(S->inter[S->top] == 15)
    			printf("F");
    		else
    		printf("%d",S->inter[S->top]);	//打印栈顶元素
    		S->top--;
    	}
    	else
    		printf("栈是空的\n");
    }
    int SysConvert(int n,int m)//进制转换,n为需要转换的十进制数,m为目标进制
    {
    	struct stack *St = S_init();
    	while(n)
    	{
    		if(stack_push(St,n%m))		//将每一次的余数压入栈
    			n = n/m;
    		else 
    		break;
    	}
    	printf("转换后的结果为:");
    	while(!stack_empty(St))
    	{
    		stack_pop(St);
    	}
    	return 0;
    }
    int main(int argc, char const *argv[])
    {
    	int m,n;
    	printf("请输入你要转换的十进制数:");
    	while(1)
    	{
    		if(scanf("%d",&n) && getchar() == '\n')//判断输入的合法性
    			break;
    		printf("输入不合法,请重新输入:");
    		while(getchar() != '\n');
    	}
    	printf("请输入要转换的进制:");
    	while(1)
    	{
    		if(scanf("%d",&m)&&((m == 2)||(m == 8)||(m == 16))&&(getchar() == '\n'))//判断输入的合法性
    			break;
    			printf("输入进制数不合法,请重新输入:");
    			while(getchar() != '\n');
    	}
    	SysConvert(n,m);
    	printf("\n");
    	return 0;
    }

    PS:我用的是Linux下的gcc编译,貌似不支持bool型,运行报错,所以我定义了一个枚举类型来判断,当然也可以用宏定义。输入的时候增加了合法性的判断,运行结果如下


    刚学栈没多久,程序不足之处希望大家指出。

    展开全文
  • c语言中堆,,数组的增长方向

    千次阅读 2016-12-07 17:33:13
    c语言中堆,,数组的增长方向这个问题在C语言中是个重点问题,也是个难点问题,接下来我们谈谈他们在内存中的增长问题: 如何判断的增长方向? 对于一个用惯了i386系列机器的人来说,这似乎是一个无聊的...

    c语言中堆,栈,数组的增长方向这个问题在C语言中是个重点问题,也是个难点问题,接下来我们谈谈他们在内存中的增长问题:

    如何判断栈的增长方向?

    对于一个用惯了i386系列机器的人来说,这似乎是一个无聊的问题,因为栈就是从高地址向低地址增长。不过,显然这不是这个问题的目的,既然把这个问题拿出来,问的就不只是i386系列的机器,跨硬件平台是这个问题的首先要考虑到的因素。

    在一个物质极大丰富的年代,除非无路可退,否则我们坚决不会使用汇编去解决问题,而对于这种有系统编程味道的问题,C是一个不错的选择。那接下来的问题就是如何用C去解决这个问题。

    C在哪里会用到栈呢?稍微了解一点C的人都会立刻给出答案,没错,函数。我们知道,局部变量都存在于栈之中。似乎这个问题立刻就得到了解答,用一个函数声明两个局部变量,然后比较两个变量的地址,这样就可以得到答案。

    等一下,怎么比较两个变量的地址呢?

    先声明的先入栈,所以,它的第一个变量的地址如果是高的,那就是从上向下增长。“先声明的先入栈”?这个结论从何而来?一般编译器都会这么处理。要是不一般呢?这种看似正确的方法实际上是依赖于编译器的,所以,可移植性受到了挑战。

    那就函数加个参数,比较参数和局部变量的位置,参数肯定先入栈。那为什么不能局部变量先入栈?第一反应是怎么可能,但仔细想来又没有什么不可以。所以,这种方法也依赖于编译器的实现。

    那到底什么才不依赖于编译器呢?

    不妨回想一下,函数如何调用。执行一个函数时,这个函数的相关信息都会出现栈之中,比如参数、返回地址和局部变量。当它调用另一个函数时,在它栈信息保持不变的情况下,会把它调用那个函数的信息放到栈中。

    似乎发现了什么,没错,两个函数的相关信息位置是固定的,肯定是先调用的函数其信息先入栈,后调用的函数其信息后入栈。那接下来,问题的答案就浮出了水面。

    比如,设计两个函数,一个作为调用方,另一个作为被调用方。被调用方以一个地址(也就是指针)作为自己的入口参数,调用方传入的地址是自己的一个局部变量的地址,然后,被调用方比较这个地址和自己的一个局部变量地址,由此确定栈的增长方向。

    给出了一个解决方案之后,我们再回过头来看看为什么之前的做法问题出在哪。为什么一个函数解决不了这个问题。前面这个大概解释了函数调用的过程,我们提到,函数的相关信息会一起送入栈,这些信息就包括了参数、返回地址和局部变量等等,在计算机的术语里,有个说法叫栈帧,指的就是这些与一次函数调用相关的东西,而在一个栈帧内的这些东西其相对顺序是由编译器决定的,所以,仅仅在一个栈帧内做比较,都会有对编译器的依赖。就这个问题而言,参数和局部变量,甚至包括返回地址,都是相同的,因为它们在同一个栈帧内,它们之间的比较是不能解决这个问题的,而它们就是一个函数的所有相关信息,所以,一个函数很难解决这个问题。

    好了,既然有了这个了解,显然可以扩展一下前面的解决方案,可以两个栈帧内任意的东西进行比较,比如,各自的入口参数,都可以确定栈的增长方向。


    复制代码
    #include<stdio.h>
    
    void func1();
    void func2(int *a);
    
    void func1()
    {
        int a=0;
        func2(&a);
    }
    void func2(int *a)
    {
        int b=0;
        printf("%x\n%x\n",a,&b);
    }
    
    
    int main()
    {
        func1();
    }
    复制代码

    结果:

    29f6ac
    29f5c8
    请按任意键继续. . .

    可以看到,a>b;说明生长方向向上。电脑中栈的增长方向是由高地址向低地址方向增长的。

     

    为什么栈向下增长?

    这个问题与虚拟地址空间的分配规则有关,每一个可执行C程序,从低地址到高地址依次是:text,data,bss,堆,栈,环境参数变量;其中堆和栈之间有很大的地址空间空闲着,在需要分配空间的时候,堆向上涨,栈往下涨。”

    这样设计可以使得堆和栈能够充分利用空闲的地址空间。如果栈向上涨的话,我们就必须得指定栈和堆的一个严格分界线,但这个分界线怎么确定呢?平均分?但是有的程序使用的堆空间比较多,而有的程序使用的栈空间比较多。所以就可能出现这种情况:一个程序因为栈溢出而崩溃的时候,其实它还有大量闲置的堆空间呢,但是我们却无法使用这些闲置的堆空间。所以呢,最好的办法就是让堆和栈一个向上涨,一个向下涨,这样它们就可以最大程度地共用这块剩余的地址空间,达到利用率的最大化!

     

    为什么要把堆和栈分开?

     为什么要把堆和栈区分出来呢?栈中不是也可以存储数据吗?

          第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。

          这样分开,使得处理逻辑更为清晰。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。

      第二,堆与栈的分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)。这种共享的收益是很多的。一方面这种共享提供了一种有效的数据交互方式(如:共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。

      第三,栈因为运行时的需要,比如保存系统运行的上下文,需要进行地址段的划分。由于栈只能向上增长,因此就会限制住栈存储内容的能力。而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。

      第四,面向对象就是堆和栈的完美结合。其实,面向对象方式的程序与以前结构化的程序在执行上没有任何区别。但是,面向对象的引入,使得对待问题的思考方式发生了改变,而更接近于自然方式的思考。当我们把对象拆开,你会发现,对象的属性其实就是数据,存放在堆中;而对象的行为(方法),就是运行逻辑,放在栈中。我们在编写对象的时候,其实即编写了数据结构,也编写的处理数据的逻辑。不得不承认,面向对象的设计,确实很美。


    复制代码
       #include  
      int main ( ) 
      { 
      char name[8]; 
      printf("Please type your name: "); 
      gets(name); 
      printf("Hello, %s!", name); 
      return 0; 
      }
    复制代码

     

    堆栈溢出

      现在我们再执行一次,输入ipxodiAAAAAAAAAAAAAAA,执行完gets(name)之后,由于我们输入的name字符串太长,name数组容纳不下,只好向内存顶部继续写‘A’。由于堆栈的生长方向与内存的生长方向相反,这些‘A’覆盖了堆栈的老的元素。 我们可以发现,EBP,ret都已经被‘A’覆盖了。在main返回的时候,就会把‘AAAA’的ASCII码:0x41414141作为返回地址,CPU会试图执行0x41414141处的指令,结果出现错误。这就是一次堆栈溢出

      3、如何利用堆栈溢出

      我们已经制造了一次堆栈溢出。其原理可以概括为:由于字符串处理函数(gets,strcpy等等)没有对数组越界加以监视和限制,我们利用字符数组写越界,覆盖堆栈中的老元素的值,就可以修改返回地址。

     

     

    堆(heap)和栈(stack)有什么区别??

     

    简单的可以理解为:

    heap:是由malloc之类函数分配的空间所在地。地址是由低向高增长的。

    stack:是自动分配变量,以及函数调用的时候所使用的一些空间。地址是由高向低减少的。

     

    预备知识—程序的内存分配

     

    一个由c/C++编译的程序占用的内存分为以下几个部分

    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

    2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

    3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放

    4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放

    5、程序代码区—存放函数体的二进制代码

     

    二、例子程序

    这是一个前辈写的,非常详细

    //main.cpp

    int a = 0; 全局初始化区

    char *p1; 全局未初始化区

    main()

    {

    int b; 栈

    char s[] = "abc"; 栈

    char *p2; 栈

    char *p3 = "123456"; 123456在常量区,p3在栈上。

    static int c =0; 全局(静态)初始化区

    p1 = (char *)malloc(10);

    p2 = (char *)malloc(20);

    分配得来得10和20字节的区域就在堆区。

    strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

    }

     

     

    二、堆和栈的理论知识

    申请方式

    stack:

    由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间

    heap:

    需要程序员自己申请,并指明大小,在c中malloc函数

    如p1 = (char *)malloc(10);

    在C++中用new运算符

    如p2 = (char *)malloc(10);

    但是注意p1、p2本身是在栈中的。


    申请后系统的响应

    栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

    堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,

    会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

    申请大小的限制

    栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。

    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

    申请效率的比较:

    栈由系统自动分配,速度较快。但程序员是无法控制的。

    堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.

    另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度, 也最灵活

    堆和栈中的存储内容

    栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。

    当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

    堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

    存取效率的比较

     

    char s1[] = "aaaaaaaaaaaaaaa";

    char *s2 = "bbbbbbbbbbbbbbbbb";

    aaaaaaaaaaa是在运行时刻赋值的;

    而bbbbbbbbbbb是在编译时就确定的;

    但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

    比如:

    #include

    void main()

    {

    char a = 1;

    char c[] = "1234567890";

    char *p ="1234567890";

    a = c[1];

    a = p[1];

    return;

    }

    对应的汇编代码

    10: a = c[1];

    00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]

    0040106A 88 4D FC mov byte ptr [ebp-4],cl

    11: a = p[1];

    0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]

    00401070 8A 42 01 mov al,byte ptr [edx+1]

    00401073 88 45 FC mov byte ptr [ebp-4],al

    第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指edx中,在根据edx读取字符,显然慢了。

    堆和栈的区别主要分:

    操作系统方面的堆和栈,如上面说的那些,不多说了。

    还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。

    虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因针值读


    说完了堆栈,我们来说说数组的增长方向:

    我的测试代码如下:

    #include <stdio.h>


    int main()
    {
    char buff[2] = {0};
    int buff1[2] = {0};


    printf("char buff:%d\n",&(buff[1]));
    printf("char buff:%d\n", &(buff[2]));
    printf("int  buff:%d\n", &(buff1[1]));
    printf("int  buff:%d\n", &(buff1[2]));


    return 0;
    }

    代码运行截图:


    这就说明数组不管任何情况下都是向上增长,堆栈的增长方向与数组的增长方向是两个不同的概念。


    展开全文
  • 顺序栈代码简单 这是数组类型的,应该会写栈顶栈底那种的 加油一起学数据结构 //2020.3.23 by不爱嚼米饭粒儿 //顺序栈 数组实现 //Init 初始化 //Push 入栈 //Pop 出栈 //Gettop 读取栈顶元素 #include<stdio....

    我觉得栈还是比较简单的,但是链表真的杀了我了,单链表忙活4天了,不断修改,重写啊啊啊啊啊
    顺序栈代码简单 这是数组类型的,应该会写栈顶栈底那种的
    加油一起学数据结构

    //2020.3.23  by大彪不爱嚼米饭粒儿 
    //顺序栈 数组实现 
    //Init  初始化
    //Push  入栈
    //Pop   出栈
    //Gettop 读取栈顶元素 
    #include<stdio.h>
    #include<malloc.h>
    #include<stdlib.h>
    #define MAXSIZE 100 
    typedef int Status;
    typedef struct sqstack{    //定义栈 
    	int  arry[MAXSIZE];
    	int   top;				//栈顶元素在栈顶中的位置 
    }Sqstack;
    Status Init(Sqstack *S)
    {
    	S->top = 0;				//栈顶元素在栈中的位置为0表示空栈 
    }
    Status Push(Sqstack *S,int  e)
    {
    	if(S->top ==MAXSIZE-1)
    	{
    		printf("栈满");
    	}
    	S->top++;
    	S->arry[S->top]=e;	 	//e成为新栈顶 
    	return 1;
    }
    Status Pop(Sqstack *S,int  *e)
    {
    	if(S->top == 0 )
    	{
    		printf("空栈"); 
    	}
    	*e = S->arry[S->top];			 
    	S->top--;
    	return 1;
    } 
    Status Gettop(Sqstack *S,int *e)
    {
    	if(S->top == 0)
    	{
    		printf("空栈");
    	}
    	*e = S->arry[S->top]; 
    	return *e;
    } 
    int main()
    {
    	int n;
    	int size;
    	int date;
    	int i;
    	Sqstack S;
    	printf("1,初始化\n2,入栈\n3,出栈\n4,读取栈顶元素\n0,退出\n");
    	scanf("%d",&n);
    	while(n!=0)
    	{
    	switch(n)
    	{
    		case 1:
    			Init(&S);
    			printf("初始化成功\n");
    			break;
    		case 2:
    			printf("输入栈长度\n");
    			scanf("%d",&size);
    			printf("输入栈数据\n");
    			for(i = 0;i<size;i++)
    			{
    				scanf("%d",&date);
    				Push(&S,date);
    			} 
    			printf("栈数据输入完毕\n");
    			break;
    		case 3:
    			printf("出栈\n");
    			for(i = 0;i<size;i++)
    			{
    				Pop(&S,&date);
    				printf("%d\t",date);
    			} 
    			printf("\n出栈完成\n");
    			break;
    		case 4:
    			printf("读取栈顶元素\n");
    			Gettop(&S,&date);
    			printf("%d",date);
    			printf("\n");
    	} 
    	scanf("%d",&n);
    	}
    	return 0;
    } 
     
    

    相比于上次的顺序表,这个比较简单,所以有功能了,未来找时间更改顺序表也改成这种
    运行结果如下:
    在这里插入图片描述

    展开全文
  • //两个顺序栈共享一个数据空间 #include&lt;stdio.h&gt; #include "stdlib.h" #define MAXSIZE 100 //是顺序栈所能存储的最多元素个数 typedef int datatype; typedef struct//顺序栈的定义  { ...
  • //算法实现2进制的转化 ...//求进制,顺序,逆序 void change2(int n) { if (!n) { return; } else { //printf("%d", n % 2);//放在前面为顺序输出 change2(n / 2); printf("%d", n % 2);//放在后面为逆序输出 } }
  •   溢出指的是程序向中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致中与其相邻的变量的值被改变。 溢出的原因: 局部数组过大。当函数内部的数组过大时,有可能导致堆栈溢出。局部...
  • 可利用数组来构造一个顺序栈 首先定义栈的结构 包含三个部分 : top值用于指示栈顶元素的上一个内存单位 用来存放栈值的数组 指向栈结构的指针 最先开始编写的代码遇到的问题: 初始定义函数的参数没有用指针,导致...
  • 顺序栈

    2015-04-12 20:45:35
    顺序栈通过数组实现,遵循先进先出 #include #include #define TRUE 1 #define FALSE 0 #define Stack_Size 50 typedef int StackElementType; typedef struct{ StackElementType elem[Stack_Size]; int
  • 顺序栈的阉割版
  • //SeqStack const int StackSize=10; template class SeqStack { private: DateType date[StackSize]; int Top1,Top2;...//构造; ~SeqStack();//释放空间; void push();//入栈 vo
  • 顺序栈(Sequential Stack)

    千次阅读 2016-05-13 20:20:57
    顺序栈(Sequential Stack) 1. 顺序栈的概念 ...顺序栈可以使用一维数组作为栈的存储空间,存放栈元素的数组的头指针为*elements,该数组的最大允许存放元素个数为maxSize,当前栈顶位置由数组下标
  • 现在我写了一个超简洁版的,目的是主要体现顺序栈原理,希望对读者有帮助。 简述原理 这段代码是顺序栈的实现。顺序栈的最大特点是长度不变,预先分配好一段存储单元,存储的数据物理上连续。关于栈的构建是用数组来...
  • 数据结构顺序栈的入栈与出栈

    千次阅读 多人点赞 2017-11-24 13:48:07
    数据结构顺序栈的入栈与出栈 #include #include  #define MaxSize 100 typedef int ElemType; typedef struct {  ElemType data[MaxSize];  int top; } SqStack;   //进桟 /*已知变量:初始化的栈,数组,...
  • C语言顺序栈:共享栈

    2020-05-13 13:35:03
    个人理解:共享顺序栈栈就是普通顺序栈在存储数组的另一头加上第二个栈顶指针。从而能够更有效地利用存储空间。 而顺序栈与链栈的区别可以参考顺序表和链表的关系。 代码如下 #include<stdio.h> #include<...
  • 在使用顺序栈时,定义空间过大,可能造成有些栈空闲,空间并没有有效利用。为了使栈的空间能充分利用,可以让多个栈共享一个足够大的连续存储空间,通过移动栈顶指针,从而使多个栈空间互相补充,存储空间得到有效...
  • 单调概念: 从名字上就听的出来,单调中存放的数据应该是有序的,所以...数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存
  • 顺序栈/链式栈

    千次阅读 2018-04-09 00:30:44
    栈是是一种限定性的线性表,它将线性表的插入和删除限定为仅在表...对应的栈成为顺序栈和链式栈。下面,分别来介绍这两种栈的相关操作。一,顺序栈 它与顺序表类似,即用一组地址连续的空间存放栈中的元素。之前的...
  • 顺序栈数组存数据,整型指向栈顶。 特点就是先入先出原则。 栈在逻辑上是线性结构。 代码收获 出栈需要个元素获取出栈的数据,实际并没有把此数据从栈顶拿走。 操作上采用传地址的方式把出栈的值传给*...
  • 使用java设计实现顺序栈的基本结构

    千次阅读 2018-03-14 23:06:56
    使用java设计实现顺序栈的基本结构,输入一个字符串来判断()以及[]是否匹配 基本栈结构介绍 顺序栈是一种FILO的结构,根据顺序栈的特性可以通过数组来实现顺序栈的相关操作。 使用一个头指针来作为数组存储元素...
  • 实验之数组逆序

    2016-08-01 10:14:35
    有n个整数,使其最后m个数变成最前面的m个数,其他各数顺序向后移m(m 输入 输入数据有2行,第一行的第一个数为n,后面是n个整数,第二行整数m。 输出 按先后顺序输出n个整数。 示例输入 5 1 2 3 4 5 2 ...
  • 数据结构——顺序栈(C语言实现)

    千次阅读 2014-10-21 20:49:20
     顺序栈实现  */ #include #define SIZE 50 static int data[SIZE]; //声明数组data,用于存储栈中数组 static int index; //声明变量index,用于表示栈中元素个数 //初始化栈 void init(){  ...
  • C++实现顺序栈

    2018-05-03 17:43:56
    用C++简单地实现了顺序栈,这种实现方法其实是把一个数组看成是两个栈,左右各一个,这样就可以更加合理的利用数组的空间,尤其是当两个栈的数据类型一样,一个栈增加另一个减小两个栈这样交替时。实现代码如下:#...
  • 数据结构:顺序栈的基本操作

    千次阅读 2018-04-16 20:25:22
    顺序栈利用一组连续的存储单元存放栈中的元素,存放顺序依次从栈底到栈顶。由于栈中元素之间的存放地址的连续性,在C语言中,同样采用数组实现栈的顺序存储。另外,增加一个栈顶指针top,用于指向顺序栈的栈顶元素。...
  • 数据结构—顺序栈

    千次阅读 多人点赞 2019-07-03 09:20:27
    顺序栈是利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的元素数据。分别使用top指针和base指针指向栈顶和栈底。 栈为空的标志是:top==base. 要注意的是:非空栈的栈顶指针总是...
  • 顺序栈的实现

    千次阅读 2014-10-22 15:38:20
    /***顺序栈的实现***/ #include #include //顺序栈定义 #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define MAXSIZE 100 typedef int Status; typedef int SElemType; typedef struct{ SElemType *base; ...
  • Java数据结构基础–顺序栈与链式栈 栈的定义: 是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端...顺序栈(基于数组): 完整代码: public class Stack {
  • 03顺序栈的建立及基本操作

    千次阅读 2019-09-20 19:10:55
    对于顺序栈,就是记录栈顶元素所在数组位置标号的一个整型变量;对于链式栈,就是记录栈顶元素所在节点地址的指针,其中它是动态变化的。表的另一端称为栈底,栈底是固定不变的。栈的插入和删除操作一般称为入栈和...
  • 1. 使用数组模拟 //定义一个ArrayStack表示,使用数组模拟 class ArrayStack{ public int maxSize; //的大小 public int[] stack; //数组数组模拟,数据就放在这里 public int top = -1 ;//top表示...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 77,971
精华内容 31,188
关键字:

顺序栈输入数组