Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

See any problems with this C# implementation of a stack?

I wrote this quickly under interview conditions, I wanted to post it to the community to possibly see if there was a better/faster/cleaner way to go about it. How could this be optimized?

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

        }

    }
}
like image 604
j03m Avatar asked Jul 30 '10 03:07

j03m


People also ask

What is problem solving using C?

This course is aimed at enabling the students to. Formulate simple algorithms for arithmetic and logical problems. Translate the algorithms to programs (in C language) Test and execute the programs and correct syntax and logical errors. Implement conditional branching, iteration and recursion.

Why do I get segmentation fault in C?

A segmentation fault occurs when your program attempts to access an area of memory that it is not allowed to access. In other words, when your program tries to access memory that is beyond the limits that the operating system allocated for your program. Used to being properly initialized.

Why is C difficult?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.

What is C used for these days?

Originally the programming language was developed to cater to writing system software. Today C is used to develop firmware and applications. It's a procedural language that provides low-level access to multiple system memories.


3 Answers

I think the Clear() method could be sped up significantly by changing it to top = null;. The entire stack will be garbage collected, and no loop required in the mean time.

like image 101
recursive Avatar answered Oct 13 '22 00:10

recursive


You could simply use an array. The .NET array methods are really fast.

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);
    }
}
like image 37
ChaosPandion Avatar answered Oct 12 '22 22:10

ChaosPandion


Might be preferable to use dynamic array as the data structure instead of a linked list. The array will have better locality of reference because the elements are next to each other. A stack doesn't need ability to delete elements in the middle, splicing etc. so an array suffices.

like image 28
seand Avatar answered Oct 12 '22 23:10

seand