当前位置: 首页 > 科技观察

动画演示:手工堆叠的两种实现方法!

时间:2023-03-13 23:08:36 科技观察

本文转载自微信公众号“Java中文社区”,作者雷哥。转载本文请联系Java中文社区公众号。正式开始之前,先和小伙伴们聊聊未来的一些打算公众号。在后面的文章中,我打算写一些关于数据结构和算法的内容。道理很简单:“底层结构决定上层建筑”。我们不仅要学习如何使用框架,还要了解它的原理和底层数据结构。只有这样,我们才能更好地应用它。当然,除了上述原因之外,还有一个重要的因素就是要完成面试。随着软件开发行业的竞争越来越激烈,面试的难度也逐渐加大,因为企业要从众多面试官中选出最优秀的人选,只能增加面试的难度,而算法和数据结构更耗脑力.硬核技能之一,自然成为面试的首选。而且随着时间的推移,算法和数据结构出现的频率和比例会不断增加,所以为了顺应时代潮流,我们不得不做出一些调整,所以在后面的文章中,我会更新一些文章关于算法和数据结构,希望大家喜欢。PS:当然,随着智能系统(比如今日头条和抖音)的普及,算法和数据结构在企业中的使用越来越多,学习算法和数据结构迫在眉睫。栈定义栈(Stack),又称堆栈(简称栈),是同端插入和删除数据的线性表。栈是最基本、最常见的数据结构之一。其数据结构和操作流程如下图所示:其中,允许插入和删除的一端称为栈顶(Top),另一端称为栈底(Bottom)。),栈底是固定的,栈顶是浮动的。当栈中的元素为零时,栈称为空栈。添加数据一般称为入栈或入栈(Push),删除数据称为入栈或出栈(Pop)。堆栈是后进先出(LIFO)的线性列表。Physicalstructure&logicalstructure在动手处理算法之前,我们先了解一下数据结构中的两个重要概念:物理结构和逻辑结构。当我们谈到“物理”和“逻辑”这两个词时,我们可以想到数据库中的逻辑删除和物理删除。所谓物理删除,是指通过delete命令从物理结构中实际删除数据的过程;而逻辑删除是指通过修改命令将数据变为“已删除”状态,而不是真正的删除数据。这里的逻辑结构和物理结构与上述概念类似。所谓物理结构,就是数据可以存储在物理空间中。比如数组、链表就属于物理数据结构;而逻辑结构则用来描述数据之间的逻辑关系。关系型的,比如本文要讲的栈,就属于逻辑结构。有的人看到这里可能会一头雾水,没关系,我这里举个例子,你就明白了。如果用人来表示物理结构和逻辑结构,那么真正有血有肉的人就属于物理结构,而人的思想和信仰则属于逻辑结构。自定义栈一:数组实现通过上面的内容,我们知道栈是一个逻辑结构,所以实现它的方式有很多种,比如数组的实现或者链表的实现。那我们先用数组来实现吧。栈的主要方法有:①定义结构那么我们先定义它的结构:publicclassMyStack{privateObject[]value=null;//栈存储容器privateinttop=-1;//栈顶(指针)privateintmaxSize=0;//栈容量//构造函数(初始化默认容量)MyStack(){this.maxSize=10;}//带参数的构造函数MyStack(intinitSize)throwsException{if(initSize<=0){thrownewException("栈容量mustbegreaterthan0");}else{value=newObject[initSize];maxSize=initSize;top=-1;}}}其中栈中的数据会存放在Object[]值数组中,topvariable表示指向栈顶的指针,实际存放的是栈顶元素的下标,随着入栈(后进先出)会发生变化,maxSize表示栈顶元素的最大容量堆。②Pushing该方法是向栈中添加数据,实现代码如下://Pushing(数据添加)publicbooleanpush(Ee)throwsException{if(maxSize-1==top){thrownewException("Pushingfailed,thestackisfull");}else{value[++top]=e;returntrue;}}每次插入数据时,只要给数组加一个值,栈顶的下标加1即可。push操作如下图所示:③pop这个方法是删除栈中的数据,实现代码如下://数据移除(pop)publicEpop()throwsException{if(top<=-1){thrownewException("取出失败,栈中没有数据");}else{return(E)value[top--];}}出栈只需要删除栈顶的数据数组(最后加入的数据),修改栈顶下标-1即可。弹出操作如下图所示:④除了上面查询数据的操作方法外,我们还需要添加一个查询栈顶数据的方法://dataquerypublicEpeep()throwsException{if(top<=-1){thrownewException("移除失败,栈中没有数据");}else{return(E)value[top];}}⑤代码测试至此,栈的数据结构已经实现了,接下来测试一下://代码测试publicstaticvoidmain(String[]args)throwsException{MyStackstack=newMyStack(10);stack.push("Hello");stack.push("Java");System.out.println(stack.peep());stack.pop();System.out.println(stack.pop());}上面程序的执行结果是:JavaHello从上面的代码可以看出,加入栈的顺序是Hello,Java和输出的顺序是Java,Hello符合栈的定义(后进先出)。自定义栈二:链表实现除了数组,我们还可以使用链表来实现栈结构。它的实现稍微复杂一些。我们先来看一下链表的数据结构:使用链表实现栈的过程是这样的:即我们把数据入栈的时候存放在链表的头部,出栈的时候取出数据出栈时的head,将栈顶指针指向原head元素的下一个元素。实现代码如下。我们先定义一个链表节点:publicclassNode{Objectvalue;//每个节点的数据Nodeext;//下一个节点publicNode(Objectvalue){this(value,null);}/***新建节点*@paramvalue当前节点数据*@paramnext指向下一个节点(头部插入方式)*/publicNode(Objectvalue,Nodenext){this.value=value;this.next=next;}}接下来我们用一个链表来实现一个完整的栈:publicclassStackByLinked{privateNodetop=null;//栈顶数据privateintmaxSize=0;//栈最大容量privateintleng=0;//栈实际容量publicStackByLinked(intinitSize)throwsException{if(initSize<=0){thrownewException("栈容量不能belessthanorequal0");}top=null;maxSize=initSize;leng=0;}/***容量是否满*@return*/publicbooleanisFull(){returnleng>=maxSize;}/***是否为空*@return*/publicbooleanisEmpty(){returnleng<=0;}/***入栈*@paramval*@return*@throwsException*/publicbooleanpush(Objectval)throwsException{if(this.isFull()){//容量满了thrownewException("容量已满");}top=newNode(val,top);//保存信息,并设置当前节点为头节点leng++;returntrue;}/***pop(remove)*@return*@throwsException*/publicNodepop()throwsException{if(this.isEmpty()){thrownewException("栈为空,无法移除");}Nodeitem=top;//返回当前元素top=top.next;leng--;returnitem;}/***查询栈顶信息*@return*/publicNodepeek()throwsException{if(isEmpty()){thrownewException("Youareoperatinganemptystack");}returntop;}//代码测试publicstaticvoidmain(String[]args)throwsException{StackByLinkedstack=newStackByLinked(10);stack.push("Hello");stack.push("Java");System.out.println(stack.peek().value);stack.pop();System.out.println(stack.pop().value);}}上面程序的执行结果为:JavaHello我们使用数组、链表等物理结构来实现栈。当然,我们也可以使用其他容器来实现,比如Java中的List。我们只需要保证栈按照后进先出的执行顺序进行操作,并且至少包含3个重要的方法:只是入栈、出栈、查询栈顶元素即可。最后,算法和数据结构的学习是3分学习和7分练习。这是一个循序渐进的过程,短时间内不会有明显的效果。因为这些算法都是经过数百年的发展和积累而流传下来的,所以要“玩好”需要一点耐心。这里有一个学习算法的“秘诀”:不懂的知识要反复阅读。如果反复阅读还是不明白,不要着急,休息一下继续阅读!相信我,说到学习算法,一切人类的过程都是一样的。