【要求】实现一个栈的逆序,只能用递归函数和这个栈本身的操作来实现,而不能自己申请另外的数据结构。
一直对递归不太有能力去处理,在思考的时候,常常因为递归向下的时候就混淆了,不清楚下一步该干啥了,特别是针对返回值,应该返回啥,很多时候不能很好的去理解。之前想的是针对递归把每一步的过程缩小到最小,然后就仅仅针对递归结束的情况进行分析和递归第一步进行分析,以后还是多对这个下下功夫。
【思路】因为只能调用本身的栈来操作,所以只能用递归函数实现了。
第一步:首先,对一个栈,每次取它的顶部元素,并递归向下,直到该栈为空,然后向上依次push存取本次pop的值,当然在最后递归结束的过程,我们以后始终返回的是最后一次递归结束的时候pop的值,而push的是本次pop的值,这里要区分最后pop的值和每次递归操作的pop的值,有区别。换一句话说就是,在整个递归的过程中,我们除了最底部的元素不重新放进去栈之外,其他的元素都按照原来的顺序放进去,所以每次向上返回的是原始栈的底部元素,这样结束的时候我们就可以得到了栈的底部元素。
得到底部元素时,向上返回3,来到倒数第二层
倒数第二层把自己重新压入栈中,继续返回原来的底部原始3,继续向上
来到倒数第三层,将自身压入栈中,最后将3返回,结束。
1 public int get(Stack<Integer> stack){ 2 int a=stack.pop(); 3 if(stack.isEmpty()){ 4 return a; 5 } 6 else{ 7 int last=get(stack); //得到栈底元素 8 stack.push(a); //压入本次得到的pop值 9 return last; //每次向上返回原始的栈底元素 10 } 11 }
第二步:通过get函数我们可以每次得到栈的底部元素,这样如果重复调用该get函数,那么就可以得到每个栈的底部元素,然后按顺序依次再把得到的底部元素从最后得到的底部元素到最早得到的底部元素的顺序压入栈中,这样就可以实现逆序操作。
1 public void reverse(Stack<Integer> stack){ 2 13 if(stack.isEmpty()){ 3 14 return; 4 15 } 5 16 else{ 6 17 int i=get(stack); //调用get函数直到栈为空 7 18 reverse(stack); //最后得到的栈底元素既是原来栈的顶部元素 8 19 stack.push(i); //依次压入(从原来的栈顶元素直到栈底元素) 9 20 } 10 21 }
递归的代码简洁可是对于逻辑要求实在是比较高,相比循环一步一步操作来说,更需要考虑逻辑的问题。有时候如果能抓住最核心的向下递归的条件和向上递归返回的值的情况就可以很明了的理清思路问题