๐Ÿ“Œ ๋ฐฐ์—ด Array

๊ฐ™์€ ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ

๋ฐฐ์—ด: int arr[5] = {10, 20, 30, 40, 50};

๋ฉ”๋ชจ๋ฆฌ:
์ฃผ์†Œ    | 1000 | 1004 | 1008 | 1012 | 1016 |
--------|------|------|------|------|------|
์ธ๋ฑ์Šค  |  0   |  1   |  2   |  3   |  4   |
๊ฐ’      |  10  |  20  |  30  |  40  |  50  |

์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅ โœ”

๐Ÿ”ง ๋ฐฐ์—ด์˜ ๊ธฐ๋ณธ ์—ฐ์‚ฐ

1. ์„ ์–ธ ๋ฐ ์ดˆ๊ธฐํ™”

// ์„ ์–ธ
int arr[5];

// ์„ ์–ธ๊ณผ ๋™์‹œ์— ์ดˆ๊ธฐํ™”
int arr[5] = {10, 20, 30, 40, 50};

// ๋ถ€๋ถ„ ์ดˆ๊ธฐํ™” (๋‚˜๋จธ์ง€๋Š” 0)
int arr[5] = {10, 20};  // {10, 20, 0, 0, 0}

// ๋ชจ๋‘ 0์œผ๋กœ ์ดˆ๊ธฐํ™”
int arr[5] = {0};

// ํฌ๊ธฐ ์ƒ๋žต (์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™ ๊ณ„์‚ฐ)
int arr[] = {10, 20, 30};  // ํฌ๊ธฐ: 3

2. ์ ‘๊ทผ (Access)

int arr[5] = {10, 20, 30, 40, 50};

// ์ฝ๊ธฐ
int value = arr[2];  // 30

// ์“ฐ๊ธฐ
arr[2] = 100;  // {10, 20, 100, 40, 50}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(1) โœ” (์ธ๋ฑ์Šค๋กœ ์ง์ ‘ ์ ‘๊ทผ)

์ธ๋ฑ์Šค ๊ณ„์‚ฐ ๊ณต์‹:

์ฃผ์†Œ = ์‹œ์ž‘์ฃผ์†Œ + (์ธ๋ฑ์Šค ร— ๋ฐ์ดํ„ฐํฌ๊ธฐ)

arr[2]์˜ ์ฃผ์†Œ = 1000 + (2 ร— 4) = 1008
(int๋Š” 4๋ฐ”์ดํŠธ)
// ์„ ํ˜• ํƒ์ƒ‰ (Linear Search)
int search(int arr[], int size, int key) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == key) {
            return i;  // ์ฐพ์€ ์ธ๋ฑ์Šค ๋ฐ˜ํ™˜
        }
    }
    return -1;  // ๋ชป ์ฐพ์Œ
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

์˜ˆ์‹œ:

arr[] = {10, 20, 30, 40, 50}
key = 30 ์ฐพ๊ธฐ

๋น„๊ต 1: arr[0] = 10 โ‰  30
๋น„๊ต 2: arr[1] = 20 โ‰  30
๋น„๊ต 3: arr[2] = 30 = 30 โœ” ์ฐพ์Œ!

์ตœ์•…์˜ ๊ฒฝ์šฐ: N๋ฒˆ ๋น„๊ต (๋งจ ๋ ๋˜๋Š” ์—†์Œ)

4. ์‚ฝ์ž… (Insert)

๋งจ ๋’ค ์‚ฝ์ž… (๊ฐ€์žฅ ๋น ๋ฆ„)

int arr[10] = {10, 20, 30, 40, 50};
int size = 5;

// ๋งจ ๋’ค์— 60 ์‚ฝ์ž…
arr[size] = 60;
size++;

// ๊ฒฐ๊ณผ: {10, 20, 30, 40, 50, 60}
// ์‹œ๊ฐ„๋ณต์žก๋„: O(1) โœ”

์ค‘๊ฐ„ ์‚ฝ์ž… (๋А๋ฆผ)

void insertAt(int arr[], int *size, int index, int value) {
    // ๋’ค์—์„œ๋ถ€ํ„ฐ ํ•œ ์นธ์”ฉ ์ด๋™
    for (int i = *size; i > index; i--) {
        arr[i] = arr[i - 1];
    }
    
    arr[index] = value;
    (*size)++;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N) โœ˜

์˜ˆ์‹œ: ์ธ๋ฑ์Šค 2์— 25 ์‚ฝ์ž…

์ดˆ๊ธฐ: {10, 20, 30, 40, 50}
       0   1   2   3   4

1๋‹จ๊ณ„: ๋’ค์—์„œ๋ถ€ํ„ฐ ์ด๋™
{10, 20, 30, 40, 50, 50}  // 50 ๋ณต์‚ฌ
{10, 20, 30, 40, 40, 50}  // 40 ๋ณต์‚ฌ
{10, 20, 30, 30, 40, 50}  // 30 ๋ณต์‚ฌ

2๋‹จ๊ณ„: ํ•ด๋‹น ์œ„์น˜์— ์‚ฝ์ž…
{10, 20, 25, 30, 40, 50}
       0   1   2   3   4   5

์ด๋™ ํšŸ์ˆ˜: 3๋ฒˆ (size - index)

5. ์‚ญ์ œ (Delete)

๋งจ ๋’ค ์‚ญ์ œ (๊ฐ€์žฅ ๋น ๋ฆ„)

int arr[10] = {10, 20, 30, 40, 50};
int size = 5;

// ๋งจ ๋’ค ์‚ญ์ œ
size--;

// ๊ฒฐ๊ณผ: {10, 20, 30, 40} (50์€ ๋ฌด์‹œ๋จ)
// ์‹œ๊ฐ„๋ณต์žก๋„: O(1) โœ”

์ค‘๊ฐ„ ์‚ญ์ œ (๋А๋ฆผ)

void deleteAt(int arr[], int *size, int index) {
    // ์•ž์œผ๋กœ ํ•œ ์นธ์”ฉ ์ด๋™
    for (int i = index; i < *size - 1; i++) {
        arr[i] = arr[i + 1];
    }
    
    (*size)--;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N) โœ˜

์˜ˆ์‹œ: ์ธ๋ฑ์Šค 2 ์‚ญ์ œ

์ดˆ๊ธฐ: {10, 20, 30, 40, 50}
       0   1   2   3   4

1๋‹จ๊ณ„: ์•ž์œผ๋กœ ์ด๋™
{10, 20, 40, 40, 50}  // arr[2] = arr[3]
{10, 20, 40, 50, 50}  // arr[3] = arr[4]

2๋‹จ๊ณ„: ํฌ๊ธฐ ๊ฐ์†Œ
{10, 20, 40, 50}
 0   1   2   3

์ด๋™ ํšŸ์ˆ˜: 2๋ฒˆ (size - index - 1)

๐Ÿ“Š ๋ฐฐ์—ด์˜ ์žฅ๋‹จ์ 

