• 특징





각각의 노드는 고유한 키값이 존재


각 키값은 중복될 수 없다!


자식 노드는 최대 2개 까지


부모보다 작은 노드는 왼쪽에, 큰 노드는 오른쪽에 위치한다


탐색은 항상 최상단 루트(Root)부터




  • 삽입





새 노드의 위치를 찾기 위해서 루트(Root)부터 탐색한다.


탐색한 노드보다 새 노드가 작으면 왼쪽, 크면 오른쪽으로 계속 탐색


다음 탐색 위치가 비어있다면, 그 위치에 새 노드 삽입





삽입 종료






  • 삭제


삭제는 몇가지 종류로 나뉜다.

01. 자식이 없는 노드 삭제

02. 자식이 한쪽만 있는 노드 삭제

03. 자식이 양쪽 다 있는 노드 삭제



    • 자식이 없는 노드 삭제

가장 간단한 경우 이다.

그냥 삭제하면 된다.




    • 자식이 한쪽만 있는 노드 삭제    


삭제할 노드의 자식을

삭제노드의 위치로 옯겨주고

노드를 삭제하면 된다.








    • 자식이 양쪽 다 있는 노드 삭제


자식이 양쪽 다 있는 노드를 삭제할때

왼쪽에서 가장 큰 노드를 찾아 삭제노드 위치에 두는 방법

오른쪽에서 가장 작은 노드를 찾아 삭제노드 위치에 두는 방법등

여러 방법은 많지만, 아래의 방법은 왼쪽에서 가장 큰 노드를 찾는 방법이다.




왼쪽에서 가장 큰 노드는 오른쪽 자식 노드가 없기 때문에

고려하지 않아도 된다.




    • 삭제 전체 코드




  • 전체 코드








  • 힙(Heap)


힙은 데이터에서 최대값(혹은 최소값을) 빠르게 찾을 수 있는 자료구조

힙은 완전 이진 트리다.

우선순위가 가장 높은 데이터가 제일 앞(루트)에 위치한다.

부모는 자식보다 우선순위가 더 높은 데이터가 배치된다.
(ex. 큰 데이터가 더 우선된다면, 모든 부모 노드는 자신의 자식 노드보다 더 크다)

대표적으로 최대 힙과 최소 힙이 있다.

최대 힙(Max Heap) : 
데이터 중 가장 큰 값이 루트에 위치
모든 부모 노드는 자식보다 크거나 같다.

최소 힙(Min Heap) :
데이터 중 가장 작은 값이 루트에 위치
모든 부모 노드는 자식보다 작거나 같다.






  • 배열을 활용한 힙 구현








  • 우선순위 큐(Priority Queue)



데이터들이 우선순위를 갖는다.

입력순서에는 상관없이 우선순위가 높은 데이터가 가장 먼저 처리된다.

아래의 모든 설명은 최대 힙을 활용한 우선순위 큐이다.





  • 삽입














  • 삭제








  • 전체 코드





  • 레벨 순회




레벨 순회 결과 : E -> B -> G -> A -> D -> F -> H -> C


-한 레벨의 모든 노드를 방문 하고 다음 레벨 방문


-레벨에서 방문 하는 순서는 왼쪽 -> 오른쪽


  • 코드보기



 

 

 

 

 

 

 

  • 후위 순회

 

 

 

 

 

 

 

후위 순회 결과 : A -> C -> D -> B ->F -> H -> G -> E

 

-왼쪽노드 -> 오른쪽 노드 -> 부모노드 순으로 방문

 

-쉽게 생각하면, 자식 노드들 모드 방문 후 마지막으로 부모 노드 방문

 

-루트 노드를 가장 마지막에 방문

 

 

  • 코드보기

 

-재귀함수를 이용한 후위 순회

더보기

//재귀함수를 이용한 후위 순회

void BinaryTree::Postorder_Recursion(NODE *node)

{

        if (node == NULL)

               return;

 

        //왼쪽 노드 재귀함수 실행

        Postorder_Recursion(node->Left);

 

        //오른쪽 노드 재귀함수 실행

        Postorder_Recursion(node->Right);

 

        //자신 데이터 출력

        PrintNode(node->Data);

 

}

 

 

-스택을 이용한 후위 순회

더보기

//스택을 이용한 후위 순회

void BinaryTree::Postorder_Stack(NODE* node)

