반응형

  ※ 트리의 개념과 이진탐색트리를 포함해서 설명이 진행되므로 모르면 아래 링크로 확인 !

  ※ C 트리(Tree)설명

 

C 트리(Tree) 설명

트리 - 비선형 자료구조의 일종이다. - 계층적 관계(Hierarchical Relationship)를 표현하는 자료구조이다. ※ 사용 예로 컴퓨터의 디렉터리 구조를 들 수 있다. 용어 정리 1. 노드(Node) : 트리의 구성요소

srdeveloper.tistory.com


 

이진탐색트리의 문제점

- 트리의 균형이 맞지 않을수록 O(n)에 가까운 시간 복잡도를 보인다.

  ※ 위와 같은 순서로 데이터가 누적이 된 상태에서 D의 값을 찾으려면 모든 노드를 탐색하게되며, 이렇게 되면 이진 탐색 트리를 쓰는 의미가 없어진다.

 

이러한 이진탐색트리의 단점을 해결한 트리를 가리켜 균형잡힌 이진트리라하며 그 중 AVL트리에 대해 설명하고자한다.

 

AVL 트리

- Adelson-Velsky and Landis에서 따온 이름이다.

- 이진탐색트리의 단점을 해결한 균형잡힌 이진트리 중 처음으로 발명되었다.

- AVL 트리는 균형의 정도를 표현한 균형 인수(Balance Factor)를 사용한다.

  ※ 계산법 : 균형 인수 = 왼쪽 서브 트리의 높이 - 오른쪽 서브 트리의 높이

- 균형이 무너졌을 때, 구조의 재조정(Rebalancing)의 종류는 LL, RR, LR, RL이 있다.

 

 

균형 인수(Balance Factor)

- 노드 위에 적힌 숫자가 균형 인수이다.

- 균형 인수의 절대값이 크면 클수록 트리의 균형이 무너진 상태이다.

  ※ 따라서 균형 인수의 절대값이 2 이상인 경우에 균형을 잡기 위한 재조정을 진행한다.

 

 

LL(Left Left), RR(Right Right) 상태

- 위 그림의 왼쪽 트리를 보면 루트 노드의 균형인수가 2이다.

- 왼쪽의 자식 노드가 연이어 연결된 상태인데 이런 상태를 가리켜 LL(Left Left)상태라고 한다.

  ※ 반대로 오른쪽으로 자식 노드가 연이어져 있으면 RR(Right Right)상태라 한다.

- 이러한 LL상태에서 불균형 해소를 위한 리밸런싱을 LL회전이라고 한다.

  ※ 반대로 오른쪽으로는 RR회전이라 한다.

- 키값이 5인 노드를 Child node(이하 CNode), 키값이 10인 노드를 Parent node(이하 PNode)라고 한 뒤, LL회전의 방법은 다음과 같다.

  1. PNode를 CNode의 오른쪽 자식으로 보낸다.

    ※ 이 때, PNode가 CNode의 자식 노드가 되므로 PNode의 기존 자식 참조값은 비워준다.

  2. CNode를 Root노드로 설정한다.

  ※ RR은 반대로 생각해주면 된다.

 

 

 

LR(Left Right), RL(Right Left) 상태

- 왼쪽 자식 노드에 오른쪽 자식 노드가 연결된 상태인데 이런 상태를 가리켜 LR(Left Right)상태라고 한다.

  ※ 반대로 오른쪽 자식 노드에 왼쪽 자식노드가 이어져있으면 RL(Right Left)상태라 한다.

- 이러한 LR 상태에서 LL회전을 하게되면 이진탐색트리의 규칙에 위배되므로 왼쪽 자식 노드를 RR회전을 먼저 진행해 불균형 상태를 LL로 만든뒤, 루트 노드를 LL회전 해줘서 리밸런싱을 한다.