์žฅ์  โœ”

  1. ๋น ๋ฅธ ์ ‘๊ทผ (Random Access)
    arr[100] = 10;  // O(1) - ์ธ๋ฑ์Šค๋กœ ๋ฐ”๋กœ ์ ‘๊ทผ
    
  2. ๊ตฌํ˜„์ด ๊ฐ„๋‹จ
    int arr[100];  // ์„ ์–ธ๋งŒ ํ•˜๋ฉด ๋จ
    
  3. ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ 
    ๋ฐ์ดํ„ฐ๋งŒ ์ €์žฅ (ํฌ์ธํ„ฐ ๋ถˆํ•„์š”)
    int ๋ฐฐ์—ด: 4๋ฐ”์ดํŠธ ร— N๊ฐœ = 4N ๋ฐ”์ดํŠธ
    
  4. ์บ์‹œ ์นœํ™”์  (Cache-Friendly)
    ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ โ†’ CPU ์บ์‹œ ํšจ์œจ ๋†’์Œ
    โ†’ ์„ฑ๋Šฅ ํ–ฅ์ƒ
    

๋‹จ์  โœ˜

  1. ๊ณ ์ • ํฌ๊ธฐ
    int arr[5];  // ํฌ๊ธฐ 5๋กœ ๊ณ ์ •
    // 6๊ฐœ๋ฅผ ์ €์žฅํ•˜๊ณ  ์‹ถ์œผ๋ฉด? โ†’ ์ƒˆ ๋ฐฐ์—ด ์ƒ์„ฑ ํ•„์š”
    
  2. ์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ๋А๋ฆผ
    // ์ค‘๊ฐ„์— ์‚ฝ์ž…/์‚ญ์ œ ์‹œ O(N)
    // ๋ชจ๋“  ์›์†Œ๋ฅผ ์ด๋™ํ•ด์•ผ ํ•จ
    
  3. ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„
    int arr[1000];  // 1000๊ฐœ ์„ ์–ธ
    // ์‹ค์ œ 10๊ฐœ๋งŒ ์‚ฌ์šฉ โ†’ 990๊ฐœ ๋‚ญ๋น„
    
  4. ํฌ๊ธฐ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€
    int arr[5];
    // ๋Ÿฐํƒ€์ž„์— ํฌ๊ธฐ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅ
    // (๋™์  ๋ฐฐ์—ด ์ œ์™ธ)
    

๐Ÿ’ป ๋ฐฐ์—ด ํ™œ์šฉ ์˜ˆ์ œ

1. ์ตœ๋Œ“๊ฐ’/์ตœ์†Ÿ๊ฐ’ ์ฐพ๊ธฐ

int findMax(int arr[], int size) {
    int max = arr[0];
    
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    
    return max;
}

int findMin(int arr[], int size) {
    int min = arr[0];
    
    for (int i = 1; i < size; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
    }
    
    return min;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

2. ๋ฐฐ์—ด ์—ญ์ˆœ ์ •๋ ฌ

void reverse(int arr[], int size) {
    int temp;
    
    for (int i = 0; i < size / 2; i++) {
        // ์–‘ ๋์„ ๊ตํ™˜
        temp = arr[i];
        arr[i] = arr[size - 1 - i];
        arr[size - 1 - i] = temp;
    }
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

์˜ˆ์‹œ:

์ดˆ๊ธฐ: {10, 20, 30, 40, 50}
       0   1   2   3   4

๊ตํ™˜ 1: arr[0] โ†” arr[4]
{50, 20, 30, 40, 10}

๊ตํ™˜ 2: arr[1] โ†” arr[3]
{50, 40, 30, 20, 10}

์ค‘๊ฐ„(arr[2])์€ ๊ทธ๋Œ€๋กœ

3. ์ค‘๋ณต ์ œ๊ฑฐ

int removeDuplicates(int arr[], int size) {
    if (size == 0) return 0;
    
    int newSize = 1;  // ์ฒซ ์›์†Œ๋Š” ํ•ญ์ƒ ํฌํ•จ
    
    for (int i = 1; i < size; i++) {
        int isDuplicate = 0;
        
        // ์ด์ „ ์›์†Œ๋“ค๊ณผ ๋น„๊ต
        for (int j = 0; j < newSize; j++) {
            if (arr[i] == arr[j]) {
                isDuplicate = 1;
                break;
            }
        }
        
        // ์ค‘๋ณต์ด ์•„๋‹ˆ๋ฉด ์ถ”๊ฐ€
        if (!isDuplicate) {
            arr[newSize] = arr[i];
            newSize++;
        }
    }
    
    return newSize;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(Nยฒ)

์˜ˆ์‹œ:

์ดˆ๊ธฐ: {10, 20, 10, 30, 20, 40}

์ฒ˜๋ฆฌ:
10 โ†’ ์ถ”๊ฐ€ (์ฒซ ์›์†Œ)
20 โ†’ ์ถ”๊ฐ€ (์ค‘๋ณต ์•„๋‹˜)
10 โ†’ ์ œ์™ธ (์ค‘๋ณต)
30 โ†’ ์ถ”๊ฐ€ (์ค‘๋ณต ์•„๋‹˜)
20 โ†’ ์ œ์™ธ (์ค‘๋ณต)
40 โ†’ ์ถ”๊ฐ€ (์ค‘๋ณต ์•„๋‹˜)

๊ฒฐ๊ณผ: {10, 20, 30, 40}

๐ŸŽฏ 2์ฐจ์› ๋ฐฐ์—ด

์„ ์–ธ ๋ฐ ์ดˆ๊ธฐํ™”

// ์„ ์–ธ
int arr[3][4];  // 3ํ–‰ 4์—ด

// ์ดˆ๊ธฐํ™”
int arr[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

// ์ผ๊ด„ ์ดˆ๊ธฐํ™”
int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

๋ฉ”๋ชจ๋ฆฌ ๋ฐฐ์น˜ (ํ–‰ ์šฐ์„  ์ˆœ์„œ)

arr[3][4]:

๋…ผ๋ฆฌ์  ๊ตฌ์กฐ:
     col0  col1  col2  col3
row0 [1]   [2]   [3]   [4]
row1 [5]   [6]   [7]   [8]
row2 [9]   [10]  [11]  [12]

์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ (์—ฐ์† ๋ฐฐ์น˜):
[1][2][3][4][5][6][7][8][9][10][11][12]

2์ฐจ์› ๋ฐฐ์—ด ์ˆœํšŒ

int arr[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

// ํ–‰ ์šฐ์„  ์ˆœํšŒ
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 4; j++) {
        printf("%d ", arr[i][j]);
    }
    printf("\n");
}

// ์ถœ๋ ฅ:
// 1 2 3 4
// 5 6 7 8
// 9 10 11 12

์ฃผ์†Œ ๊ณ„์‚ฐ

arr[i][j]์˜ ์ฃผ์†Œ = ์‹œ์ž‘์ฃผ์†Œ + ((i ร— ์—ด๊ฐœ์ˆ˜) + j) ร— ๋ฐ์ดํ„ฐํฌ๊ธฐ

์˜ˆ: arr[1][2]์˜ ์ฃผ์†Œ
= 1000 + ((1 ร— 4) + 2) ร— 4
= 1000 + 6 ร— 4
= 1000 + 24
= 1024

๐Ÿ“Œ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ LinkedList

๋…ธ๋“œ๋“ค์ด ํฌ์ธํ„ฐ๋กœ ์—ฐ๊ฒฐ๋œ ์ž๋ฃŒ๊ตฌ์กฐ

๋…ธ๋“œ ๊ตฌ์กฐ:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ data โ”‚ next โ”‚  โ†’ next: ๋‹ค์Œ ๋…ธ๋“œ์˜ ์ฃผ์†Œ
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ:
Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|โ—] โ†’ [40|NULL]
       1000     2000     3000     4000

๋ฉ”๋ชจ๋ฆฌ๋Š” ๋น„์—ฐ์†์ ! โœ”

๐Ÿ’ป ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„

๋…ธ๋“œ ๊ตฌ์กฐ์ฒด

typedef struct Node {
    int data;           // ๋ฐ์ดํ„ฐ
    struct Node* next;  // ๋‹ค์Œ ๋…ธ๋“œ ํฌ์ธํ„ฐ
} Node;

1. ๋…ธ๋“œ ์ƒ์„ฑ

Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    
    if (newNode == NULL) {
        printf("Memory allocation failed\n");
        return NULL;
    }
    
    newNode->data = data;
    newNode->next = NULL;
    
    return newNode;
}

2. ์‚ฝ์ž… (Insert)

๋งจ ์•ž ์‚ฝ์ž… (Head์— ์‚ฝ์ž…)

void insertFront(Node** head, int data) {
    Node* newNode = createNode(data);
    
    newNode->next = *head;  // ์ƒˆ ๋…ธ๋“œ๊ฐ€ ํ˜„์žฌ head๋ฅผ ๊ฐ€๋ฆฌํ‚ด
    *head = newNode;         // head๋ฅผ ์ƒˆ ๋…ธ๋“œ๋กœ ๋ณ€๊ฒฝ
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(1) โœ”

์˜ˆ์‹œ:

์ดˆ๊ธฐ: Head โ†’ [20|โ—] โ†’ [30|NULL]

10 ์‚ฝ์ž…:

1๋‹จ๊ณ„: ์ƒˆ ๋…ธ๋“œ ์ƒ์„ฑ
[10|NULL]

2๋‹จ๊ณ„: newNode->next = head
[10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]

3๋‹จ๊ณ„: head = newNode
Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]

๋งจ ๋’ค ์‚ฝ์ž… (Tail์— ์‚ฝ์ž…)

void insertBack(Node** head, int data) {
    Node* newNode = createNode(data);
    
    // ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด์žˆ์œผ๋ฉด
    if (*head == NULL) {
        *head = newNode;
        return;
    }
    
    // ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ์ฐพ๊ธฐ
    Node* current = *head;
    while (current->next != NULL) {
        current = current->next;
    }
    
    current->next = newNode;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N) โœ˜ (๋งˆ์ง€๋ง‰๊นŒ์ง€ ์ˆœํšŒ)

์˜ˆ์‹œ:

์ดˆ๊ธฐ: Head โ†’ [10|โ—] โ†’ [20|NULL]

30 ์‚ฝ์ž…:

1๋‹จ๊ณ„: ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ์ฐพ๊ธฐ
Head โ†’ [10|โ—] โ†’ [20|NULL]
                  โ†‘
              current

2๋‹จ๊ณ„: current->next = newNode
Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]

