前言
本文是【程序员代码面试指南(第二版)学习笔记】C#版算法实现系列之一,用C#实现了《程序员代码面试指南》(第二版)栈和队列中的用一个栈实现另一个栈的排序。
一、题目要求
允许申请一个辅助栈和变量来让另一个栈完成排序,但不能使用其他数据结构。
二、算法设计及代码实现
2.1 算法思想
概述:此题不止有一种解法,书上的这种解法效率较高,可以一组一组的排序,而不是单独的将一个一个的元素找见放入。整体思想是要让辅助栈的元素有栈底到栈顶从大到小排列,然后逐个放入到原栈内便可实现从小到大排序。要实现该功能,就需要每次把已经排好序的元素压入辅助栈,遇到序列不对的,用类似插入排序的思想将其插入即可。
具体过程:
将要排序的栈记为nums,辅助栈为helpStack。在nums弹出的元素记为cur。
1、如果cur小于或等于helpStack的栈顶元素,则将cur直接压入helpStack;
2、如果cur大于help的栈顶元素,则将 help 的元素逐一弹出,逐一压入nums,直到cur不大于helpStack的栈顶元素,再将cur压入helpStack。
2.2 代码实现
public static void Sort(Stack<int> nums) {
// 申请一个辅助栈
Stack<int> helpStack = new();
// 记录此时弹出的数字
int cur;
// 将所有元素按序放入辅助栈中
while (nums.Count > 0) {
cur = nums.Pop();
// 顺序是对的, 就直接入辅助栈
if (helpStack.Count == 0 || cur <= helpStack.Peek()) {
helpStack.Push(cur);
continue;
}
// 否则就需要弹出辅助栈中的元素, 直到cur不大于辅助栈顶数字或栈空才能压入
while (helpStack.Count > 0 && helpStack.Peek() < cur) {
nums.Push(helpStack.Pop());
}
// 结束循环后放入元素
helpStack.Push(cur);
}
// 有序放入辅助栈后, 只需要逐个放回原栈即可
while (helpStack.Count > 0) {
nums.Push(helpStack.Pop());
}
}