- 키값이 1인 노드를 Leaf node(이하 LNode), 키값이 5인 노드를 Child node(이하 CNode), 키값이 10인 노드를 Parent node(이하 PNode)라고 한 뒤, LL회전의 방법은 다음과 같다.

  1. 먼저 CNode를 RR회전을 해줘서 LNode를 CNode의 자리에 옮기고 CNode를 LNode의 왼쪽 자식으로 옮긴다.

    ※ 이 과정이 끝나면 트리가 LL상태가 되어있다.

  2. (LL 회전 시작) PNode를 LNode의 오른쪽 자식으로 보낸다.

  3. LNode를 Root 노드로 설정한다.

  ※ RL은 반대로 생각해주면 된다. (자식 노드를 LL회전한 뒤 Root 노드를 RR회전)

 

반응형

'Stack > Data struct' 카테고리의 다른 글

[C#] 자료구조 힙(Heap) 트리 구현  (0) 2022.10.04
C AVL 트리(AVL Tree) 구현  (2) 2021.09.11
C 트리 순회(Tree traversal) 구현  (0) 2021.09.10
C 이진탐색트리(Binary search tree) 구현  (0) 2021.09.09
C 트리(Tree) 설명  (0) 2021.09.09
반응형

  ※ 이 글은 코드 위주이니 설명은 아래 링크로 확인 !

  ※ C 트리(Tree) 설명

 

C 트리(Tree) 설명

트리 - 비선형 자료구조의 일종이다. - 계층적 관계(Hierarchical Relationship)를 표현하는 자료구조이다. ※ 사용 예로 컴퓨터의 디렉터리 구조를 들 수 있다. 용어 정리 1. 노드(Node) : 트리의 구성요소

srdeveloper.tistory.com


코드 설명에 들어가기에 앞서, 다시한번 강조하자면 자식 노드에 대한 순회 순서는 무조건 왼쪽에서 오른쪽으로 간다고 생각하면 되고, 전위냐 중위냐 후위냐에 따라 부모 노드가 앞, 중간, 뒤에 붙는다고 생각하면 된다.

 

순회에 사용할 구조체

typedef struct Node
{
    int data;
    struct Node* Left, * Right;
}Node;

  ※ 앞서 봐왔던 구조체들과 다르지 않다.

 

 

 

전위순회(Preorder)

void Preorder(Node* node)
{
    if (node == NULL) return;
	
    printf("%d ", node->data);
    Preorder(node->Left);
    Preorder(node->Right);
}

  ※ 부모 노드가 처음에 위치하면 되므로 출력 순서는 부모 노드 ▶ 왼쪽 자식 노드 ▶ 오른쪽 자식 노드 순이다.

 

 

 

중위순회(Inorder)

void Inorder(Node* node)
{
    if (node == NULL) return;
	
    Inorder(node->Left);
    printf("%d ", node->data);
    Inorder(node->Right);
}

  ※ 부모 노드가 중간에 위치하면 되므로 출력 순서는 왼쪽 자식 노드 ▶ 부모 노드 ▶ 오른쪽 자식 노드 순이다.

 

 

 

후위순회(Postorder)

void Postorder(Node* node)
{
    if (node == NULL) return;
	
    Postorder(node->Left);
    Postorder(node->Right);
    printf("%d ", node->data);
}

  ※ 부모 노드가 마지막에 위치하면 되므로 출력 순서는 왼쪽 자식 노드 ▶ 오른쪽 자식 노드 ▶ 부모 노드 순이다.

 

 

 

풀 소스 코드와 예제 트리는 다음과 같다.

#include <stdio.h>

typedef struct Node
{
    int data;
    struct Node* Left, * Right;
}Node;

Node* Insert(Node* node, int data)
{
    if (node == NULL)
    {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data;
        newNode->Left = NULL;
        newNode->Right = NULL;
		
        return newNode;
    }
    else
    {
        if (node->data > data)
        {
            node->Left = Insert(node->Left, data);
        }
        else if (node->data < data)
        {
            node->Right = Insert(node->Right, data);
        }
        else
        {
            //중복 된 데이터이므로 추가하지 않는다.
        }

        return node;
    }
}

void Preorder(Node* node)
{
    if (node == NULL) return;
	
    printf("%d ", node->data);
    Preorder(node->Left);
    Preorder(node->Right);
}

void Inorder(Node* node)
{
    if (node == NULL) return;
	
    Inorder(node->Left);
    printf("%d ", node->data);
    Inorder(node->Right);
}

void Postorder(Node* node)
{
    if (node == NULL) return;
	
    Postorder(node->Left);
    Postorder(node->Right);
    printf("%d ", node->data);
}

void main()
{
    Node* root = NULL;

    //INSERT
    root = Insert(root, 20);
    root = Insert(root, 10);
    root = Insert(root, 32);
    root = Insert(root, 4);
    root = Insert(root, 13);
    root = Insert(root, 25);
    root = Insert(root, 55);
    
    //PREORDER
    Preorder(root);
    
    //결과 : 20 10 4 13 32 25 55
    
    //INORDER
    Inorder(root);
    
    //결과 : 4 10 13 20 25 32 55
    
    //POSTORDER
    Postorder(root);
    
    //결과 : 4 13 10 25 55 32 20
}

  ※ Insert 함수는 트리에 데이터를 넣기위한 함수이다.

반응형

'Stack > Data struct' 카테고리의 다른 글

C AVL 트리(AVL Tree) 구현  (2) 2021.09.11
C AVL 트리(AVL Tree) 설명  (0) 2021.09.10
C 이진탐색트리(Binary search tree) 구현  (0) 2021.09.09
C 트리(Tree) 설명  (0) 2021.09.09
C 큐(Queue) 구현  (0) 2021.09.09
반응형

  ※ 이 글은 코드 위주이니 설명은 아래 링크로 확인 !

  ※ C 트리(Tree) 설명

 

C 트리(Tree) 설명

트리 - 비선형 자료구조의 일종이다. - 계층적 관계(Hierarchical Relationship)를 표현하는 자료구조이다. ※ 사용 예로 컴퓨터의 디렉터리 구조를 들 수 있다. 용어 정리 1. 노드(Node) : 트리의 구성요소

srdeveloper.tistory.com

 

이진 탐색 트리에 사용할 구조체

typedef struct Node
{
    int data;
    struct Node* Left, * Right;
}Node;

  ※ 2개의 자식 노드를 가질것이므로 왼쪽, 오른쪽 참조 변수를 가진다.

 

 

 

데이터 삽입(Insert)

Node* Insert(Node* node, int data)
{
    if(node == NULL)
    {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data;
        newNode->Left = NULL;
        newNode->Right = NULL;
        
        return newNode;
    }
    else
    {
        if(node->data > data)
        {
            node->Left = Insert(node->Left, data);
        }
        else if(node->data < data)
        {
            node->Right = Insert(node->Right, data);
        }
        else
        {
        	//중복 된 데이터이므로 추가하지 않는다.
        }
        
        return node;
    }
}

  ※ 간결한 코드를 위해 재귀함수로 작성했다. (밑에 나올 수정, 탐색, 삭제, 순회 또한 재귀로 구성한다.)

  ※ 인수로 받은 데이터와 노드가 가진 키값의 대소관계에 따라 재귀 함수를 호출해준다.

 

 

 

데이터 수정(Modify)

void Modify(Node* node, int data, int newData)
{
    if(node == NULL) return;
    
    if(node->data == data)
    {
        node->data = newData;
    }
    else
    {
        if(node->data > data)
        {
            Modify(node->Left, data, newData);
        }
        else
        {
            Modify(node->Right, data, newData);
        }
    }
}

  ※ 더 이상 newData와 같은 키값을 가진 노드가 없거나, 같은 키값을 가진 노드가 나올때까지 재귀함수를 호출해서 만약 존재하면 데이터를 변경한다.

  ※ 수정할 때 이진 탐색 트리의 규칙에 위배되는 값이 들어가도 수정되는 코드는 따로 넣지 않았다. (기능의 본질에만 중점을 두고 작성되었다.)

 

 

 

데이터 탐색(Search)

Node* Search(Node* node, int data)
{
    if(node == NULL) return NULL;
    
    if(node->data == data)
    {
        return node;
    }
    else
    {
        if(node->data > data)
        {
            return Search(node->Left, data);
        }
        else
        {
            return Search(node->Right, data);
        }
    }
}

  ※ 더 이상 data와 같은 키값을 가진 노드가 없으면 NULL, 같은 키값을 가진 노드가 나올때까지 재귀함수를 호출해서 만약 노드가 존재하면 찾은 노드를 반환한다.

 

 

 

데이터 삭제(Delete)

Node* FindMinNode(Node* node, Node** minNode)
{
    if(node->Left == NULL)
    {
        *minNode = node;
        node = node->Right;
        return node;
    }
    else
    {
        node->Left = FindMinNode(node->Left, minNode);
        return node;
    }
}

Node* Delete(Node* node, int data)
{
    if(node == NULL) return NULL;
    
    if(node->data == data)
    {
        Node* deleteNode = node;
        if(node->Left == NULL && node->Right == NULL)
        {
            node = NULL;
        }
        else if(node->Left != NULL && node->Right == NULL)
        {
            node = node->Left;
        }
        else if(node->Left == NULL && node->Right != NULL)
        {
            node = node->Right;
        }
        else
        {
            Node* minNode = NULL;
            node->Right = FindMinNode(node->Right, &minNode);
            minNode->Left = deleteNode->Left;
            minNode->Right = deleteNode->Right;
            node = minNode;
        }
        
        free(deleteNode);
        return node;
    }
    else
    {
        if(node->data > data)
        {
            node->Left = Delete(node->Left, data);
        }
        else
        {
            node->Right = Delete(node->Right, data);
        }
        
        return node;
    }
}

  ※ 이진탐색트리에서의 삭제는 다른 자료구조와는 다르게 다소 복잡한 형태를 가지고 있다.

    1. 삭제할 키 값을 가지고 있는 노드를 재귀함수로 탐색한다.

    2. 노드를 찾게되면 조건을 다음과 같이 나눈다.

     2-1) 찾은 노드에서 양쪽의 자식이 없을 때 : 찾은 노드만 삭제하면 된다. (반환값 NULL)

     2-2) 왼쪽 자식 노드만 있을 때 : 찾은 노드를 삭제하고 왼쪽 노드를 반환한다.

     2-3) 오른쪽 자식 노드만 있을 때 : 찾은 노드를 삭제하고 오른쪽 노드를 반환한다.

     2-4) 양쪽 자식 노드가 전부 존재할 때 : 왼쪽 자식 노드 중 가장 큰 키값을 가진 노드를 찾거나, 오른쪽 자식 노드 중 가장 작은 키값을 가진 노드를 찾아서 키값이 일치한 노드의 자리에 넣어주고 기존의 노드는 삭제한다. (이렇게 찾는 이유는 이진 탐색 트리의 규칙 때문에 그렇다.)

      ※ 위의 코드를 기준으로는 오른쪽 자식 노드에서 가장 작은 키값을 가진 노드를 탐색하고있다.

      ※ 즉, 왼쪽 자식이 없는 노드가 가장 작은 키값을 가진 노드가 될것이므로 왼쪽 자식이 없는 노드를 찾을때까지 FindMinNode로 재귀함수를 호출한다.

 

  ※ 위 과정중에서 2-4의 방법이 제일 복잡한데, 이유는 FindMinNode 함수로 찾은 노드가 오른쪽 자식 노드를 갖고 있을 수도 있기 때문이다.

  ※ 즉, FindMinNode로 찾은 노드(이하 minNode)에서 Delete함수에서 인수로 받은 data와 같은 키값을 가지고 있는 노드(이하 rootNode)의 위치로 교체하기전에 minNode의 자식을 minNode의 부모노드와 연결 시키고 rootNode의 위치로 교체되어야 한다.

 

 