์ค‘๊ฐ„ ์‚ฝ์ž… (ํŠน์ • ์œ„์น˜)

void insertAt(Node** head, int position, int data) {
    Node* newNode = createNode(data);
    
    // ๋งจ ์•ž ์‚ฝ์ž…
    if (position == 0) {
        newNode->next = *head;
        *head = newNode;
        return;
    }
    
    // ์ด์ „ ๋…ธ๋“œ ์ฐพ๊ธฐ
    Node* current = *head;
    for (int i = 0; i < position - 1 && current != NULL; i++) {
        current = current->next;
    }
    
    if (current == NULL) {
        printf("Invalid position\n");
        free(newNode);
        return;
    }
    
    newNode->next = current->next;
    current->next = newNode;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

์˜ˆ์‹œ: ์ธ๋ฑ์Šค 2์— 25 ์‚ฝ์ž…

์ดˆ๊ธฐ: Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]
              0         1         2

1๋‹จ๊ณ„: position-1 (1๋ฒˆ) ๋…ธ๋“œ ์ฐพ๊ธฐ
Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]
                  โ†‘
              current

2๋‹จ๊ณ„: newNode->next = current->next
       current->next = newNode

๊ฒฐ๊ณผ: Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [25|โ—] โ†’ [30|NULL]
              0         1         2         3

3. ์‚ญ์ œ (Delete)

๋งจ ์•ž ์‚ญ์ œ

void deleteFront(Node** head) {
    if (*head == NULL) {
        printf("List is empty\n");
        return;
    }
    
    Node* temp = *head;
    *head = (*head)->next;
    free(temp);
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(1) โœ”

์˜ˆ์‹œ:

์ดˆ๊ธฐ: Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]

1๋‹จ๊ณ„: temp = head
temp โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]
  โ†“
Head

2๋‹จ๊ณ„: head = head->next
Head โ†’ [20|โ—] โ†’ [30|NULL]
temp โ†’ [10|โ—]

3๋‹จ๊ณ„: free(temp)
Head โ†’ [20|โ—] โ†’ [30|NULL]

๋งจ ๋’ค ์‚ญ์ œ

void deleteBack(Node** head) {
    if (*head == NULL) {
        printf("List is empty\n");
        return;
    }
    
    // ๋…ธ๋“œ๊ฐ€ 1๊ฐœ๋งŒ ์žˆ์„ ๋•Œ
    if ((*head)->next == NULL) {
        free(*head);
        *head = NULL;
        return;
    }
    
    // ๋งˆ์ง€๋ง‰ ์ด์ „ ๋…ธ๋“œ ์ฐพ๊ธฐ
    Node* current = *head;
    while (current->next->next != NULL) {
        current = current->next;
    }
    
    free(current->next);
    current->next = NULL;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N) โœ˜

ํŠน์ • ๊ฐ’ ์‚ญ์ œ

void deleteValue(Node** head, int value) {
    if (*head == NULL) {
        return;
    }
    
    // ์ฒซ ๋…ธ๋“œ๊ฐ€ ์‚ญ์ œ ๋Œ€์ƒ
    if ((*head)->data == value) {
        Node* temp = *head;
        *head = (*head)->next;
        free(temp);
        return;
    }
    
    // ์‚ญ์ œํ•  ๋…ธ๋“œ์˜ ์ด์ „ ๋…ธ๋“œ ์ฐพ๊ธฐ
    Node* current = *head;
    while (current->next != NULL && current->next->data != value) {
        current = current->next;
    }
    
    // ๋ชป ์ฐพ์Œ
    if (current->next == NULL) {
        printf("Value not found\n");
        return;
    }
    
    // ์‚ญ์ œ
    Node* temp = current->next;
    current->next = current->next->next;
    free(temp);
}

