Видите какие-либо проблемы с этой реализацией стека C #? - PullRequest
5 голосов
/ 30 июля 2010

Я написал это быстро в условиях собеседования, я хотел опубликовать его в сообществе, чтобы, возможно, посмотреть, есть ли лучший / быстрый / чище способ сделать это.Как это можно оптимизировать?

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"); }

        }

    }
}

Ответы [ 3 ]

4 голосов
/ 30 июля 2010

Я думаю, что метод Clear () можно значительно ускорить, изменив его на top = null;. Весь стек будет собираться мусором, и в это время цикл не требуется.

3 голосов
/ 30 июля 2010

Вы можете просто использовать массив.Методы массива .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 голосов
/ 30 июля 2010

Может быть предпочтительнее использовать динамический массив в качестве структуры данных вместо связанного списка.Массив будет иметь лучшую локальность ссылок, потому что элементы расположены рядом друг с другом.Стек не нуждается в способности удалять элементы посередине, сращивания и т. Д., Поэтому достаточно массива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...