전체 코드

using System.ComponentModel;
using System.Numerics;
using System.Threading;
using System.Collections.Generic;

namespace CSharp
{
    
    
    class Program
    {
        

        static void Main(string[] args)
        {
            // List
            // 데이터가 많아지면 동적으로 변경이 불가능하다.
            // 따라서 새로운 형태
            // 데이터가 커짐에 따라 크기가 유동적으로 변함

            // List <- 동적 배열
            List<int> list = new List<int>();
            //List<float> listFloat;
            // <> 안에 타입을 넣어준다.    

            // 생성을 바로 했을 경우는 빈 상태
            // 바로 접근하면 OutofRange 에러 발생
            
            // 리스트가 한 개이상 있어야 실행됨

            // Add : 맨 뒤에 추가
            for (int i = 0; i < 5; i++)
            {
                list.Add(i);
            }

            // List 출력
            for (int i = 0; i<5; i++)
            {
                Console.WriteLine(list[i]);
            }

            // foreach 사용
            foreach (int num in list)
            {
                Console.WriteLine(num);
            }

            // 삽입 : 중간 삽입
            list.Insert(2, 999);

            for (int i = 0; i < list.Count; i++)
            {
                list.Add(i);
            }

            foreach (int num in list)
            {
                Console.WriteLine(num);
            }

            // 삭제
            bool success = list.Remove(3); // 검색해서 맨 처음 3을 삭제함

            list.RemoveAt(0); // 인덱스로 삭제

            list.Clear(); // 전체 삭제

            // 항상 복사가 일어나서 삽입 삭제가 효율적이지 않음
        }
    }
}

1️⃣ List란 무엇인가?

List<T>동적 배열이다.
✅ 배열처럼 연속된 메모리를 사용하지만, 크기가 자동으로 늘어나며 관리된다.
✅ 내부적으로는 배열을 감싼 래퍼 클래스로, 데이터가 가득 차면 더 큰 배열로 복사하여 확장하는 구조.

C++의 vector와 거의 동일한 개념

2️⃣ List 기본 문법과 생성

네임스페이스 임포트

using System.Collections.Generic;
  • List<T>System.Collections.Generic에 포함
  • 제네릭 컬렉션이라 반드시 제네릭 타입 명시 필요

리스트 선언과 생성

List<int> list = new List<int>();
키워드설명
List정수형 동적 배열 선언
new List()실제 메모리 할당 (힙 영역에 생성)

3️⃣ List 주요 메서드 상세 분석

1. Add - 맨 끝에 추가

list.Add(1);
  • 현재 리스트 끝에 값 1 추가
  • 내부 배열 공간이 모자라면 더 큰 배열을 새로 할당하고 기존 데이터를 복사 (자동 확장)

2. Insert - 중간 삽입

list.Insert(2, 999);
  • 인덱스 2 위치에 값 999 삽입
  • 이후 원소들이 한 칸씩 밀림 (비효율적)

3. Remove - 값으로 삭제

list.Remove(3);
  • 값이 3인 원소를 찾아 삭제
  • 첫 번째로 발견된 값만 삭제
  • 삭제 성공 시 true 반환, 없으면 false

4. RemoveAt - 인덱스로 삭제

list.RemoveAt(0);
  • 인덱스 0의 원소 삭제
  • 이후 원소들이 한 칸씩 당겨짐 (비효율적)

5. Clear - 전체 삭제

list.Clear();
  • 모든 원소 제거, 리스트 비움

6. Count - 현재 길이 확인

Console.WriteLine(list.Count);
  • 리스트에 저장된 현재 원소 개수 반환
  • 프로퍼티라 괄호 없이 사용

4️⃣ 배열과 List 비교

구분배열 (Array)List
크기고정가변 (자동 확장)
선언int[] arrList<int>
메모리연속된 메모리연속된 메모리 (내부적으로 배열 기반)
요소 접근빠름 (O(1))빠름 (O(1))
삽입 삭제비효율적끝 삽입만 효율적, 중간 삽입/삭제는 비효율적
공간 관리직접자동 관리

5️⃣ 성능과 내부 동작 분석

✔️ Add 동작 원리

  1. 빈 공간이 있으면 끝에 바로 추가 (O(1))
  2. 빈 공간이 없으면 더 큰 배열 새로 할당 (기존 2배 크기)
  3. 기존 데이터를 모두 복사
  4. 새 배열 끝에 데이터 추가

⚠️ 평균적으로는 빠르지만, 특정 시점에서 큰 비용 발생 (재할당 + 복사)


✔️ 중간 삽입/삭제 동작 원리

  • 삽입/삭제 위치 이후의 모든 원소를 한 칸씩 이동 (O(n))
  • 동적 배열의 가장 큰 단점

profile
李家네_공부방

0개의 댓글