Giriş
Depth First Search (DFS) sürekli alt seviyeye giderek tüm çocukları dolaşır.
Depth First Search (DFS) sürekli alt seviyeye giderek tüm çocukları dolaşır.
DFS Iterative veya Recursive olarak gerçekeleştirilebilir
1. Iterative Algoritma
DFS'in algoritması şöyledir.
Şöyle yaparız.
DFS'i gerçekleştirmek için 3 tane yöntem var. Ziyaret edilen düğüm hemen işleniyorsa Pre-Order denilir. İşleme In-Order, Post-Order olarak ta yapılabilir. Pre-Order dışında hiçbirini kullanmadım.
1. Pre-Order
Açıklaması şöyle. Düğüm ziyaret edilince hemen bir iş yapılır.
2. Post-Order
Açıklaması şöyle
Açıklaması şöyle.
Binary Tree Node Count
Ağaçtaki toplam düğüm sayısı bulunur.
Örnek - recursive
Şöyle yaparız.
Şöyle yaparız.
İmzasını şöyle yaparız.
Elimizde şöyle bir soru olsun.
Ağacın derinliği bulunur
Örnek - recursive
Şöyle yaparız.
1. Iterative Algoritma
DFS'in algoritması şöyledir.
1  procedure DFS-iterative(G,v):
2      let S be a stack
3      S.push(v)
4      while S is not empty
5            v = S.pop() 
6            if v is not labeled as discovered:
7                label v as discovered
8                for all edges from v to w in G.adjacentEdges(v) do
9                    S.push(w)Şöyle yaparız.
static bool Contains<T>(T item, Node<T> tree) {
  Stack<Node<T>> stack = new Stack<Node<T>>();
  stack.Push(tree); //Push the root node into the stack
  Node<T> current;
  do {
    current = stack.Pop(); //Get the last item 
    if (item.Equals(current.Data))
    {
      Console.WriteLine("Found");
      return true; //then return true
    }
    //Otherwise add the left and right nodes to the stack if they exist.
    if(current.Left != null)
      stack.Push(current.Left);
    if(current.Right != null)
      stack.Push(current.Right);
  } while(stack.Count > 0); //If the stack still contains items, go back to the 'do'
  //If we've reached this point we've searched the entire tree and found nothing
  return false;
}DFS'i gerçekleştirmek için 3 tane yöntem var. Ziyaret edilen düğüm hemen işleniyorsa Pre-Order denilir. İşleme In-Order, Post-Order olarak ta yapılabilir. Pre-Order dışında hiçbirini kullanmadım.
1. Pre-Order
Açıklaması şöyle. Düğüm ziyaret edilince hemen bir iş yapılır.
Do a depth-first traveral and write out the node when you encounter it the first time.
Örnek - recursive dolaşarak range içindekileri bulma
Elimizde bir fiyat ağacı olsun. low ve high arasındaki ürünleri bulmak için şöyle yaparız.
- Eğer low değeri düğümün sol tarafından halen küçükse sol taraf dolaşılır. 
- Eğer düğümün sağ tarafı high değerinden küçükse sağ taraf ta dolaşılır
- low = 7, high = 20 ise çıktı olarak {9, 8, 14, 20, 17} alırız
public static void preOrder(Node node, int low, int high, List<Integer> output){if (node != null) {if (node.val <= high && low <= node.val)output.add(node.val);if (low <= node.val)preOrder(node.leftChild, low, high, output);if (node.val <= high)preOrder(node.rightChild, low, high, output);}}public static List<Integer> productsInRange(Node root, int low, int high){List<Integer> output = new ArrayList<>();preOrder(root, low, high, output);return output;}public static void main( String args[] ) {// Driver codeBinarySearchTree bst = new BinarySearchTree();bst.insert(9);bst.insert(6);bst.insert(14);bst.insert(20);bst.insert(1);bst.insert(30);bst.insert(8);bst.insert(17);bst.insert(5);System.out.println(productsInRange(bst.root, 7, 20));}
Açıklaması şöyle
Do a depth-first traversal and write out the node after you have processed all its children.3. In-Order
Açıklaması şöyle.
Do a depth-first traversal and write out the left subtree first, then the node itself and afterwards the right subtree.
Klasik bir  In-Order kodu şöyledir
Elimizde şöyle bir ağaç olsun. Bu ağacı şöyle dolaşırsak in-order olur. 12, 25, 37, 50, 75, 62, 85
Elimizde şöyle bir ağaç olsun. Ağaç sıralı bir binary tree değil.private void inOrder(TreeNode node) {
  if (node == null) {
    return;
  }
  inOrder(node.left);
  System.out.printf("%s ", node.data); //Burası In-Order'da yapılan iş
  inOrder(node.right);
}
Elimizde şöyle bir ağaç olsun. Bu ağacı şöyle dolaşırsak in-order olur. 12, 25, 37, 50, 75, 62, 85
                          50
                         /  \
                        /    \
                       /      \
                     25        75
                    /  \      /  \
                  12    37  62    85                                     9
                                  /     \
                                 5       12
                                / \     /  \
                               2   7   11   15
                              /   /   /  \    \
                             3   6   10  13    16
                                                 \
                                                  17
pre-order: 9 5 2 3 7 6 12 11 10 13 15 16 17
post-order: 3 2 6 7 5 10 13 11 17 16 15 12 9
in-order: 3 2 5 6 7 9 10 11 13 12 15 16 17
3. Çeşitli Sorular
Bu sorular iterative veya recursive çözülebilir.
Ağaçtaki toplam düğüm sayısı bulunur.
Örnek - recursive
Şöyle yaparız.
int count(node *tree)
{
  int c =  1;             //Node itself should be counted
  if (tree ==NULL)
    return 0;
  else
  {
    c += count(tree->left);
    c += count(tree->right);
    return c;
  }
}Şöyle yaparız.
int count(Node root) {
  if (root != null) {
    return 1 + count(root.left) + count(root.right);
  } else {
    return 0;
  }
}İmzasını şöyle yaparız.
bool checkSame(Node* first, Node* second);return first->data == second->data 
    && checkSame(first->left, second->left)
    && checkSame(first->right, second->right); Elimizde şöyle bir soru olsun.
Düğümler şöyle olsunGiven the preorder traversal of a binary search tree, how do we identify the leaf nodes without building the tree?
[5,3,2,4,8,7,9][*,*,2,4,*,7,9]Ağacın derinliği bulunur
Örnek - recursive
Şöyle yaparız.
public int maxDepth(TreeNode root) {
   if(root == null)
    return 0;
  int left = maxDepth(root.left);
  int right = maxDepth(root.right);
  if(left > right)
    return left + 1;
  else
    return right + 1;
}public int maxDepth(TreeNode root) {
  if (root == null) {
    return 0;
  }
  return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
Şöyle yaparız.public static int getHeight(Node root) {
  if (root == null) return -1;
  return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}
public static boolean isBalanced(Node root) {
  if (root == null) return true;
  int heightDiff = getHeight(root.left) - getHeight(root.right);
  if (Math.abs(heightDiff) > 1) {
    return false;
  } else {
    return isBalanced(root.left) && isBalanced(root.right);
  }
}
Birbirine bağlı olan işler için kullanılır.Şöyle yaparız.
Elimizde şu işler olsun.
result = []
visited = {}
dfs(x):
  if x in visited: return
  visited.insert(x)
  for y in adj(x):
    dfs(y)
  result.push(x)
for x in V: dfs(x)
reverse(result)If a topological sort has the property that all pairs of consecutive vertices in the sorted order are connected by edges, then the topological sort order is unique.Örnek
Elimizde şu işler olsun.
A1, B, C1, A2, A3, F, G, C2, H, A4Sonucun şöyle olmasını isteyelim. Yani önce C'ler yapılacak, en son B'ler yapılacak. Aradaki işlerin sırası korunacak.
C1 C2 A1 A2 A3 F G H A4 BŞöyle yaparız.
template <typename Iterator, typename Compare>
void stable_toposort(Iterator begin, Iterator end, Compare cmp)
{
 while (begin != end)
 {
   auto const new_begin = std::stable_partition(begin, end, [&](auto const& a)
   {
     return std::none_of(begin, end, [&](auto const& b) { return cmp(b, a); });
    });
    assert(new_begin != begin && "not a partial ordering");
    begin = new_begin;
  }
}bool CompareItems(SItem const& item1, SItem const& item2)
{
 if (item1.type == C && item2.type == A) return true;
 if (item1.type == A && item2.type == B) return true;
 return false;
} 
 
Hiç yorum yok:
Yorum Gönder