Pa-Lab 2019. 6. 15. 23:29

선형 데이터 구조 (Linear Data Structure) 

  • items are organized one after another

  • list, stack, queue

비선형 데이터 구조 (Nonlinear Data Structure) 

  • item have multiple immediate successor
  • tree, graph

트리 (Tree)


비선형 자료구조

계층형 자료구조

확장되는 나무 모양의 구조

노드 (Node) : 트리를 구성하는 원소

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

서브 트리 (Sub Tree) : 자식노드들이 독립하여 구성한 트리

 

노드간의 관계 용어


자식 (Child) : the node directly below node n in the tree

부모 (Parent) : the node directly above node n in the tree

형제 (Siblings) : nodes with a common parent

루트 (Root) : the only node in the tree with no parent, the name of tree

단말 (Leaf) : a node with no child

조상 (Ancestor) : a node on the path from the root to node n

자손 (Descendant) : a node on the path from node n to a leaf

 

높이 (Height)

  노드의 높이 : 루트에서 노드에 이르는 간선의 수

  트리의 높이 : 트리에 있는 노드의 높이 중에서 가장 큰 값

차수 (Degree)

  노드의 차수 : 노드에 연결된 자식 노드의 수

  트리의 차수 : 트리에 있는 노드의 차수 중에서 가장 큰 값

 

이진트리 (Binary Tree)


트리의 노드 구조를 일정하게 정의하여 트리의 구현과 연산이 쉽도록 정의한 트리

특성 1 : n개의 노드를 가진 이진 트리는 항상 (n-1)개의 간선을 가진다.

특성 2 : 높이 h 이진 트리는 최소 h+1개 최대 2^(h+1) - 1개의 노드를 가진다.

포화 이진 트리 : 모든 레벨에 노드가 포화상태로 차 있는 이진 트리

완전 이진 트리 : 1번 부터 n번까지 빈 자리가 없는 이진 트리

편향 이진 트리 : 한쪽 방향의 자식 노드만을 가진 이진 트리

 

이진트리의 순회 


typedef struct treeNode {
  char data;
  struct treeNode *left;
  struct treeNode *right;
}treeNode;

전위 순회

void preorder(treeNode* root)
{
  if(root)
  {
    printf("%c", root->data);
    preorder(root->left);
    preorder(root->right);
  }
}

중위 순회

void inorder(treeNode* root)
{
  if(root)
  {
    inorder(root->left);
    printf("%c", root->data);
    inorder(root->right);
  }
}

후위 순회

void postorder(treeNode* root)
{
  if(root)
  {
    postorder(root->left);
    postorder(root->right);
    printf("%c", root->data);
  }
}

 

이진 탐색 트리


이진 트리에 탐색을 위한 조건을 추가하여 정의한 자료구조

탐색 연산

searchBST(bsT, x)
  p ← bsT;
  if (p=null) then
    return null;
  if (x = p.key) then
    return p;
  if (x < p.key) then
    return searchBST(p.left, x);
  else 
    return searchBST(p.right, x);
end searchBST() 

삽입 연산

insertBST(bsT, x)
  p ← bsT;
  while (p≠null) do {
    if (x = p.key) return;
    q ← p;
    if (x < p.key) p ← p.left;
    else           p ← p.right;
  }
  new ← getNode();
  new.key ← x;
  new.left ← null;
  new.right ← null;
  if (bsT = null)      bsT←new;
  else if (x < q.key)  q.left ← new;
  else                 q.right ← new;
  return;
end insertBST()

삭제 연산

deleteBST(bsT, x)
  p ← 삭제할 노드;
  parent ← 삭제할 노드의 부모 노드;
  if (p = null) then return;
  if (p.left = null and p.right = null) then { // (1) 차수가 0인 노드(단말노드) 삭제
    if (parent.left = p) then parent.left ← null;
    else parent.right ← null;
  }
  else if (p.left = null or p.right = null) then { // (2) 차수가 1인 노드의 삭제
    if (p.left ≠ null) then { // 왼쪽자식노드를 가진 경우
      if (parent.left = p) then parent.left ← p.left;
      else parent.right ← p.left;
    }
    else { // 오른쪽자식노드를 가진 경우
      if (parent.left = p) then parent.left ← p.right;
      else parent.right ← p.right;
    }
  }
  else if (p.left ≠ null and p.right ≠ null) then { // (3) 차수가 2인 노드의 삭제
    q ← maxNode(p.left);
    p.key ← q.key;
    deleteBST(p.left, p.key);
  }
end deleteBST() 

 

히프


완전 이진 트리에 있는 노드 중에서 키 값이 가장 큰 노드나 키 값이 가장 작은 노드를 찾기 위해서 만든 자료형

삽입 연산

insertHeap(heap, item)
  if (n = heapSize) then heapFull();
  n ← n+1; // 1
  for (i ← n; ;) do {
    if (i = 1) then exit;
    if (item ≤ heap[ i/2 ]) then exit; // 2
    heap[i] ← heap[ i/2 ]; // 3
    i ← i/2 // 4
  }
  heap[i] ← item; // 5
end insertHeap()

삭제 연산

deleteHeap(heap)
  if (n = 0) then return error;
  item ← heap[1]; // 1 루트노드의 원소를 item에 저장
  temp ← heap[n]; // 2 마지막노드의 원소를 temp에 보관
  n ← n-1; // 3 히프의 노드개수 1감소
  i ← 1; // 4 i: temp원소가 저장될 노드번호 저장변수
  j ← 2; // j : i의 좌측자식노드 번호
  while (j ≤ n) do {
    if (j < n) then
    if (heap[j] < heap[j+1]) then j ← j+1; // 키값이 큰 자식노드 찾기
    if (temp ≥ heap[j]) then exit; // 5 자식노드가 작으면, 자리 확정
    heap[i] ← heap[j]; // 6 자식노드가 크면, 자리 교환
    i ← j;
    j ← j*2;
  }
  heap[i] ← temp; // 7
  return item; // 8
end deleteHeap()