2010-07-30 16 views
5

Bunu röportaj koşullarında hızlıca yazdım, muhtemelen daha iyi/daha hızlı/daha temiz bir yol olup olmadığını görmek için toplulukta yayınlamak istedim. Bu nasıl optimize edilebilir?Yığının bu C# uygulamasında herhangi bir sorun var mı?

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

'StackElement' sarmalayıcısının gerekliliğinden biraz şüpheliyim. – ChaosPandion

+2

@ChaosPandion: Aslında bir bağlantılı liste. – SLaks

+0

Çok küçük bir şey, bir cevaba değmez - StackElement sınıfını özel iç içe geçmiş bir Stack sınıfı yapardım. –

cevap

3

Sadece bir dizi kullanabilirsiniz. .NET dizi yöntemleri gerçekten hızlı.

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); 
    } 
} 
+0

Ölçek()? O nedir? – recursive

+0

@Recurive - Diziyi dinamik olarak gerektiğinde büyüyecektir. – ChaosPandion

+0

Sanırım Clear() yönteminiz, 'Array.Clear (...) yerine' _index = 0; 'olmalıdır; current Geçerli kodla, yığın, Clear (Temizle) çağrısı yaptıktan sonra içinde öğeleri olduğunu düşünecektir.) – recursive

4

ben Temizle() yöntemi top = null; bunu değiştirerek önemli ölçüde hızlandırdı olabileceğini düşünüyorum. Tüm yığın, toplanan çöpler ve ortalama zamanda döngü gerektirmez.

2

Bağlı bir liste yerine veri yapısı olarak dinamik dizi kullanmak tercih edilebilir. Dizi birbiri ardına olduğu için dizinin daha iyi referans noktası olacaktır. Bir yığının ortadaki elemanları silmek için yeteneğe ihtiyacı yoktur, böylece bir dizi yeterlidir.

İlgili konular