利用两个栈,反转其中一个栈的元素
有两个相同的栈,一个里面放着自大到小排列的数,栈顶的数最小,另一个栈是空的。不允许利用其它的数据结构,只能利用这两个栈,要求把第一个栈里的数字反过来,从小到大排列,结果还放在原来的那个栈里面。
思路:假设stackA存放数,stackB为辅助栈。stackA元素个数为N。
第1次操作:先取stackA栈顶元素,记为tmp,然后把剩余N-1个元素转移到stackB中,接着把tmp和stackB的N-1个元素依次压入stackA中,这样完成了stackA原栈顶的反转。
第2次操作:先取stackA栈顶元素,记为tmp,因为栈底有一个元素已完成反转,故只需要把剩余的N-2个元素转移到stackB,接着把tmp和stackB的N-2个元素依次压入stackA中,这样完成了stackA原栈顶第二个元素的反转。
...
第i次操作:先取stackA栈顶元素,记为tmp,之前已有i-1个元素完成反转,只需要把栈顶的N-i+1个元素转移到stackB,接着把tmp和stackB的N-i+1依次压入stackA中。
注意:第N次操作时,因为前面N-1次操作已完成,而此时的栈顶就是初始的栈底,故第N次操作不需要做。总的过程只需要N-1次操作。
实现:
1 void ReverseStack(stack<int>&A, stack<int>&B) 2 { 3 int nLen = A.size(); 4 if (nLen <= 0) 5 { 6 return; 7 } 8 //共需要nLen-1次操作 9 for (int i = 0; i < nLen - 1; ++i) 10 { 11 //取栈顶 12 int tmp = A.top(); 13 A.pop(); 14 while (A.size() > i) 15 { //转移元素到stackB 16 int tmp1 = A.top(); 17 A.pop(); 18 B.push(tmp1); 19 } 20 //依次压入tmp和stackB元素 21 A.push(tmp); 22 while (!B.empty()) 23 { 24 int tmp2 = B.top(); 25 B.pop(); 26 A.push(tmp2); 27 } 28 } 29 }
测试函数:
1 void TestSortStack() 2 { 3 stack<int> stackA; 4 stack<int> stackB; 5 printf("依次压入数据:\n"); 6 for (int i=10;i>0;i--) 7 { 8 printf("%d ",i); 9 stackA.push(i); 10 11 } 12 13 ReverseStack(stackA,stackB); 14 printf("\nreverse result:\n"); 15 int tmp; 16 while (!stackA.empty()) 17 { 18 tmp = stackA.top(); 19 stackA.pop(); 20 printf("%d ",tmp); 21 } 22 }
因为栈是先进后出的,而把栈中元素反过来后,再输出数据就会和压入的顺序一致了。
不经历风雨,怎么见彩虹!