풀 소스코드는 다음과 같다.

#include <stdio.h>

typedef struct Node
{
    int data;
    struct Node* Left, * Right;
}Node;

Node* Insert(Node* node, int data)
{
    if(node == NULL)
    {
        Node* newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data;
        newNode->Left = NULL;
        newNode->Right = NULL;
        
        return newNode;
    }
    else
    {
        if(node->data > data)
        {
            node->Left = Insert(node->Left, data);
        }
        else if(node->data < data)
        {
            node->Right = Insert(node->Right, data);
        }
        else
        {
        	//중복 된 데이터이므로 추가하지 않는다.
        }
        
        return node;
    }
}

void Modify(Node* node, int data, int newData)
{
    if(node == NULL) return;
    
    if(node->data == data)
    {
        node->data = newData;
    }
    else
    {
        if(node->data > data)
        {
            Modify(node->Left, data, newData);
        }
        else
        {
            Modify(node->Right, data, newData);
        }
    }
}

Node* Search(Node* node, int data)
{
    if(node == NULL) return NULL;
    
    if(node->data == data)
    {
        return node;
    }
    else
    {
        if(node->data > data)
        {
            return Search(node->Left, data);
        }
        else
        {
            return Search(node->Right, data);
        }
    }
}

Node* FindMinNode(Node* node, Node** minNode)
{
    if(node->Left == NULL)
    {
        *minNode = node;
        node = node->Right;
        return node;
    }
    else
    {
        node->Left = FindMinNode(node->Left, minNode);
        return node;
    }
}