์˜ˆ์‹œ: 20 ์‚ญ์ œ

์ดˆ๊ธฐ: Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]

1๋‹จ๊ณ„: 20์˜ ์ด์ „ ๋…ธ๋“œ(10) ์ฐพ๊ธฐ
Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]
        โ†‘        โ†‘
    current    temp

2๋‹จ๊ณ„: current->next = temp->next
Head โ†’ [10|โ—] โ”€โ”€โ”€โ”€โ”€โ”
                    โ†“
       [20|โ—]   [30|NULL]
        temp

3๋‹จ๊ณ„: free(temp)
Head โ†’ [10|โ—] โ†’ [30|NULL]
Node* search(Node* head, int key) {
    Node* current = head;
    
    while (current != NULL) {
        if (current->data == key) {
            return current;  // ์ฐพ์Œ
        }
        current = current->next;
    }
    
    return NULL;  // ๋ชป ์ฐพ์Œ
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

5. ์ถœ๋ ฅ (Display)

void display(Node* head) {
    Node* current = head;
    
    printf("List: ");
    while (current != NULL) {
        printf("%d โ†’ ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

6. ์ „์ฒด ์‚ญ์ œ (๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ)

void deleteAll(Node** head) {
    Node* current = *head;
    Node* next;
    
    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
    
    *head = NULL;
}

๐Ÿ”— ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ์ข…๋ฅ˜

1. ๋‹จ์ผ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ (Singly Linked List)

์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ธฐ๋ณธ ํ˜•ํƒœ

Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|NULL]

ํŠน์ง•:
- ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์ด๋™ ๊ฐ€๋Šฅ
- ์ด์ „ ๋…ธ๋“œ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์—†์Œ

2. ์ด์ค‘ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ (Doubly Linked List)

์–‘๋ฐฉํ–ฅ ํฌ์ธํ„ฐ

typedef struct DNode {
    int data;
    struct DNode* prev;  // ์ด์ „ ๋…ธ๋“œ
    struct DNode* next;  // ๋‹ค์Œ ๋…ธ๋“œ
} DNode;
NULL โ† [10|โ—] โ‡„ [20|โ—] โ‡„ [30|โ—] โ†’ NULL
       prev  next

์žฅ์ :

๋‹จ์ :

3. ์›ํ˜• ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ (Circular Linked List)

๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๊ฐ€ ์ฒซ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด

     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ†“                 โ”‚
Head โ†’ [10|โ—] โ†’ [20|โ—] โ†’ [30|โ—]

์žฅ์ :

ํ™œ์šฉ:


๐Ÿ“Š ๋ฐฐ์—ด vs ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ

๋น„๊ตํ‘œ

๊ตฌ๋ถ„ ๋ฐฐ์—ด ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ
๋ฉ”๋ชจ๋ฆฌ ์—ฐ์†์  ๋น„์—ฐ์†์ 
ํฌ๊ธฐ ๊ณ ์ • ๋™์ 
์ ‘๊ทผ O(1) โœ” O(N) โœ˜
ํƒ์ƒ‰ O(N) O(N)
๋งจ์•ž ์‚ฝ์ž… O(N) โœ˜ O(1) โœ”
๋งจ๋’ค ์‚ฝ์ž… O(1) โœ” O(N) โœ˜
์ค‘๊ฐ„ ์‚ฝ์ž… O(N) O(N)
๋งจ์•ž ์‚ญ์ œ O(N) โœ˜ O(1) โœ”
๋งจ๋’ค ์‚ญ์ œ O(1) โœ” O(N) โœ˜
์ค‘๊ฐ„ ์‚ญ์ œ O(N) O(N)
๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ ๋†’์Œ โœ” ๋‚ฎ์Œ (ํฌ์ธํ„ฐ) โœ˜
์บ์‹œ ํšจ์œจ ๋†’์Œ โœ” ๋‚ฎ์Œ โœ˜

์ƒ์„ธ ๋น„๊ต

1. ์ ‘๊ทผ ์†๋„

// ๋ฐฐ์—ด: O(1)
int value = arr[100];  // ๋ฐ”๋กœ ์ ‘๊ทผ

// ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ: O(N)
Node* current = head;
for (int i = 0; i < 100; i++) {
    current = current->next;  // 100๋ฒˆ ์ด๋™
}
int value = current->data;

2. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ

๋ฐฐ์—ด (10๊ฐœ int):
[10][20][30][40][50]...[100]
๋ฉ”๋ชจ๋ฆฌ: 4๋ฐ”์ดํŠธ ร— 10 = 40๋ฐ”์ดํŠธ

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ (10๊ฐœ int):
[10|โ—] โ†’ [20|โ—] โ†’ ... โ†’ [100|NULL]
๋ฉ”๋ชจ๋ฆฌ: (4๋ฐ”์ดํŠธ + 8๋ฐ”์ดํŠธ) ร— 10 = 120๋ฐ”์ดํŠธ
(64๋น„ํŠธ ์‹œ์Šคํ…œ์—์„œ ํฌ์ธํ„ฐ 8๋ฐ”์ดํŠธ)

๋ฐฐ์—ด์ด 3๋ฐฐ ํšจ์œจ์ ! โœ”

3. ์‚ฝ์ž…/์‚ญ์ œ ๋น„๊ต

๋ฐฐ์—ด์˜ ์ค‘๊ฐ„ ์‚ฝ์ž…:

{10, 20, 30, 40, 50}์— 25 ์‚ฝ์ž… (์ธ๋ฑ์Šค 2)

์ด๋™ ํ•„์š”: 30, 40, 50 โ†’ 3๊ฐœ
์‹œ๊ฐ„: O(N)

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ์ค‘๊ฐ„ ์‚ฝ์ž…:

[10] โ†’ [20] โ†’ [30] โ†’ [40] โ†’ [50]์— 25 ์‚ฝ์ž…

์ฐพ๊ธฐ: 20๊นŒ์ง€ ์ด๋™ โ†’ O(N)
์‚ฝ์ž…: ํฌ์ธํ„ฐ 2๊ฐœ ๋ณ€๊ฒฝ โ†’ O(1)
์ „์ฒด: O(N)

๊ฒฐ๋ก : ์‚ฝ์ž…/์‚ญ์ œ๋„ ๋น„์Šทํ•˜์ง€๋งŒ, ๋งจ ์•ž ์ž‘์—…์€ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์œ ๋ฆฌ

4. ์บ์‹œ ํšจ์œจ

๋ฐฐ์—ด:
[10][20][30][40][50]  โ† ์—ฐ์† ๋ฉ”๋ชจ๋ฆฌ
์บ์‹œ์— ํ•œ ๋ฒˆ์— ๋กœ๋“œ โ†’ ๋น ๋ฆ„ โœ”

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ:
[10] โ†’ [20] โ†’ [30] โ†’ [40] โ†’ [50]
๊ฐ ๋…ธ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์œ„์น˜ โ†’ ์บ์‹œ ๋ฏธ์Šค โ†’ ๋А๋ฆผ โœ˜

๐ŸŽฏ ์–ธ์ œ ๋ฌด์—‡์„ ์‚ฌ์šฉํ• ๊นŒ?

๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ โœ”

1. ์ธ๋ฑ์Šค ์ ‘๊ทผ์ด ๋นˆ๋ฒˆํ•  ๋•Œ
   ์˜ˆ: arr[i], ๋žœ๋ค ์•ก์„ธ์Šค

2. ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •๋˜์–ด ์žˆ์„ ๋•Œ
   ์˜ˆ: ํ•™์ƒ 100๋ช…์˜ ์„ฑ์ 

3. ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ œํ•œ์ ์ผ ๋•Œ
   ์˜ˆ: ์ž„๋ฒ ๋””๋“œ ์‹œ์Šคํ…œ

4. ์ˆœ์ฐจ ์ ‘๊ทผ์ด ๋งŽ์„ ๋•Œ
   ์˜ˆ: for๋ฌธ์œผ๋กœ ์ „์ฒด ์ˆœํšŒ

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ โœ”

1. ํฌ๊ธฐ๊ฐ€ ๋™์ ์œผ๋กœ ๋ณ€ํ•  ๋•Œ
   ์˜ˆ: ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋”ฐ๋ผ ํฌ๊ธฐ ๋ณ€ํ™”

2. ๋งจ ์•ž ์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ๋นˆ๋ฒˆํ•  ๋•Œ
   ์˜ˆ: ์Šคํƒ, ํ ๊ตฌํ˜„

3. ์ค‘๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ณ 
   ํ•ด๋‹น ์œ„์น˜๋ฅผ ์ด๋ฏธ ์•Œ๊ณ  ์žˆ์„ ๋•Œ
   ์˜ˆ: ํฌ์ธํ„ฐ๋กœ ์œ„์น˜๋ฅผ ์ €์žฅํ•ด๋‘” ๊ฒฝ์šฐ

4. ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋ฅผ ํ”ผํ•˜๊ณ  ์‹ถ์„ ๋•Œ
   ์˜ˆ: ํฐ ์—ฐ์† ๋ฉ”๋ชจ๋ฆฌ ํ™•๋ณด ์–ด๋ ค์›€

์‹ค๊ธฐ ๊ธฐ์ถœ ์œ ํ˜•

๐ŸŽฏ ์œ ํ˜• 1: ์ฝ”๋“œ ๊ฒฐ๊ณผ ์˜ˆ์ธก

๋ฐฐ์—ด ๋ฌธ์ œ

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int i;
    
    for (i = 0; i < 5; i++) {
        arr[i] = arr[i] + 5;
    }
    
    printf("%d %d", arr[2], arr[4]);
    
    return 0;
}

ํ’€์ด:

์ดˆ๊ธฐ: arr[] = {10, 20, 30, 40, 50}

๋ฐ˜๋ณต๋ฌธ ์‹คํ–‰:
i=0: arr[0] = 10 + 5 = 15
i=1: arr[1] = 20 + 5 = 25
i=2: arr[2] = 30 + 5 = 35
i=3: arr[3] = 40 + 5 = 45
i=4: arr[4] = 50 + 5 = 55

์ตœ์ข…: arr[] = {15, 25, 35, 45, 55}

์ถœ๋ ฅ: arr[2]=35, arr[4]=55
๋‹ต: 35 55

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๋ฌธ์ œ

typedef struct Node {
    int data;
    struct Node* next;
} Node;

int main() {
    Node* head = NULL;
    
    // ๋…ธ๋“œ ์ƒ์„ฑ ๋ฐ ์—ฐ๊ฒฐ
    Node* n1 = createNode(10);
    Node* n2 = createNode(20);
    Node* n3 = createNode(30);
    
    head = n1;
    n1->next = n2;
    n2->next = n3;
    n3->next = NULL;
    
    // ๋งจ ์•ž์— 5 ์‚ฝ์ž…
    Node* newNode = createNode(5);
    newNode->next = head;
    head = newNode;
    
    // ์ถœ๋ ฅ
    printf("%d %d", head->data, head->next->next->data);
    
    return 0;
}

ํ’€์ด:

1. ์ดˆ๊ธฐ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ:
Head โ†’ [10] โ†’ [20] โ†’ [30] โ†’ NULL

2. ๋งจ ์•ž์— 5 ์‚ฝ์ž…:
newNode = [5]
newNode->next = head  โ†’ [5] โ†’ [10] โ†’ [20] โ†’ [30] โ†’ NULL
head = newNode

์ตœ์ข…: Head โ†’ [5] โ†’ [10] โ†’ [20] โ†’ [30] โ†’ NULL

์ถœ๋ ฅ:
head->data = 5
head->next = [10]
head->next->next = [20]
head->next->next->data = 20

๋‹ต: 5 20

๐ŸŽฏ ์œ ํ˜• 2: ๋นˆ์นธ ์ฑ„์šฐ๊ธฐ

๋ฐฐ์—ด ๋ฌธ์ œ

// ๋ฐฐ์—ด์—์„œ ์ตœ๋Œ“๊ฐ’ ์ฐพ๊ธฐ
int findMax(int arr[], int size) {
    int max = arr[0];
    
    for (int i = 1; i < size; i++) {
        if (arr[i] ______ max) {  // ๋นˆ์นธ 1
            max = ______;          // ๋นˆ์นธ 2
        }
    }
    
    return max;
}

์ •๋‹ต:

if (arr[i] > max) {      // ๋นˆ์นธ 1: >
    max = arr[i];         // ๋นˆ์นธ 2: arr[i]
}

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๋ฌธ์ œ

// ๋งจ ๋’ค์— ๋…ธ๋“œ ์‚ฝ์ž…
void insertBack(Node** head, int data) {
    Node* newNode = createNode(data);
    
    if (*head == NULL) {
        *head = newNode;
        return;
    }
    
    Node* current = *head;
    while (current->______ != NULL) {  // ๋นˆ์นธ 1
        current = current->next;
    }
    
    current->next = ______;             // ๋นˆ์นธ 2
}

์ •๋‹ต:

while (current->next != NULL) {  // ๋นˆ์นธ 1: next
    current = current->next;
}

current->next = newNode;          // ๋นˆ์นธ 2: newNode

๐ŸŽฏ ์œ ํ˜• 3: ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ž‘์„ฑ

๋ฐฐ์—ด ๋ฌธ์ œ: ๋ฐฐ์—ด ํšŒ์ „ (์™ผ์ชฝ์œผ๋กœ 1์นธ)

// ๋ฐฐ์—ด์„ ์™ผ์ชฝ์œผ๋กœ 1์นธ ํšŒ์ „
// {10, 20, 30, 40} โ†’ {20, 30, 40, 10}

void rotateLeft(int arr[], int size) {
    int temp = arr[0];  // ์ฒซ ์›์†Œ ์ €์žฅ
    
    // ์™ผ์ชฝ์œผ๋กœ ์ด๋™
    for (int i = 0; i < size - 1; i++) {
        arr[i] = arr[i + 1];
    }
    
    arr[size - 1] = temp;  // ๋งˆ์ง€๋ง‰์— ์ €์žฅ
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

๋™์ž‘ ๊ณผ์ •:

์ดˆ๊ธฐ: {10, 20, 30, 40}

temp = 10

์ด๋™:
arr[0] = arr[1] โ†’ {20, 20, 30, 40}
arr[1] = arr[2] โ†’ {20, 30, 30, 40}
arr[2] = arr[3] โ†’ {20, 30, 40, 40}

๋งˆ์ง€๋ง‰์— temp ๋ฐฐ์น˜:
arr[3] = temp โ†’ {20, 30, 40, 10}

๋ฐฐ์—ด ๋ฌธ์ œ: ๋‘ ๋ฐฐ์—ด ํ•ฉ์น˜๊ธฐ

// arr1๊ณผ arr2๋ฅผ result์— ํ•ฉ์น˜๊ธฐ
void mergeArrays(int arr1[], int size1, 
                 int arr2[], int size2, 
                 int result[]) {
    int i, j;
    
    // arr1 ๋ณต์‚ฌ
    for (i = 0; i < size1; i++) {
        result[i] = arr1[i];
    }
    
    // arr2 ๋ณต์‚ฌ
    for (j = 0; j < size2; j++) {
        result[i + j] = arr2[j];
    }
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N + M)

์˜ˆ์‹œ:

arr1[] = {10, 20, 30}  (size1 = 3)
arr2[] = {40, 50}      (size2 = 2)

๊ฒฐ๊ณผ: result[] = {10, 20, 30, 40, 50}

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๋ฌธ์ œ: ๋ฆฌ์ŠคํŠธ ์—ญ์ˆœ

// ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์—ญ์ˆœ์œผ๋กœ ๋ณ€๊ฒฝ
Node* reverse(Node* head) {
    Node* prev = NULL;
    Node* current = head;
    Node* next = NULL;
    
    while (current != NULL) {
        next = current->next;    // ๋‹ค์Œ ๋…ธ๋“œ ์ €์žฅ
        current->next = prev;     // ๋ฐฉํ–ฅ ์ „ํ™˜
        prev = current;           // prev ์ด๋™
        current = next;           // current ์ด๋™
    }
    
    return prev;  // ์ƒˆ๋กœ์šด head
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

๋™์ž‘ ๊ณผ์ •:

์ดˆ๊ธฐ: [10] โ†’ [20] โ†’ [30] โ†’ NULL

1๋‹จ๊ณ„: current = [10]
next = [20]
[10] โ†’ NULL (๋ฐฉํ–ฅ ์ „ํ™˜)
prev = [10], current = [20]

2๋‹จ๊ณ„: current = [20]
next = [30]
[20] โ†’ [10] โ†’ NULL
prev = [20], current = [30]

3๋‹จ๊ณ„: current = [30]
next = NULL
[30] โ†’ [20] โ†’ [10] โ†’ NULL
prev = [30], current = NULL

์ตœ์ข…: [30] โ†’ [20] โ†’ [10] โ†’ NULL

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๋ฌธ์ œ: ์ค‘๊ฐ„ ๋…ธ๋“œ ์ฐพ๊ธฐ

// ๋ฆฌ์ŠคํŠธ์˜ ์ค‘๊ฐ„ ๋…ธ๋“œ ์ฐพ๊ธฐ (Fast & Slow Pointer)
Node* findMiddle(Node* head) {
    if (head == NULL) return NULL;
    
    Node* slow = head;
    Node* fast = head;
    
    // fast๋Š” 2์นธ, slow๋Š” 1์นธ์”ฉ ์ด๋™
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }
    
    return slow;  // slow๊ฐ€ ์ค‘๊ฐ„ ์ง€์ 
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

๋™์ž‘ ๊ณผ์ •:

๋ฆฌ์ŠคํŠธ: [10] โ†’ [20] โ†’ [30] โ†’ [40] โ†’ [50] โ†’ NULL

์ดˆ๊ธฐ:
slow = [10], fast = [10]

1๋‹จ๊ณ„:
slow = [20], fast = [30]

2๋‹จ๊ณ„:
slow = [30], fast = [50]

3๋‹จ๊ณ„:
fast->next = NULL โ†’ ์ข…๋ฃŒ
slow = [30] โœ” (์ค‘๊ฐ„ ๋…ธ๋“œ)

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๋ฌธ์ œ: ์ˆœํ™˜ ๊ฐ์ง€

// ๋ฆฌ์ŠคํŠธ์— ์ˆœํ™˜(Cycle)์ด ์žˆ๋Š”์ง€ ํ™•์ธ
bool hasCycle(Node* head) {
    if (head == NULL) return false;
    
    Node* slow = head;
    Node* fast = head;
    
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        
        // ๋งŒ๋‚˜๋ฉด ์ˆœํ™˜ ์žˆ์Œ
        if (slow == fast) {
            return true;
        }
    }
    
    return false;  // ์ˆœํ™˜ ์—†์Œ
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

๋™์ž‘ ์›๋ฆฌ:

์ˆœํ™˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ:
[10] โ†’ [20] โ†’ [30] โ†’ [40]
              โ†‘       โ†“
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

slow์™€ fast๊ฐ€ ์–ธ์  ๊ฐ€ ๋งŒ๋‚จ โœ”

์ˆœํ™˜์ด ์—†๋Š” ๊ฒฝ์šฐ:
[10] โ†’ [20] โ†’ [30] โ†’ [40] โ†’ NULL

fast๊ฐ€ NULL์— ๋„๋‹ฌ โ†’ ์ˆœํ™˜ ์—†์Œ โœ”

๐ŸŽฏ ์œ ํ˜• 4: ๊ฐœ๋… ์„œ์ˆ 

Q1: ๋ฐฐ์—ด๊ณผ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ์ฐจ์ด์ ์„ 3๊ฐ€์ง€ ์„œ์ˆ ํ•˜์‹œ์˜ค.

๋‹ต:

1. ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ:
   - ๋ฐฐ์—ด: ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅ
   - ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ: ๋น„์—ฐ์†์  ๋ฉ”๋ชจ๋ฆฌ, ํฌ์ธํ„ฐ๋กœ ์—ฐ๊ฒฐ

2. ์ ‘๊ทผ ์†๋„:
   - ๋ฐฐ์—ด: ์ธ๋ฑ์Šค๋กœ ์ง์ ‘ ์ ‘๊ทผ O(1)
   - ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ: ์ˆœ์ฐจ ์ ‘๊ทผ O(N)

3. ํฌ๊ธฐ ๋ณ€๊ฒฝ:
   - ๋ฐฐ์—ด: ๊ณ ์ • ํฌ๊ธฐ, ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€
   - ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ: ๋™์  ํฌ๊ธฐ, ์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

Q2: ๋ฐฐ์—ด์—์„œ ์ค‘๊ฐ„ ์‚ฝ์ž…์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(N)์ธ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜์‹œ์˜ค.

๋‹ต:

์ค‘๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•˜๋ ค๋ฉด ํ•ด๋‹น ์œ„์น˜ ์ดํ›„์˜
๋ชจ๋“  ์›์†Œ๋ฅผ ํ•œ ์นธ์”ฉ ๋’ค๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ: {10, 20, 30, 40, 50}์˜ ์ธ๋ฑ์Šค 2์— 25 ์‚ฝ์ž…

1. 50์„ ์ธ๋ฑ์Šค 5๋กœ ์ด๋™
2. 40์„ ์ธ๋ฑ์Šค 4๋กœ ์ด๋™
3. 30์„ ์ธ๋ฑ์Šค 3์œผ๋กœ ์ด๋™
4. ์ธ๋ฑ์Šค 2์— 25 ์‚ฝ์ž…

์ด๋™ ํšŸ์ˆ˜๋Š” (๋ฐฐ์—ด ํฌ๊ธฐ - ์‚ฝ์ž… ์œ„์น˜)์ด๋ฏ€๋กœ
์ตœ์•…์˜ ๊ฒฝ์šฐ(๋งจ ์•ž ์‚ฝ์ž…) N๋ฒˆ ์ด๋™ โ†’ O(N)

Q3: ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์—์„œ ๋งจ ๋’ค ์‚ฝ์ž…์ด O(N)์ธ๋ฐ, ์ด๋ฅผ O(1)๋กœ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€?

๋‹ต:

Tail ํฌ์ธํ„ฐ๋ฅผ ์ถ”๊ฐ€๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์กฐ:
typedef struct List {
    Node* head;
    Node* tail;  // ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
} List;

์‚ฝ์ž… ์‹œ:
1. newNode ์ƒ์„ฑ
2. tail->next = newNode
3. tail = newNode

Tail ํฌ์ธํ„ฐ๋กœ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๋ฐ”๋กœ ์ ‘๊ทผํ•˜๋ฏ€๋กœ
์ˆœํšŒ ์—†์ด O(1)์— ์‚ฝ์ž… ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Q4: ์ด์ค‘ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ์žฅ์ ๊ณผ ๋‹จ์ ์„ ์„ค๋ช…ํ•˜์‹œ์˜ค.

๋‹ต:

์žฅ์ :
1. ์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰ ๊ฐ€๋Šฅ (prev ํฌ์ธํ„ฐ)
2. ํŠน์ • ๋…ธ๋“œ ์‚ญ์ œ ์‹œ ์ด์ „ ๋…ธ๋“œ ์ฐพ๊ธฐ ์‰ฌ์›€
3. ์—ญ์ˆœ ์ˆœํšŒ ๊ฐ€๋Šฅ

๋‹จ์ :
1. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ฆ๊ฐ€ (ํฌ์ธํ„ฐ 2๊ฐœ)
2. ์‚ฝ์ž…/์‚ญ์ œ ์‹œ ํฌ์ธํ„ฐ ๊ด€๋ฆฌ ๋ณต์žก (prev, next ๋ชจ๋‘ ์ฒ˜๋ฆฌ)
3. ๊ตฌํ˜„ ๋‚œ์ด๋„ ์ฆ๊ฐ€

ํ™œ์šฉ:
- ๋ธŒ๋ผ์šฐ์ €์˜ ์•ž/๋’ค ์ด๋™
- ํ…์ŠคํŠธ ์—๋””ํ„ฐ์˜ Undo/Redo
- LRU ์บ์‹œ ๊ตฌํ˜„

๐Ÿ’ก ์‹ค์ „ ์‘์šฉ ๋ฌธ์ œ

๋ฌธ์ œ 1: ๋ฐฐ์—ด์—์„œ ๋‘ ์ˆ˜์˜ ํ•ฉ

// ๋ฐฐ์—ด์—์„œ ํ•ฉ์ด target์ธ ๋‘ ์ˆ˜์˜ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ
// arr[] = {2, 7, 11, 15}, target = 9
// ๋‹ต: [0, 1] (2 + 7 = 9)

void twoSum(int arr[], int size, int target) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; j++) {
            if (arr[i] + arr[j] == target) {
                printf("[%d, %d]\n", i, j);
                return;
            }
        }
    }
    printf("Not found\n");
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(Nยฒ)

๋ฌธ์ œ 2: ๋ฐฐ์—ด ํšŒ์ „ (์˜ค๋ฅธ์ชฝ์œผ๋กœ k์นธ)

// ๋ฐฐ์—ด์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ k์นธ ํšŒ์ „
// arr[] = {1, 2, 3, 4, 5}, k = 2
// ๊ฒฐ๊ณผ: {4, 5, 1, 2, 3}

void reverse(int arr[], int start, int end) {
    while (start < end) {
        int temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
        start++;
        end--;
    }
}

void rotateRight(int arr[], int size, int k) {
    k = k % size;  // k๊ฐ€ size๋ณด๋‹ค ํด ๊ฒฝ์šฐ ๋Œ€๋น„
    
    // 1. ์ „์ฒด ์—ญ์ˆœ
    reverse(arr, 0, size - 1);
    
    // 2. ์•ž k๊ฐœ ์—ญ์ˆœ
    reverse(arr, 0, k - 1);
    
    // 3. ๋‚˜๋จธ์ง€ ์—ญ์ˆœ
    reverse(arr, k, size - 1);
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

๋™์ž‘ ๊ณผ์ •:

์ดˆ๊ธฐ: {1, 2, 3, 4, 5}, k = 2

1. ์ „์ฒด ์—ญ์ˆœ:
{5, 4, 3, 2, 1}

2. ์•ž 2๊ฐœ ์—ญ์ˆœ:
{4, 5, 3, 2, 1}

3. ๋‚˜๋จธ์ง€ ์—ญ์ˆœ:
{4, 5, 1, 2, 3} โœ”

๋ฌธ์ œ 3: ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ ๋ณ‘ํ•ฉ (์ •๋ ฌ๋œ ๋‘ ๋ฆฌ์ŠคํŠธ)

// ์ •๋ ฌ๋œ ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ •๋ ฌ๋œ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ๋กœ
// list1: [1] โ†’ [3] โ†’ [5]
// list2: [2] โ†’ [4] โ†’ [6]
// ๊ฒฐ๊ณผ: [1] โ†’ [2] โ†’ [3] โ†’ [4] โ†’ [5] โ†’ [6]

Node* mergeSortedLists(Node* l1, Node* l2) {
    // ๋”๋ฏธ ๋…ธ๋“œ ์ƒ์„ฑ
    Node dummy;
    Node* tail = &dummy;
    dummy.next = NULL;
    
    while (l1 != NULL && l2 != NULL) {
        if (l1->data <= l2->data) {
            tail->next = l1;
            l1 = l1->next;
        } else {
            tail->next = l2;
            l2 = l2->next;
        }
        tail = tail->next;
    }
    
    // ๋‚จ์€ ๋…ธ๋“œ ์—ฐ๊ฒฐ
    if (l1 != NULL) {
        tail->next = l1;
    } else {
        tail->next = l2;
    }
    
    return dummy.next;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N + M)

๋ฌธ์ œ 4: ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์—์„œ N๋ฒˆ์งธ ๋’ค ๋…ธ๋“œ ์‚ญ์ œ

// ๋’ค์—์„œ N๋ฒˆ์งธ ๋…ธ๋“œ ์‚ญ์ œ
// ๋ฆฌ์ŠคํŠธ: [1] โ†’ [2] โ†’ [3] โ†’ [4] โ†’ [5], N = 2
// ๊ฒฐ๊ณผ: [1] โ†’ [2] โ†’ [3] โ†’ [5] (4 ์‚ญ์ œ)

Node* removeNthFromEnd(Node* head, int n) {
    Node dummy;
    dummy.next = head;
    
    Node* first = &dummy;
    Node* second = &dummy;
    
    // first๋ฅผ n+1์นธ ์•ž์„œ๊ฒŒ ์ด๋™
    for (int i = 0; i <= n; i++) {
        if (first == NULL) return head;
        first = first->next;
    }
    
    // ๋‘˜ ๋‹ค ์ด๋™ (๊ฐ„๊ฒฉ ์œ ์ง€)
    while (first != NULL) {
        first = first->next;
        second = second->next;
    }
    
    // ์‚ญ์ œ
    Node* temp = second->next;
    second->next = second->next->next;
    free(temp);
    
    return dummy.next;
}

// ์‹œ๊ฐ„๋ณต์žก๋„: O(N)

๋™์ž‘ ๊ณผ์ •:

๋ฆฌ์ŠคํŠธ: [1] โ†’ [2] โ†’ [3] โ†’ [4] โ†’ [5], N = 2

1. first๋ฅผ n+1=3์นธ ์ด๋™:
first โ†’ [4], second โ†’ [dummy]

2. ๋‘˜ ๋‹ค ๋๊นŒ์ง€ ์ด๋™ (๊ฐ„๊ฒฉ ์œ ์ง€):
first โ†’ NULL, second โ†’ [3]

3. second->next (4) ์‚ญ์ œ:
[1] โ†’ [2] โ†’ [3] โ†’ [5]

๐Ÿ“ ํ•ต์‹ฌ ์•”๊ธฐ ์‚ฌํ•ญ

๋ฐฐ์—ด (Array)

โœ” ์—ฐ์†๋œ ๋ฉ”๋ชจ๋ฆฌ
โœ” ๊ณ ์ • ํฌ๊ธฐ
โœ” ์ธ๋ฑ์Šค ์ ‘๊ทผ: O(1)
โœ” ํƒ์ƒ‰: O(N)
โœ” ๋งจ๋’ค ์‚ฝ์ž…/์‚ญ์ œ: O(1)
โœ” ์ค‘๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ: O(N)
โœ” ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ 
โœ” ์บ์‹œ ์นœํ™”์ 

์ฃผ์†Œ ๊ณ„์‚ฐ: ์‹œ์ž‘์ฃผ์†Œ + (์ธ๋ฑ์Šค ร— ๋ฐ์ดํ„ฐํฌ๊ธฐ)

๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ (Linked List)

โœ” ๋น„์—ฐ์†์  ๋ฉ”๋ชจ๋ฆฌ
โœ” ๋™์  ํฌ๊ธฐ
โœ” ์ธ๋ฑ์Šค ์ ‘๊ทผ: O(N)
โœ” ํƒ์ƒ‰: O(N)
โœ” ๋งจ์•ž ์‚ฝ์ž…/์‚ญ์ œ: O(1)
โœ” ๋งจ๋’ค ์‚ฝ์ž…/์‚ญ์ œ: O(N) (Tail ์—†์„ ๋•Œ)
โœ” ์ค‘๊ฐ„ ์‚ฝ์ž…/์‚ญ์ œ: O(N)
โœ” ํฌ์ธํ„ฐ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ

๋…ธ๋“œ ๊ตฌ์กฐ: data + next ํฌ์ธํ„ฐ

์‹œ๊ฐ„๋ณต์žก๋„ ๋น„๊ต

์—ฐ์‚ฐ ๋ฐฐ์—ด ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ
์ ‘๊ทผ O(1) O(N)
ํƒ์ƒ‰ O(N) O(N)
๋งจ์•ž ์‚ฝ์ž… O(N) O(1)
๋งจ๋’ค ์‚ฝ์ž… O(1) O(N)
์ค‘๊ฐ„ ์‚ฝ์ž… O(N) O(N)
๋งจ์•ž ์‚ญ์ œ O(N) O(1)
๋งจ๋’ค ์‚ญ์ œ O(1) O(N)

๐ŸŽ“ ์‹ค๊ธฐ ์‹œํ—˜ ํŒ

1. ๋ฐฐ์—ด ์ธ๋ฑ์Šค ์ฃผ์˜

int arr[5];  // ์ธ๋ฑ์Šค: 0, 1, 2, 3, 4

arr[5] = 10;  // โœ˜ ๋ฒ”์œ„ ์ดˆ๊ณผ (Undefined Behavior)
arr[4] = 10;  // โœ” ์˜ฌ๋ฐ”๋ฆ„

2. ํฌ์ธํ„ฐ ์ดˆ๊ธฐํ™”

Node* head = NULL;  // โœ” ๋ฐ˜๋“œ์‹œ ์ดˆ๊ธฐํ™”

if (head == NULL) {  // NULL ์ฒดํฌ ์Šต๊ด€ํ™”
    // ์ฒ˜๋ฆฌ
}

3. ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ

Node* temp = head;
head = head->next;
free(temp);  // โœ” ๋ฐ˜๋“œ์‹œ ํ•ด์ œ

4. ์ด์ค‘ ํฌ์ธํ„ฐ ์ดํ•ด

void insertFront(Node** head, int data) {
    // *head๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด **head ํ•„์š”
    *head = newNode;
}

5. ๊ฒฝ๊ณ„ ์กฐ๊ฑด ์ฒดํฌ

// ๋นˆ ๋ฆฌ์ŠคํŠธ
if (head == NULL) { ... }

// ๋…ธ๋“œ 1๊ฐœ
if (head->next == NULL) { ... }

// ๋ฐฐ์—ด ๋ฒ”์œ„
if (index < 0 || index >= size) { ... }

check list: