๐ŸŽต C#, Unity | Part 2 - ์„น์…˜ 1. ์„ ํ˜• ์ž๋ฃŒ ๊ธฐ์ดˆ

๋ฐฐ์—ด, ๋™์ ๋ฐฐ์—ด, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋น„๊ต

์„ ํ˜• ๊ตฌ์กฐ
์„ ํ˜• ๊ตฌ์กฐ๋Š” ์ž๋ฃŒ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๋‚˜์—ดํ•œ ํ˜•ํƒœ

  • ๋ฐฐ์—ด
  • ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ
  • ์Šคํƒ / ํ

๋น„์„ ํ˜• ๊ตฌ์กฐ
๋น„์„ ํ˜• ๊ตฌ์กฐ๋Š” ํ•˜๋‚˜์˜ ์ž๋ฃŒ ๋’ค์— ๋‹ค์ˆ˜์˜ ์ž๋ฃŒ๊ฐ€ ์˜ฌ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ

  • ํŠธ๋ฆฌ
  • ๊ทธ๋ž˜ํ”„

/ ๊ตฌ๋ถ„์„  /

๋ฐฐ์—ด :

  • ์‚ฌ์šฉํ•  ๋ฐฉ ๊ฐœ์ˆ˜๋ฅผ ๊ณ ์ •ํ•ด์„œ ๊ณ„์•ฝํ•˜๊ณ  (์ ˆ๋Œ€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€)
  • ์—ฐ์†๋œ ๋ฐฉ์œผ๋กœ ๋ฐฐ์ • ๋ฐ›์•„ ์‚ฌ์šฉ
    ์žฅ์  : ์—ฐ์†๋œ ๋ฐฉ
    ๋‹จ์  : ๋ฐฉ์„ ์ถ”๊ฐ€/์ถ•์†Œ ๋ถˆ๊ฐ€

๋™์  ๋ฐฐ์—ด :

  • ์‚ฌ์šฉํ•  ๋ฐฉ ๊ฐœ์ˆ˜๋ฅผ ์œ ๋™์ ์œผ๋กœ ๊ณ„์•ฝ
  • ์—ฐ์†๋œ ๋ฐฉ์œผ๋กœ ๋ฐฐ์ • ๋ฐ›์•„ ์‚ฌ์šฉ
    ๋ฌธ์ œ์  : ์ด์‚ฌ ๋น„์šฉ์€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋‚˜?
    ๋™์  ๋ฐฐ์—ด ํ• ๋‹น ์ •์ฑ… :
  • ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ๋ฐฉ๋ณด๋‹ค ๋งŽ์ด, ์—ฌ์œ ๋ถ„์„ ๋‘๊ณ  (๋Œ€๋žต 1.5~2๋ฐฐ) ์˜ˆ์•ฝ
  • ์ด์‚ฌ ํšŸ์ˆ˜๋ฅผ ์ตœ์†Œํ™”
    ์žฅ์  : ์œ ๋™์ ์ธ ๊ณ„์•ฝ (๋ฐฉ ์ถ”๊ฐ€ ์˜ˆ์•ฝ์œผ๋กœ ์ด์‚ฌ ํšŸ์ˆ˜ ์ตœ์†Œํ™”)
    ๋‹จ์  : ์ค‘๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ์–ด๋ ต๋‹ค.

์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ :

  • ์—ฐ์†๋˜์ง€ ์•Š์€ ๋ฐฉ์„ ์‚ฌ์šฉ
    ์žฅ์  : ์ค‘๊ฐ„ ์ถ”๊ฐ€/์‚ญ์ œ ์ด์ 
    ๋‹จ์  : N๋ฒˆ์งธ ๋ฐฉ์„ ๋ฐ”๋กœ ์ฐพ์„ ์ˆ˜๊ฐ€ ์—†์Œ (์ž„์˜ ์ ‘๊ทผ Random Access๋ถˆ๊ฐ€)

๋™์  ๋ฐฐ์—ด ๊ตฌํ˜„ ์—ฐ์Šต

class MyList<T> //๋ฆฌ์ŠคํŠธ๋Š” ์ œ๋„ค๋ฆญํ˜•์‹์ด๋ฏ€๋กœ<T>๋ฅผ ๋„ฃ์–ด์ค€๋‹ค
{
    const int DEFAULTSize = 1; // ๋ฐฐ์—ด์˜ ์‚ฌ์ด์ฆˆ ์„ ์–ธ
    T[] _data = new T[DEFAULTSize]; // ๋ฐฐ์—ด ์„ ์–ธ

    public int Count = 0; // ์‹ค์ œ๋กœ ์‚ฌ์šฉ์ค‘์ธ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜
    public int Capacity { get { return _data.Length; } } // ์˜ˆ์•ฝ๋œ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜

    // ์‹œ๊ฐ„ ๋ณต์žก๋„ : 0(1) ์˜ˆ์™ธ ์ผ€์ด์Šค : ์ด์‚ฌ ๋น„์šฉ์€ ๋ฌด์‹œํ•œ๋‹ค.
    public void Add(T item) // ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
    {
        // 1. ๊ณต๊ฐ„์ด ์ถฉ๋ถ„ํžˆ ๋‚จ์•„ ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
        if (Count >= Capacity)
        {
            // ๊ณต๊ฐ„์„ ๋Š˜๋ ค์„œ ๋‹ค์‹œ ํ™•๋ณดํ•œ๋‹ค
            T[] newArray = new T[Count * 2];
            for (int i = 0; i < Count; i++) //์ด์‚ฌ๋ฅผ ์‹œ์ผœ์ค€๋‹ค
            {
                newArray[i] = _data[i];
            }
            _data = newArray;
        }
        // 2. (๊ณต๊ฐ„์ด ํ™•๋ณด๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •์‹œ) ๊ณต๊ฐ„์—๋‹ค๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.
        _data[Count] = item;
        Count++;
    }

    // ์‹œ๊ฐ„ ๋ณต์žก๋„ : 0(1)
    public T this[int index] // ์ธ๋ฑ์„œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ถ€๋ถ„
    {
        get { return _data[index]; }
        set { _data[index] = value; }
    }

    // ์‹œ๊ฐ„ ๋ณต์žก๋„ : 0(N)
    public void ReoteAt(int index)
    {
        // 101 102 103 104 105๋ฒˆ ๋ฐฉ์ด ์žˆ์„ ์‹œ
        // 103 ๋ฒˆ๋ฐฉ์„ ์ง€์šธ๋•Œ (*103์ด ์—†์–ด์งˆ ๋–„*) 104 /105๋ฅผ ์•ž์œผ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค
        for (int i = index; i < Count - 1; i++)
            _data[i] = _data[Count + 1];
        _data[Count - 1] = default(T);
        Count--;
    }
}
public void Initialize()
{
        // ๋™์  ๋ฐฐ์—ด 
        _data2.Add(101);
        _data2.Add(102);
        _data2.Add(103);
        _data2.Add(104);
        _data2.Add(105);

        int temp = _data2[2];
        // ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
        // ์ธ๋ฑ์„œ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•œ๋‹ค
        // 103์ด ์ถ”์ถœ๋œ๋‹ค.

        _data2.RemoveAt(2);
        // ๋ฐ์ดํ„ฐ ์‚ญ์ œ
        // ๋ช‡๋ฒˆ์งธ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•œ๋‹ค.
}

์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„ ์—ฐ์Šต

public void Initialize()
{
        // ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ
        _data3.AddLast(101);
        _data3.AddLast(102);
        LinkedListNode<int> node = _data3.AddLast(103);
        _data3.AddLast(104);
        _data3.AddLast(105);
  	
  	_data3.Remove(node);
}
class MyLinkedListNode<T>
{
        public T Data;
        public MyLinkedListNode<T> Next; // ๋‹ค์Œ ๋ฐฉ
        public MyLinkedListNode<T> Prev; // ์ด์ „๋ฐฉ
}
    class MyLinkedList<T>
    {
        public MyLinkedListNode<T> Head = null; // ์ฒซ๋ฒˆ์งธ
        public MyLinkedListNode<T> Tail = null; // ๋งˆ์ง€๋ง‰
        public int Count = 0;

  	// ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” 0(1)
        public MyLinkedListNode<T> AddLast(T data) // ์ƒˆ๋กœ์šด ๋ฐฉ์„ ๋‹ฌ๋ผ๊ณ  ์š”๊ตฌํ•  ๋•Œ์—
        {
            MyLinkedListNode<T> newRoom = new MyLinkedListNode<T>(); // ์ƒˆ๋กœ ๋งŒ๋“  ๋ฐฉ
            newRoom.Data = data; // ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.

            // ๋งŒ์•ฝ์— ์•„์ง ๋ฐฉ์ด ์•„์˜ˆ ์—†์—ˆ๋‹ค๋ฉด, ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ ๋ฐฉ์ด ๊ณง Head์ด๋‹ค.
            if (Head == null)
            { 
                Head = newRoom;
            }

            // 101, 102, 103, ๋งŒ ์žˆ๋‹ค๊ฐ€ 104๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด 104๊ฐ€ ๋์ด๋‹ค.
            // ๊ธฐ์กด์˜ [๋งˆ์ง€๋ง‰ ๋ฐฉ]๊ณผ [์ƒˆ๋กœ ์ถ”๊ฐ€ ๋˜๋Š” ๋ฐฉ]์„ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค.
            if (Tail != null)
            {
                Tail.Next = newRoom;
                newRoom.Prev = Tail;
            }

            // [์ƒˆ๋กœ ์ถ”๊ฐ€๋˜๋Š” ๋ฐฉ]์„ [๋งˆ์ง€๋ง‰ ๋ฐฉ]์œผ๋กœ ์ธ์ •ํ•œ๋‹ค.
            Tail = newRoom;
            Count++;
            return newRoom;
        }
  
	// ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” 0(1)
        // 101 102 103 104 105
        public void Remove(MyLinkedListNode<T> room)
        {
            // [๊ธฐ์กด์˜ ์ฒซ๋ฒˆ์งธ ๋ฐฉ์˜ ๋‹ค์Œ ๋ฐฉ]์„ [์ฒซ๋ฒˆ์งธ ๋ฐฉ์œผ๋กœ] ์ธ์ •ํ•œ๋‹ค.
            if (Head == room)
                Head = Head.Next;

            // [๊ธฐ์กด์˜ ๋งˆ์ง€๋ง‰ ๋ฐฉ์˜ ์ด์ „ ๋ฐฉ]์„ [๋งˆ์ง€๋ง‰ ๋ฐฉ์œผ๋กœ] ์ธ์ •ํ•œ๋‹ค.
            if (Tail == room)
                Tail = Tail.Prev;

            // ์ด์ „์˜ ๋ฐฉ์ด ์žˆ๋‹ค๋ฉด ์ด์ „ ๋ฐฉ์˜ ๋‹ค์Œ ๋ฐฉ์„ ์—ฐ๊ฒฐํ•œ๋‹ค
            // 103๋ฒˆ์„ ์‚ญ์ œํ• ๋•Œ 102๋ฒˆ๊ณผ 104๋ฒˆ์„ ์—ฐ๊ฒฐํ•œ๋‹ค
            if (room.Prev != null)
                room.Prev.Next = room.Next;

            if (room.Next != null)
                room.Next.Prev = room.Prev;

            Count--;
        }
    }

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