我在面试条件下迅速写了这篇文章,我想把它发布到社区,看看是否有更好/更快/更清洁的方式去做。怎么可以优化呢?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Stack
{
class StackElement<T>
{
public T Data { get; set; }
public StackElement<T> Below { get; set; }
public StackElement(T data)
{
Data = data;
}
}
public class Stack<T>
{
private StackElement<T> top;
public void Push(T item)
{
StackElement<T> temp;
if (top == null)
{
top = new StackElement<T>(item);
}
else
{
temp = top;
top = new StackElement<T>(item);
top.Below = temp;
}
}
public T Pop()
{
if (top == null)
{
throw new Exception("Sorry, nothing on the stack");
}
else
{
T temp = top.Data;
top = top.Below;
return temp;
}
}
public void Clear()
{
while (top != null)
Pop();
}
}
class TestProgram
{
static void Main(string[] args)
{
Test1();
Test2();
Test3();
}
private static void Test1()
{
Stack<string> myStack = new Stack<string>();
myStack.Push("joe");
myStack.Push("mike");
myStack.Push("adam");
if (myStack.Pop() != "adam") { throw new Exception("fail"); }
if (myStack.Pop() != "mike") { throw new Exception("fail"); }
if (myStack.Pop() != "joe") { throw new Exception("fail"); }
}
private static void Test3()
{
Stack<string> myStack = new Stack<string>();
myStack.Push("joe");
myStack.Push("mike");
myStack.Push("adam");
myStack.Clear();
try
{
myStack.Pop();
}
catch (Exception ex)
{
return;
}
throw new Exception("fail");
}
private static void Test2()
{
Stack<string> myStack = new Stack<string>();
myStack.Push("joe");
myStack.Push("mike");
myStack.Push("adam");
if (myStack.Pop() != "adam") { throw new Exception("fail"); }
myStack.Push("alien");
myStack.Push("nation");
if (myStack.Pop() != "nation") { throw new Exception("fail"); }
if (myStack.Pop() != "alien") { throw new Exception("fail"); }
}
}
}
答案 0 :(得分:4)
我认为Clear()方法可以通过将其更改为top = null;
来显着加快。整个堆栈将被垃圾收集,同时不需要循环。
答案 1 :(得分:3)
你可以简单地使用一个数组。 .NET数组方法非常快。
public class Stack<T>
{
private const int _defaultSize = 4;
private const int _growthMultiplier = 2;
private T[] _elements;
private int _index;
private int _limit;
public Stack()
{
_elements = new T[_defaultSize];
_index = -1;
_limit = _elements.Length - 1;
}
public void Push(T item)
{
if (_index == _limit)
{
var temp = _elements;
_elements = new T[_elements.Length * _growthMultiplier];
_limit = _elements.Length - 1;
Array.Copy(temp, _elements, temp.Length);
}
_elements[++_index] = item;
}
public T Pop()
{
if (_index < 0)
throw new InvalidOperationException();
var item = _elements[_index];
_elements[_index--] = default(T);
return item;
}
public void Clear()
{
_index = -1;
Array.Clear(_elements, 0, _elements.Length);
}
}
答案 2 :(得分:2)
最好使用动态数组作为数据结构而不是链表。数组将具有更好的引用局部性,因为元素彼此相邻。堆栈不需要删除中间元素,拼接等的能力,因此数组就足够了。