{

        m_Stack.Clear();

 

        while (true)

        {

               while (NULL != node)

               {

                      //현재 노드를 2번 입력

                       m_Stack.Push(node);

                       m_Stack.Push(node);

 

                       //왼쪽 노드로 이동

                       node = node->Left;

               }

 

               if (!m_Stack.IsEmpty())

               {

                       node = m_Stack.Pop();

 

                       //현재 노드의 첫번째 방문일때, 오른쪽으로 이동

                       if (!m_Stack.IsEmpty() && node == m_Stack.Peek())

                       {

                              node = node->Right;

                       }

                       //현재 노드를 두번째 방문 했을때 출력한다.

                       else

                       {

                              PrintNode(node->Data);

                              node = NULL;

                       }

               }

               else

               {

                       break;

               }

        }

}

 

출처  https://www.geeksforgeeks.org/iterative-postorder-traversal-using-stack/

 





  • 중위 순회










중위 순회 결과 : A -> B -> C -> D ->E -> F -> G -> H


-왼쪽을 가장 먼저 방문하며, 오른쪽 노드 방문전에 부모노드를 방문


-이진 탐색 트리에서 사용하면 크기 순서대로 나열됨



  • 코드보기

-재귀함수를 이용한 중위 순회



-스택을 이용한 중위 순회








  • 전위 순회









전위 순회 결과 : E -> B -> A -> D -> C -> G -> F -> H


-왼쪽을 우선으로 진행하며, 부모노드 방문 후 자식노드를 좌, 우 순서로 방문한다고 생각하면 쉽다.


  • 코드보기

-재귀함수를 이용한 전위 순회



-스택을 이용한 전위 순회




'자료구조' 카테고리의 다른 글

트리 순회 알고리즘#03 후위 순회(Postorder Traversal)  (4) 2017.01.23
트리 순회 알고리즘#02 중위 순회(Inorder Traversal)  (0) 2017.01.23
이진 트리(Binary Tree)  (0) 2017.01.23
큐(Queue)  (0) 2017.01.22
스택(Stack)  (0) 2017.01.21

 

 

 

 

 

 

 

  • 트리의 주요 용어
 
 
 

 

 

 

루트(Root) : 최상위 노드(부모가 없는 노드), 루트 노드는 트리에 단 하나만 존재한다. 노드A가 루트 노드

 

리프(Leaf) : 최하위 노드(자식이 없는 노드), 리프 노드는 트리에 복수가 존재할 수 있다. B, E, C가 리프 노드

 

부모(Parent) : 어떤 노드의 상위 노드, 노드는 단 하나의 부모 노드만을 갖는다.

B와 C의 부모 노드 : A

D와 E의 부모 노드 : B

 

자식(Child) : 어떤 노드의 하위 노드, 자식 노드의 갯수는 구현에 따라 달라질 수 있지만, 이진 트리에선 최대 2개의 자식 노드만 갖는다.

A의 자식 노드 : B, C

B의 자식 노드 : D, E

 

형제(Sibling) : 같은 부모를 갖는 자식 노드들

B와 C

D와 E

 

 

 

  • 트리의 순회 알고리즘(링크)
  1. 전위 순회(Preorder Traverse)로 가기
  2. 중위 순회(Inorder Traverse)로 가기
  3. 후위 순회(Postorder Traverse)로 가기
  4. 레벨 순회(Level Order Traverse)로 가기
 
 
  • 전체 코드
※트리에 사용한 템플릿 스택(Stack)
더보기

#pragma once

#include "stdafx.h"

 

template<typename T>

class tStack

{

private:

        typedef struct _Node

        {

               T Data;

               struct _Node* Next;

 

               _Node()

               {

                       Data = NULL;

                       Next = NULL;

               }

 

               _Node(T data)

               {

                       Data = data;

                       Next = NULL;

               }

        } NODE;

 

private:

        NODE *m_top, *m_bottom;

 

public:

        tStack()

        {

               m_top = new NODE();

               m_bottom = new NODE();

 

               Init();

        }

 

        ~tStack()

        {

               Clear();

 

               delete m_top;

               delete m_bottom;

 

               m_top = NULL;

               m_bottom = NULL;

        }

 

        //스택 비우기

        void Clear(void)

        {

               NODE* indexNode = m_top->Next;

               for (indexNode; indexNode != m_bottom;)

               {

                       NODE* deleteNode = indexNode;

                       indexNode = indexNode->Next;

 

                       delete deleteNode;

                       deleteNode = NULL;

               }

 

               Init();

        }

 

        //입력

        void Push(T data)

