ShovelingLife
A Game Programmer
ShovelingLife
전체 방문자
오늘
어제
  • 분류 전체보기 (1072)
    • 그래픽스 (57)
      • 공통 (19)
      • 수학 물리 (22)
      • OpenGL & Vulkan (1)
      • DirectX (14)
    • 게임엔진 (183)
      • Unreal (69)
      • Unity (103)
      • Cocos2D-X (3)
      • 개인 플젝 (8)
    • 코딩테스트 (221)
      • 공통 (7)
      • 프로그래머스 (22)
      • 백준 (162)
      • LeetCode (19)
      • HackerRank (2)
      • 코딩테스트 알고리즘 (8)
    • CS (235)
      • 공통 (21)
      • 네트워크 (44)
      • OS & 하드웨어 (55)
      • 자료구조 & 알고리즘 (98)
      • 디자인패턴 (6)
      • UML (4)
      • 데이터베이스 (7)
    • 프로그래밍 언어 (348)
      • C++ (167)
      • C# (90)
      • Java (9)
      • Python (33)
      • SQL (30)
      • JavaScript (8)
      • React (7)
    • 그 외 (9)
      • Math (5)
      • 일상 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Source Code 좌측 상단에 복사 버튼 추가 완료
  • 언리얼 엔진 C++ 빌드시간 단축 꿀팁
  • 게임 업계 코딩테스트 관련
  • 1인칭 시점으로 써내려가는 글들

인기 글

태그

  • string
  • C
  • SQL
  • 언리얼
  • C++
  • 클래스
  • 백준
  • Unity
  • 함수
  • c#
  • 그래픽스
  • 배열
  • 포인터
  • 오블완
  • 파이썬
  • 유니티
  • 문자열
  • 프로그래머스
  • 알고리즘
  • 티스토리챌린지

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ShovelingLife

A Game Programmer