Node* Delete(Node* node, int data)
{
    if(node == NULL) return NULL;
    
    if(node->data == data)
    {
        Node* deleteNode = node;
        if(node->Left == NULL && node->Right == NULL)
        {
            node = NULL;
        }
        else if(node->Left != NULL && node->Right == NULL)
        {
            node = node->Left;
        }
        else if(node->Left == NULL && node->Right != NULL)
        {
            node = node->Right;
        }
        else
        {
            Node* minNode = NULL;
            node->Right = FindMinNode(node->Right, &minNode);
            minNode->Left = deleteNode->Left;
            minNode->Right = deleteNode->Right;
            node = minNode;
        }
        
        free(deleteNode);
        return node;
    }
    else
    {
        if(node->data > data)
        {
            node->Left = Delete(node->Left, data);
        }
        else
        {
            node->Right = Delete(node->Right, data);
        }
        
        return node;
    }
}

void ShowInOrder(Node* node)
{
    if (node == NULL) return;
    
    ShowInOrder(node->Left);
    printf("%d ", node->data);
    ShowInOrder(node->Right);
}

void main()
{
	Node* root = NULL;
    
    //INSERT
    root = Insert(root, 20);
    root = Insert(root, 10);
    root = Insert(root, 32);
    root = Insert(root, 4);
    root = Insert(root, 13);
    root = Insert(root, 25);
    root = Insert(root, 55);
    //               내부 구조
    //                  20
    //          10              32
    //      4       13      25      55

    ShowInOrder(root);
    //결과 : 4 10 13 20 25 32 55
	
    //MODIFY
    Modify(root, 10, 12);
    ShowInOrder(root);
    //결과 : 4 12 13 20 25 32 55
	
    //SEARCH
    printf("%d", Search(root, 12)->data);
    //결과 : 12
	
    //DELETE
    root = Delete(root, 32);
    //               내부 구조
    //                  20
    //          10              55
    //      4       13      25      

    ShowInOrder(root);
    //결과 : 4 12 13 20 25 55
}

  ※ 중위순회함수는 트리의 이해를 돕기 위해 잠시 넣은 함수이다.

  ※ 내부 구조 주석에서 보여지는 트리 데이터는 게시물 상단의 링크에서 사용한 트리를 바탕으로 세팅했다.