        {

               // 노드 생성 데이터 입력

               NODE *newNode = new NODE(data);

 

               // 노드의 Next 현재 제일 앞에 있는 노드를 지정

               newNode->Next = m_top->Next;

 

               //현재 노드를 제일 노드로 지정

               m_top->Next = newNode;

        }

 

        //출력

        T Pop(void)

        {

               // 노드가 마지막 노드(m_bottom : 빈노드) 데이터가 없음

               if (IsEmpty())

                       return NULL;

 

               //첫번째 노드 데이터 수령

               NODE *deleteNode = m_top->Next;

               T result = deleteNode->Data;

 

               //2번째 노드를 첫번째 노드로

               m_top->Next = m_top->Next->Next;

 

               //첫번째 노드 삭제

               delete deleteNode;

               deleteNode = NULL;    

 

               //결과 반환

               return result;

        }

 

       //삭제 없이 출력

        T Peek(void)

        {

               // 노드가 마지막 노드(m_bottom : 빈노드) 데이터가 없음

               if (IsEmpty())

                       return NULL;

 

               //첫번째 노드 데이터 리턴

               return  m_top->Next->Data;

        }

 

        //비었는지 확인

        bool IsEmpty(void)

        {

               // 노드가 마지막 노드(m_bottom : 빈노드) 데이터가 없음

               if (m_top->Next == m_bottom)

                       return true;

               else

                       return false;

        }

 

private:

        //초기화

        void Init(void)

        {

               m_top->Next = m_bottom;

               m_bottom->Next = m_bottom;

        }

};

 
※트리에 사용한 템플릿 큐(Queue)
더보기

#pragma once

#include "stdafx.h"

 

template<class T>

class tCircularQueue

{

private:

        T *m_Queue;                   //

        int m_Front;                  //제일 먼저 입력된 데이터의 위치

        int m_Rear;                   //가장 늦게 입력된 데이터의 다음위치 ->빈공간

        const int SIZE;

 

public:

        tCircularQueue(const int QueueSize) :SIZE(QueueSize)

        {

               m_Queue = new T[QueueSize];

               Init();

        }

 

        ~tCircularQueue()

        {

               delete[] m_Queue;

               m_Queue = NULL;

        }

 

        //초기화

        void Init(void)       

        {

               m_Front = 0;

               m_Rear = 0;

        }

 

        //데이터 삽입

        void Put(T data)

        {

               //Rear 다음 위치 계산

               int nextIndex = (m_Rear + 1) % SIZE;

 

               //다음 위치가 Front위치라면 입력 중단->큐가 꽉찬 상태

               if (nextIndex == m_Front)

                       return;

 

               //현재 Rear위치에 데이터 입력

               m_Queue[m_Rear] = data;

 

               //Rear 다음 칸으로 이동

               m_Rear = nextIndex;

        }

 

        //데이터 추출

        T Get(void)

        {

               //Front Rear 같은 위치라면 -> 데이터가 없는 상태

               if (IsEmpty())

                       return NULL;

 

               //데이터 저장

               T result = m_Queue[m_Front];

 

               //Front 한칸 뒤로 이동

               m_Front = (m_Front + 1) % SIZE;

 

               return result;

        }

 

        bool IsEmpty()

        {

               if (m_Front == m_Rear)

                       return true;

 

               return false;

        }

};

 

 

 
※트리 코드
더보기

#pragma once

#include "tStack.h"

#include "tCircularQueue.h"

 

class BinaryTree

{

private:

        typedef struct _Node

        {

               _Node(char data)

               {

                       Data = data;

                       Left = NULL;

                       Right = NULL;

               }

 

               char Data;

               struct _Node *Left;

               struct _Node *Right;

        }NODE;

 

private:

        NODE *m_root;

        tStack<NODE*> m_Stack;

        tCircularQueue<NODE*> m_Queue = tCircularQueue<NODE*>(16);

public:

        BinaryTree();

 

        ~BinaryTree();

 

        void Push(char);

 

        void TraversalPreorder(bool);                //전위 순회

        void TraversalInorder(bool);                 //중위 순회

        void TraversalPostorder(bool);               //후위 순회

        void TraversalLevelorder(void);              //레벨 순회

 

private:

        void Preorder_Stack(NODE*);                   //스택을 이용한 전위 순회

        void Preorder_Recursion(NODE*);               //재귀함수를 이용한 전위 순회

 

        void Inorder_Stack(NODE*);                    //스택을 이용한 중위 순회

