DynamicArray of T

최승원·2024년 2월 3일

DynamicArrayOfT.cs

IEnumerable< T > 인터페이스를 상속받는 동적배열 generic 클래스입니다.

using System;
using System.Collections;
using System.Collections.Generic;

namespace Collections
{
    internal class DynamicArray<T> : IEnumerable<T>
        where T : IComparable<T>
    {
        private static int DEFAULT_SIZE = 1;
        
        public int Count => _count;
        public int Capacity => _items.Length;

        public T this[int index] // 인덱스 프로퍼티
        {
            get
            {
                if ((uint)index >= _count)
                {
                    throw new IndexOutOfRangeException();
                }

                return _items[index];
            }
            set
            {
                if ((uint)index >= _count)
                {
                    throw new IndexOutOfRangeException();
                }

                _items[index] = value;
            }
        }

        private T[] _items = new T[DEFAULT_SIZE];
        private int _count;

        // 삽입 알고리즘
        // 일반적인 경우에는 O(1), 공간이 모자란 경우에는 O(N) 
        public void Add(T item)
        {
            if (_count == _items.Length)
            {
                T[] tmpItems = new T[_count * 2];
                Array.Copy(_items, 0, tmpItems, 0, _count);
                _items = tmpItems;
            }

            _items[_count++] = item;
        }

        // 탐색 알고리즘
        // 최악의 경우 O(N)
        public T Find(Predicate<T> match)
        {
            for (int i = 0; i < _count; i++)
            {
                if (match.Invoke(_items[i]))
                {
                    return _items[i];
                }
            }

            return default(T);
        }
        
        // 탐색 알고리즘
        // 최악의 경우 O(N)
        // 공간 복잡도도 최악의 경우 O(N)
        public MyDynamicArray<T> FindAll(Predicate<T> match)
        {
            MyDynamicArray<T> result = new MyDynamicArray<T>();
            
            for (int i = 0; i < _count; i++)
            {
                if (match.Invoke(_items[i]))
                {
                    result.Add(_items[i]);
                }
            }

            return result;
        }
        
        // 탐색 알고리즘
        // 최악의 경우 O(N)
        public int IndexOf(T item)
        {
            for (int i = 0; i < _count; i++)
            {
                if (Comparer<T>.Default.Compare(_items[i], item) == 0)
                {
                    return i;
                }
            }

            return -1;
        }

        // 삭제 알고리즘
        public bool Remove(T item)
        {
            int index = IndexOf(item);

            if (index < 0)
            {
                return false;
            }

            for (int i = index; i < _count; i++)
            {
                _items[i] = _items[i + 1];
            }

            _count--;
            return true;
        }
        
        public IEnumerator<T> GetEnumerator()
        {
            for (int i = 0; i < _count; i++)
            {
                yield return _items[i];
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Enumerator(this);
        }

        public struct Enumerator : IEnumerator<T>
        {
            public bool MoveNext()
            {
                _index++;
                return _index < _data._count;
            }

            public void Reset()
            {
                _index = -1;
            }

            public T Current => _data._items[_index];

            object IEnumerator.Current => _data._items[_index];

            private MyDynamicArray<T> _data;
            private int _index;
            public Enumerator(MyDynamicArray<T> data)
            {
                _data = data;
                _index = -1; // MoveNext()를 먼저 호출하기 때문에 -1로 초기화;
            }

            public void Dispose() // 관리되지 않는 힙 영역(Unmanagerd Heap Memory) 에 올라간 데이터는 직접 해제를 해줘야 한다.
                                  // 관리되는 힙 영역(Managed Heap Memory)에 올라간 데이터는 GC가 관리해준다.
            {
                throw new NotImplementedException();
            }
        }
    }
}
profile
안녕하세요. 최승원입니다.

0개의 댓글