반응형

'Stack > Data struct' 카테고리의 다른 글

C AVL 트리(AVL Tree) 설명  (0) 2021.09.10
C 트리 순회(Tree traversal) 구현  (0) 2021.09.10
C 트리(Tree) 설명  (0) 2021.09.09
C 큐(Queue) 구현  (0) 2021.09.09
C 스택(Stack) 구현  (0) 2021.09.05
반응형

트리

- 비선형 자료구조의 일종이다.

- 계층적 관계(Hierarchical Relationship)를 표현하는 자료구조이다.

  ※ 사용 예로 컴퓨터의 디렉터리 구조를 들 수 있다.

 

용어 정리

1. 노드(Node) : 트리의 구성요소에 해당하는 요소.

2. 간선(Edge) : 노드와 노드를 연결하는 연결선.

3. 루트 노드(Root node) : 트리 구조에서 최상위에 존재하는 노드.

4. 단말 노드(Leaf node) : 아래로 또 다른 노드가 연결되어 있지 않은 노드.

5. 내부 노드(Internal node) : 단말 노드를 제외한 모든 노드.

6. 형제 노드(Sibling node) : 같은 부모를 가지는 노드.

 

 

이진 트리(Binary tree)

- 노드의 자식 수가 2 이하인 트리

 

 

포화 이진 트리(Full binary tree)

- 단말 노드를 제외한 모든 노드가 2개의 자식을 가진 트리

 

 

이진 탐색 트리(Binary search tree)

- 이진 탐색 트리는 이진 탐색과 이진 트리를 결합한 자료구조이다.

- 이진 탐색 트리는 다음과 같은 속성을 갖기 때문에 효율적인 탐색이 가능하다.

  1. 중복된 값을 혀용하지 않는다. (하지만 일부에서는 중복된 값을 혀용하는 경우도 있다.)

  2. 왼쪽 서브트리의 키들은 부모 노드의 키보다 작다.

  3. 오른쪽 서브트리의 키들은 부모 노드의 키보다 크다.

  4. 양쪽 서브트리는 그 자체로 이진 탐색 트리이다.

- 위와 같은 특징 때문에 탐색 연산은 O(log₂n)의 시간복잡도를 가진다.

 

트리 순회(Tree traversal)

- 트리의 순회는 전위 순회, 중위 순회, 후위 순회 세 가지가 있다.

  ※ 순회에서 중요한 부분은 자식 노드를 좌, 우 순서로 출력된다고 생각하면 된다.

- 전위 순회(PreOrder) : Root 노드부터 시작된다.

- 중위 순회(InOrder) : Root 노드가 중간에 위치한다.

- 후위 순회(PostOrder) : Root 노드가 마지막에 위치한다.

 

전위 순회

- Root 노드가 제일 먼저 순회가 시작되고 자식 노드의 좌, 우 순서로 순회가 이루어진다

- 즉, 탐색 순서는 A → B → D → E → C → F → G가 된다.

 

중위 순회

- 왼쪽 자식노드, Root 노드, 오른쪽 자식노드 순으로 순회가 이루어진다.

- 즉, 순회 순서는 D → B → E → A → F → C → G가 된다.

 

후위 순회

- 왼쪽 자식노드, 오른쪽 자식노드, Root 노드 순으로 순회가 이루어진다.

- 즉, 순회 순서는 D → E → B → F → G → C → A가 된다.

 

  ※ 어렵게 생각할 필요없이 자식 노드는 무조건 오른쪽 왼쪽 순으로 순회가 되고, 전위냐 중위냐 후위냐에 따라 Root 노드가 자식 노드들의 앞, 중간, 뒤에 위치한다고 생각하면 편하다.

반응형

'Stack > Data struct' 카테고리의 다른 글

C 트리 순회(Tree traversal) 구현  (0) 2021.09.10
C 이진탐색트리(Binary search tree) 구현  (0) 2021.09.09
C 큐(Queue) 구현  (0) 2021.09.09
C 스택(Stack) 구현  (0) 2021.09.05
C Linked List(연결리스트 구현)  (0) 2021.09.05
반응형

- 선형 자료구조의 일종이다.