        void Inorder_Recursion(NODE*);                //재귀함수를 이용한 중위 순회

 

        void Postorder_Stack(NODE*);                 //스택을 이용한 후위 순회

        void Postorder_Recursion(NODE*);             //재귀함수를 이용한 후위 순회

private:

        void PrintNode(char data);                   //노드 데이터 출력

        void StackNode(NODE*);                       //노드 스택에 입력(+NULL체크도)

};

 

더보기

#include "stdafx.h"

#include "BinaryTree.h"

 

 

BinaryTree::BinaryTree()

{

        m_root = NULL;

}

 

 

BinaryTree::~BinaryTree()

{

        m_Stack.Clear();

       

        delete m_root;

}

 

//트리에 데이터 입력

void BinaryTree::Push(char data)

{

        //루트가 NULL이라면 루트에 데이터 입력

        if (m_root == NULL)

        {

               m_root = new NODE(data);

               return;

        }

       

        //루트 노드부터 검색 시작

        NODE* indexNode = m_root;            

        while (true)

        {

               //중복 데이터 입력 방지

               if (indexNode->Data == data)

                       return;

 

               //입력 받은 데이터가 현재 노드의 데이터 보다 작다면 -> 왼쪽 노드 체크

               if (indexNode->Data > data)

               {

                       //자식 노드가 비어있다면, 노드 생성 & 데이터 입력

                       if (indexNode->Left == NULL)

                       {

                              indexNode->Left = new NODE(data);

                              break;

                       }

                       else//아니라면 index노드에 현재 왼쪽 자식 노드 입력

                              indexNode = indexNode->Left;

               }

               else //입력 받은 데이터가 현재 노드의 데이터 보다 크다면 -> 오른쪽 노드 체크

               {

                       //자식 노드가 비어있다면, 노드 생성 & 데이터 입력

                       if (indexNode->Right == NULL)

                       {

                              indexNode->Right = new NODE(data);

                              break;

                       }

                       else//아니라면 index노드에 현재 오른쪽 자식 노드 입력

                              indexNode = indexNode->Right;

               }

        }

}

 

//전위순회

void BinaryTree::TraversalPreorder(bool bUseStack)

{

        printf("전위순회");

 

        if (bUseStack)

               printf("[스택]"), Preorder_Stack(m_root);

        else

               printf("[재귀]"), Preorder_Recursion(m_root);

 

        printf("\n");

}

 

//중위 순회

void BinaryTree::TraversalInorder(bool bUseStack)

{

        printf("중위순회");

 

        if (bUseStack)

               printf("[스택]"), Inorder_Stack(m_root);

        else

               printf("[재귀]"), Inorder_Recursion(m_root);

       

 

        printf("\n");

}

 

//후위 순회

void BinaryTree::TraversalPostorder(bool bUseStack)

{

        printf("후위순회");

 

        if (bUseStack)

               printf("[스택]"), Postorder_Stack(m_root);

        else

               printf("[재귀]"), Postorder_Recursion(m_root);

 

 

        printf("\n");

}

 

//레벨 순회

void BinaryTree::TraversalLevelorder(void)

{

        printf("레벨순회");

 

        NODE* indexNode;

       

        // 초기화

        m_Queue.Init();

 

        //루트노드 입력

        m_Queue.Put(m_root);

 

        //큐가 빌때까지 반복

        while (!m_Queue.IsEmpty())

        {

               //제일 먼저 입력된 노드 수령

               indexNode = m_Queue.Get();

 

               //방문(출력)

               PrintNode(indexNode->Data);

 

               //왼쪽 노드가 있다면 왼쪽노드 큐에 입력

               if (indexNode->Left != NULL)

                       m_Queue.Put(indexNode->Left);

 

               //오른쪽 노드가 있다면 왼쪽노드 큐에 입력

               if (indexNode->Right != NULL)

                       m_Queue.Put(indexNode->Right);

        }

 

        printf("\n");

}

 

//스택을 이용한 전위 순회

void BinaryTree::Preorder_Stack(NODE* rootNode)

{

        NODE* indexNode;

 

        m_Stack.Clear();

        //스택에 제일먼저 루트를 입력

        m_Stack.Push(rootNode);

 

        //스택이 빌때까지 반복

        while (!m_Stack.IsEmpty())

        {

               //스텍 최상단 노드 출력

               indexNode = m_Stack.Pop();

 

               //노드 데이터 프린트

               PrintNode(indexNode->Data);

 

               //오른쪽 노드가 있다면 스텍에 입력

               StackNode(indexNode->Right);

 

               //왼쪽 노드가 있다면 스텍에 입력 <= 후입선출(LIFO)이니까 먼저 출력됨

               StackNode(indexNode->Left);

        }

}

 