[C#] 연결 리스트(Linked List)란?
CS/자료구조 & 알고리즘

[C#] 연결 리스트(Linked List)란?

2023. 8. 29. 11:34

1. 연결 리스트(Linked List)란?

* 연결 리스트(Linked List) : 데이터를 저장하는 자료구조. 각 노드가 데이터와 포인터를 가지고 있으면서 노드들이 한 줄로 쭉 연결되어 있는 방식.

2. 단일 연결 리스트(Singly Linked List)

 : 단방향으로 노드들을 연결한 간단한 자료 구조.

(ex) 아래는 4개의 노드를 갖는 단일 연결 리스트를 그림으로 표현한 것.

using System;

public class LinkedList_Study<T>
{
    public T Data { get; set; }
    public LinkedList_Study<T> Next { get; set; }
    public LinkedList_Study(T data)
    {
        this.Data = data;
        this.Next = null;
    }

    private LinkedList_Study<T> head;

    public void Add(LinkedList_Study<T> newNode) // 새 노드를 추가.
    {
        if (head == null) head = newNode; //리스트가 비어 있을 때 head에 새 노드를 할당.
        else // 리스트가 비어있지 않을 때.
        {
            var current = head;
            while (current != null && current.Next != null)  // 마지막 노드(Tail)로 이동하여 추가.
                current = current.Next;
            current.Next = newNode;
        }
    }

    public void AddAfter(LinkedList_Study<T> current, LinkedList_Study<T> newNode) //새 노드를 중간에 삽입.
    {
        if (head == null || current == null || newNode == null)
            throw new InvalidOperationException();
        newNode.Next = current.Next;
        current.Next = newNode;
    }

    public void Remove(LinkedList_Study<T> removeNode) // 특정 노드를 삭제.
    {
        if (head == null || removeNode == null) return;
        if(removeNode == head)
        {
            head = head.Next;
            removeNode = null;
        }
        else
        {
            var current = head;
            while (current != null && current.Next != removeNode) current = current.Next;
            if(current != null)
            {
                current.Next = removeNode.Next;
                removeNode = null;
            }
        }
    }

    public LinkedList_Study<T> GetNode(int index) // 지정한 위치에 있는 노드를 반환.
    {
        var current = head;
        for (int i = 0; i < index && current != null; i++)
        {
            current = current.Next;
        }
        return current;
    }

    public int Count() // head부터 마지막 노드까지 이동하면서 카운트 증가(노드가 몇개 있는지)
    {
        int cnt = 0;
        var current = head;
        while(current != null)
        {
            cnt++;
            current = current.Next;
        }
        return cnt;
    }
}

 

3. 이중 연결 리스트(Double Linked List)

: 이전 노드와 다음 노드를 가리키는 포인터를 모두 갖고 있어 양방향으로 탐색이 가능한 자료구조.

(ex) 아래 그림은 4개의 노드를 갖는 이중 연결 리스트를 표현한 것.

using System;

public class LinkedList_Study2<T> //이중 링크 리스트 구현
{
    public T Data { get; set; }
    public LinkedList_Study2<T> Prev { get; set; }
    public LinkedList_Study2<T> Next { get; set; }

    public LinkedList_Study2(T data, LinkedList_Study2<T> prev, LinkedList_Study2<T> next)
    {
        this.Data = data;
        this.Prev = prev;
        this.Next = next;
    }

    public LinkedList_Study2(T data) 
        : this(data, null, null) { }

    private LinkedList_Study2<T> head;

    public void Add(LinkedList_Study2<T> newNode) //새 노드 추가.
    {
        if (head == null) head = newNode; //리스트가 비어있으면 head에 새 노드 할당
        else //비어 있지 않을 때
        {
            var current = head;
            while (current != null && current.Next != null)
                current = current.Next;
            current.Next = newNode;
            newNode.Prev = current;
            newNode.Next = null;
        }
    }

    public void AddAfter(LinkedList_Study2<T> current, LinkedList_Study2<T> newNode) //새 노드를 중간에 삽입
    {
        if (head == null || current == null || newNode == null)
            throw new InvalidOperationException();
        newNode.Next = current.Next;
        current.Next.Prev = newNode;
        newNode.Prev = current;
        newNode.Next = newNode;
    }

    public void Remove(LinkedList_Study2<T> removeNode) //특정 노드 삭제
    {
        if (head == null || removeNode == null) return;
        if(removeNode == head)
        {
            head = head.Next;
            if (head != null) head.Prev = null;
        }
        else
        {
            removeNode.Prev.Next = removeNode.Next;
            if (removeNode.Next != null)
                removeNode.Next.Prev = removeNode.Prev;
        }
        removeNode = null;
    }

    public LinkedList_Study2<T> GetNode(int index) //지정한 위치의 노드 반환
    {
        var current = head;
        for (int i = 0; i < index && current != null; i++)
        {
            current = current.Next;
        }
        return current;
    }

    public int Count()
    {
        int cnt = 0;
        var current = head;
        while(current != null)
        {
            cnt++;
            current = current.Next;
        }
        return cnt;
    }
}

4. 원형 연결 리스트(Circular Linked List)

: 일반 연결 리스트에서 마지막 노드를 처음 노드에 연결시켜 만든 구조.

(ex) 아래 그림은 4개의 노드를 갖는 원형 이중 연결 리스트를 표현한 것.

using System;

public class LinkedList_Study3<T> //이중 링크 리스트 구현
{
    public T Data { get; set; }
    public LinkedList_Study3<T> Prev { get; set; }
    public LinkedList_Study3<T> Next { get; set; }

    public LinkedList_Study3(T data, LinkedList_Study3<T> prev, LinkedList_Study3<T> next)
    {
        this.Data = data;
        this.Prev = prev;
        this.Next = next;
    }
    private LinkedList_Study3<T> head;

    public void Add(LinkedList_Study3<T> newNode) //새 노드 추가.
    {
        if (head == null) //리스트가 비어있으면 head에 새 노드 할당
        {
            head = newNode;
            head.Next = head;
            head.Prev = head;
        }
        else //비어 있지 않을 때
        {
            var tail = head.Prev;
            head.Prev = newNode;
            tail.Next = newNode;
            newNode.Prev = tail;
            newNode.Next = head;
        }
    }

    public void AddAfter(LinkedList_Study3<T> current, LinkedList_Study3<T> newNode) //새 노드를 중간에 삽입
    {
        if (head == null || current == null || newNode == null)
            throw new InvalidOperationException();
        newNode.Next = current.Next;
        current.Next.Prev = newNode;
        newNode.Prev = current;
        newNode.Next = newNode;
    }

    public void Remove(LinkedList_Study3<T> removeNode) //특정 노드 삭제
    {
        if (head == null || removeNode == null) return;
        if (removeNode == head && head == head.Next) //삭제할 노드가 헤드 노드이고, 노드가 1개일 때
            head = null;
        else //아니면 Prev 노드와 Next 노드를 연결
        {
            removeNode.Prev.Next = removeNode.Next;
            removeNode.Next.Prev = removeNode.Prev;
        }
        removeNode = null;
    }

    public LinkedList_Study3<T> GetNode(int index) //지정한 위치의 노드 반환
    {
        if (head == null) return null;
        int cnt = 0;
        var current = head;
        while(cnt < index)
        {
            current = current.Next;
            cnt++;
            if (current == head) return null;
        }
        return current;
    }

    public int Count()
    {
        int cnt = 0;
        var current = head;
        do
        {
            cnt++;
            current = current.Next;
        } while (current != head);
        return cnt;
    }
}

 

아래는 원형 연결 리스트인지 체크하는 함수

public static bool is_Circular(LinkedList_Study3<T> head) // 원형 연결 리스트인지 체크
{
    if (head == null) return true;
    var current = head;
    while(current != null)
    {
        current = current.Next;
        if (current == head) return true;
    }
    return false;
}

 

아래와 같이 중간부터 원형을 보이는 연결 리스트도 있는데요, 다음과 같은 함수로 이 또한 체크할 수 있다.

public static bool is_Cyclic(LinkedList_Study3<int> head) //연결리스트 중간에 원형이 있는지 체크
{
    var p1 = head;
    var p2 = head;
    do
    {
        p1 = p1.Next;
        p2 = p2.Next;
        if (p1 == null || p2 == null || p2.Next == null) return false;
        p2 = p2.Next;
    } while (p1 != p2);
    return true;
}

[C# 기초] #18.연결 리스트(Linked List)란? (tistory.com)

저작자표시 (새창열림)

'CS > 자료구조 & 알고리즘' 카테고리의 다른 글

에라토스테네스의 체  (0) 2023.09.03
C++ 다익스트라(Dijkstra) 알고리즘 개념 및 구현 (무방향 그래프)  (0) 2023.08.30
[C#] .NET의 연결 리스트 : LinkedList<T>  (0) 2023.08.29
[C#] 힙 (Heap)  (0) 2023.08.29
비헤이비어 트리 (Behavior Tree)  (0) 2023.08.17
    'CS/자료구조 & 알고리즘' 카테고리의 다른 글
    • 에라토스테네스의 체
    • C++ 다익스트라(Dijkstra) 알고리즘 개념 및 구현 (무방향 그래프)
    • [C#] .NET의 연결 리스트 : LinkedList<T>
    • [C#] 힙 (Heap)
    ShovelingLife
    ShovelingLife
    Main skill stack => Unity C# / Unreal C++ Studying Front / BackEnd, Java Python

    티스토리툴바