- 먼저 들어간 것이 먼저 나오는 선입선출(FIFO : First In First Out)형식의 자료구조이다.

  ※ 사용 예로 번호표 시스템을 들 수 있다.

  ※ 들어간 순서대로 나오므로 위 그림 기준으로 오른쪽에 데이터가 입력이 되고, 왼쪽 데이터부터 출력이 이루어진다.

 

큐를 작성할 코드에 활용할 구조체는 다음과 같다.

typedef struct Queue
{
    int data;
    struct Queue* NEXT;
}Queue;

 

 

Enqueue(입력)

void Enqueue(Queue** front, Queue** rear, int data)
{
    Queue* newNode = (Queue*)malloc(sizeof(Queue));
    newNode->data = data;
    newNode->NEXT = NULL;
    
    if(*front == NULL)
    {
        *front = newNode;
        *rear = newNode;
    }
    else
    {
        (*rear)->NEXT = newNode;
        *rear = newNode;
    }
}

  ※ Stack과는 다르게 연결리스트의 첫 노드와 마지막 노드를 참조할 변수를 인수로 받아 값을 넣어준다.

  ※ 결과적으로 Queue의 데이터가 1개일때는 front와 rear가 같은 노드를 참조하게되고, 2개 이상이 되면 rear는 마지막 노드를 참조하게 된다.

 

 

Dequeue(출력)

void Dequeue(Queue** front, Queue** rear)
{
    if(*front == NULL) return;
    
    printf("%d ", (*front)->data);
    
    Queue* deleteNode = *front;
    *front = (*front)->NEXT;
    if(*front == NULL)
        *rear = NULL;
    
    free(deleteNode);
}

  ※ 데이터를 출력하고 front가 참조하고 있는 노드를 할당 해제해준다.

  ※ front가 NULL이면 Queue에 더이상 데이터가 없는것이므로 rear의 참조도 NULL로 밀어준다.

 

위 과정을 그림으로 보면 다음과 같다.

  ※ 첫 노드는 front, 제일 마지막 노드는 rear가된다.

  ※ Enqueue : 새 데이터를 입력하면 Enqueue함수에서 노드를 동적할당하고 rear에 새로 할당한 노드를 참조해준다.

  ※ Dequeue : front가 참조하고 있는 데이터를 출력하고 front의 참조를 다음 노드로 변경해준다.

 

 

풀 소스코드는 다음과 같다.

#include <stdio.h>
#define MAX 10

typedef struct Queue
{
    int data;
    struct Queue* NEXT;
}Queue;

void Enqueue(Queue** front, Queue** rear, int data)
{
    Queue* newNode = (Queue*)malloc(sizeof(Queue));
    newNode->data = data;
    newNode->NEXT = NULL;
    
    if(*front == NULL)
    {
        *front = newNode;
        *rear = newNode;
    }
    else
    {
        (*rear)->NEXT = newNode;
        *rear = newNode;
    }
}

void Dequeue(Queue** front, Queue** rear)
{
    if(*front == NULL) return;
    
    printf("%d ", (*front)->data);
    
    Queue* deleteNode = *front;
    *front = (*front)->NEXT;
    if(*front == NULL)
        *rear = NULL;
    
    free(deleteNode);
}

void main()
{
    Queue* front = NULL, * rear = NULL;
    for(int i = 0; i < MAX; i++)
        Enqueue(&front, &rear, i);
        
    //현재 상태 : 0(front), 1, 2, 3, 4, 5, 6, 7, 8, 9(rear)
    
    for(int i = 0; i < MAX; i++)
        Dequeue(&front, &rear);
        
    //결과 : 0 1 2 3 4 5 6 7 8 9
}
반응형

'Stack > Data struct' 카테고리의 다른 글

C 트리 순회(Tree traversal) 구현  (0) 2021.09.10
C 이진탐색트리(Binary search tree) 구현  (0) 2021.09.09
C 트리(Tree) 설명  (0) 2021.09.09
C 스택(Stack) 구현  (0) 2021.09.05
C Linked List(연결리스트 구현)  (0) 2021.09.05

+ Recent posts