//재귀함수를 이용한 전위 순회

void BinaryTree::Preorder_Recursion(NODE* node)

{

        if (node == NULL)

               return;

 

        //자신을 출력하고

        PrintNode(node->Data);

 

        //왼쪽 방문

        Preorder_Recursion(node->Left);

 

        //마지막으로 오른쪽 방문

        Preorder_Recursion(node->Right);

}

 

 

//스택을 이용한 중위 순회

void BinaryTree::Inorder_Stack(NODE* rootNode)

{

        NODE *indexNode = rootNode;

 

        m_Stack.Clear();

 

        while (true)

        {

               //현재 노드에서 도달 있는 최좌측 노드 찾기 & 경로에 있는 노드들 저장

               while (indexNode != NULL)

               {

                       //현재 노드 저장

                       m_Stack.Push(indexNode);

 

                       //다음 좌측 노드 지정

                       indexNode = indexNode->Left;

               }

 

               //스택에 노드가 있다면

               if (!m_Stack.IsEmpty())

               {

                       //가장 늦게 이력된 노드 수령

                       indexNode = m_Stack.Pop();

 

                       // 노드 데이터 출력

                       PrintNode(indexNode->Data);

 

                       //현재 노드의 우측노드를 다음 노드로 => 다음 반복에서 상위 While문에 있는 m_Stack.Push 스택에 입력됨

                       indexNode = indexNode->Right;

               }

               else

                       break;

        }

}

 

//재귀함수를 이용한 중위 순회

void BinaryTree::Inorder_Recursion(NODE * node)

{

        if (node == NULL)

               return;

 

        //왼쪽 노드 재귀함수 실행

        Inorder_Recursion(node->Left);

 

        //자신 데이터 출력

        PrintNode(node->Data);

 

        //오른쪽 노드 재귀함수 실행

        Inorder_Recursion(node->Right);

}

 

 

//스택을 이용한 후위 순회

void BinaryTree::Postorder_Stack(NODEnode)

{

        m_Stack.Clear();

 

        while (true)

        {

               while (NULL !node)

               {

                      //현재 노드를 2번 입력

                       m_Stack.Push(node);

                       m_Stack.Push(node);

 

                       //왼쪽 노드로 이동

                       node = node->Left;

               }

 

               if (!m_Stack.IsEmpty())

               {

                       node = m_Stack.Pop();

 

                       //현재 노드의 첫번째 방문일때, 오른쪽으로 이동

                       if (!m_Stack.IsEmpty() && node == m_Stack.Peek())

                       {

                              node node->Right;

                       }

                       //현재 노드를 두번째 방문 했을때 출력한다.

                       else

                       {

                              PrintNode(node->Data);

                              node = NULL;

                       }

               }

               else

               {

                       break;

               }

        }

}

 

//재귀함수를 이용한 후위 순회

void BinaryTree::Postorder_Recursion(NODE *node)

{

        if (node == NULL)

               return;

 

        //왼쪽 노드 재귀함수 실행

        Postorder_Recursion(node->Left);

 

        //오른쪽 노드 재귀함수 실행

        Postorder_Recursion(node->Right);

 

        //자신 데이터 출력

        PrintNode(node->Data);

}

 

//노드 데이터 프린트

void BinaryTree::PrintNode(char data)

{

        printf(" -> %c", data);

}

 

//스택에 노드 입력

void BinaryTree::StackNode(NODE *node)

{

        if (node != NULL)

               m_Stack.Push(node);

}

 

 

후위 순위(스택) 코드 출처: https://www.geeksforgeeks.org/iterative-postorder-traversal-using-stack/







  • 큐의 기본 구조





-큐는 입력과 출력의 방향이 반대다.


-들어온 순서대로 처리가되는 선입선출(FIFO), 이와 반대되는 후입선출(LIFO) 방식의 대표적인 예는 스택(Stack)이 있다.


-큐(Queue)란 단어의 의미는 대기행령, 대기줄이다. 어떤 일을 순차적으로 처리하고자 할때 사용된다.


-큐에서 입력은 Put, 출력을 Get이라 편의상 부르겠다(입력을 Enqueue, 출력을 Dequeue라고 하기도 한다).





  • 환형큐(원형큐)



-왚과 뒤가 원처럼 이어져 있는 큐 구조


-입력과 출력이 이어지며, Front와 Rear의 위치가 계속 변경되게 된다.


-선형큐의 문제점을 해결하기 위해, 나왔다고 한다.


-입력을 하면 Rear(뒷 부분)가 한칸 뒤로 밀린다.


-출력을 하면 Front(앞 부분)가 한칸 뒤로 밀린다.


-Rear는 빈공간을 가리킨다.


-최대 입력 가능한 데이터 수는, 최대 공간보다 한칸 적다(Rear가 빈공간을 하나 차지하니까!).

Max Data = Max Size - 1;








  • 큐의 입력(Put, Enqueue)








  • 큐의 출력(Get, Dequeue)





  • 전체 코드










  • 스택 기본 구조



-스택은 입출력이 한방향으로 이루어 진다(자료를 입력하는 쪽과 출력하는 쪽이 같다).

-늦게 들어온 자료가 더 빨리 나가는 구조(LIFO : Last in First out).

-일반적으로 스텍에서 입력을 Push, 출력을 Pop이라고 한다.






현실에서 LIFO의 예



  • 스택의 삽입(Push)

-스택의 삽입은 가장 앞쪽에서 이루어 진다.


-위 그림에서 Head노드는 데이터는 갖지 않고, 첫번째 노드의 위치를 저장하는 노드다

(Head노드에도 데이터를 저장한다면, 삽입 노드가 Head노드가 되게하면 된다).



Head노드의 다음노드(Next) = 삽입노드

삽입 노드의 다음노드(Next) = 노드#01(첫번째 데이터 노드)




삽입 완료





  • 스택의 출력(Pop)



출력(Pop) 요청시 첫번째 노드를 출력




Head노드의 다음노드(Next)를 2번째 노드(출력 노드의 Next)로 지정

( = 2번째 노드를 첫번째 노드로 만듬)



데이터 전달 & 노드를 삭제를 완료하면

출력 종료




  • 전체 코드




  • 템플릿으로 구현한 스택


'자료구조' 카테고리의 다른 글

트리 순회 알고리즘#01 전위 순회(Preorder Traversal)  (0) 2017.01.23
이진 트리(Binary Tree)  (0) 2017.01.23
큐(Queue)  (0) 2017.01.22
이중 링크드 리스트(Doubly Linked List)  (1) 2017.01.20
링크드 리스트(Linked List)  (0) 2017.01.20









  • 이중 링크드 리스트 기본 구조


-노드는 정보(Data) & 다음 노드(Next)가 누구인지  & 이전 노드가(Prev) 누구인지 저장하고 있다.


-제일 앞의 노드(Head)와 제일 뒤의 노드(End)를 연결 시키면 원형 링크드 리스트가 된다.



  • 단일 링크드 리스트와의 차이

-이중 링크드 리스트는 전 노드에 접근 가능하다는 장점이 있다.



  • 이중 링크드 리스트 삽입


삽입할 노드가 들어갈 위치를 찾고,



노드#01의 다음노드(Next) = 삽입노드

삽입 노드의 전 노드(Prev) = 노드#01



삽입 노드의 다음노드(Next) = 노드#02

노드#02의 전 노드(Prev) = 삽입노드




삽입 종료


  • 이중 링크드 리스트 삭제
이중 링크드 리스트의 삭제는

삭제할 노드의 앞뒤를 연결 시킨 후, 삭제할 노드를 삭제하면 된다.

단일 링크드 리스트와 다른 점이라면, 뒷노드의 Prev(전 노드)도 신경 써야 한다는 점이다.



삭제할 노드를 찾고,




삭제할 노드의 앞노드(삭제 노드의 Prev) : 노드#01

삭제할 노드의 다음 노드(삭제 노드의 Next) : 노드#02


[노드#01과 노드#02를 연결]

노드#01의 다음 노드(Next) = 노드#02

노드#02의 전 노드(Prev) = 노드#01



앞뒤 노드 연결이 완료되면,

노드를 삭제하면 된다.


  • 전체 코드



'자료구조' 카테고리의 다른 글

트리 순회 알고리즘#01 전위 순회(Preorder Traversal)  (0) 2017.01.23
이진 트리(Binary Tree)  (0) 2017.01.23
큐(Queue)  (0) 2017.01.22
스택(Stack)  (0) 2017.01.21
링크드 리스트(Linked List)  (0) 2017.01.20

+ Recent posts