23 Ekim 2019 Çarşamba

Fourier Transform

Giriş
Açıklaması şöyle.
the Fourier transform takes a real or complex signal as an input, and produces a complex signal as an output,
Fourier Transform Neden Var
Bir çok sinyal periyodik değil. Şeklen şöyle

Açıklaması şöyle. Yani bir sinyali sinüs sinyallerin toplamı haline getiriyor.
... that any function, whether continuous or discontinuous, can be expanded into a series of sines (to be completely accurate, into a series of complex exponentials, but don't worry about this for now). What this means is that each of these sines can be combined linearly (fancy word to say "summed") to add up to the original signal.

In that sense you could say that aperiodic signals, such as the noise you took as an example, "have many different wavelengths". In fact, they are composed of an infinite sum of sinusoidal (hence periodic) waveforms, each with a different wavelength, amplitude, and phase.

- period / frequency / wavelength: how long it takes for that sine to complete a cycle (in seconds) / how many cycles that sine goes through in a second (in Hz) / the distance traveled by that sine in one cycle (in meters).
- amplitude: the amount of that sine in the original signal.
- phase: the offset of that sine relative to a sine with same frequency and 0 phase.

So, how do you get the wavelength, amplitude and phase for each of these components? Here comes the Fourier Transform.

Fourier Transform Çeşitleri
Temelde iki çeşit Fourier Transform var

1. Continuous Fourier Transform
Açıklaması şöyle.
There's little in the ways of actual need for this in digital electronics – digital signals are sampled, so you'd use the DFT.
Bu neden kullanılmıyor. Açıklaması şöyle. Yani sonsuz sinyaller içindir. Dijital sinyaller ise sonsuz değildir. Mutlaka örnekleme yapılır.
The answer is the same to the question: "Why do we need computers to process data when we have paper and pencil?"

DTFT as well as the continuous-time Fourier Transform is a theoretical tool for infinitely long hypothetical signals.

the DFT is to observe the spectrum of actual data that is finite in size.
2. Discrete Fourier Transform (DFT)
Açıklaması şöyle
- The Fourier transform is a framework to analyze these types of aperiodic signals. Using clever mathematics, you can transform a time-domain signal (including, but not limited to, noise) into the frequency-domain, which allows you to compute the characteristics (wavelength, amplitude and phase) for each sine wave that compose this signal.

- The DFT (Discrete Fourier Transform) is used when dealing with discrete signals, and is usually implemented using the FFT (Fast Fourier Transform) algorithm. Depending on your software/language (MatlabPythonRC?) there are libraries you can use to easily compute that.
Açıklaması şöyle.
Usually, that's implemented as an FFT, Fast Fourier Transform. That's one of the most important algorithmic discoveries of the 20th century, ...
Açıklaması şöyle.
There are 4 versions of Fourier transforms that are all close cousins.

It's all due to the basic property that "sampling in one domain corresponds to periodicity in the other domain". If a time signal is periodic, the frequency domain signal is discrete. If a frequency domain signal is periodic, the time domain signal is discrete.
Tablo şöyle.
> `Time                       Frequency               Transform 
Continuos & aperidoc          Continuos & aperidoc    Fourier Transform
Discrete  & aperidoc          Continuos &  peridoc    Discrete Time Fourier Transform
Continuos &  peridoc          Discrete  & aperidoc    Fourier Series
Discrete  &  peridoc          Discrete  &  peridoc    Discrete Fourier Transform
2.1 Fast Fourier Transform - Yani Discrete Fourier Transform Gerçekleştirimi
Açıklaması şöyle. Aslında Discrete Fourier Transform'un daha hızlı çalışan bir alt kümesi.
First, the fast Fourier transform is just an algorithm that realizes the discrete Fourier transform quickly; so it's a perfect subset of the DFT.
FFT zaman ekseninde verilen sinyali , frekans ekseninde gösterecek şekilde bileşenlere ayırır. FFT ile yapılan bir varsayım sinyalin tek seferlik değil, periyodik olmasıdır.

FFT 2^n örnek alırsa geriye 2^(n-1) tane gerçek veya sanal sayı (imaginary number) döndürür.
How to get Frequency from FFT result sorusundan da anlaşıldığı gibi 44,100 Hz ile yapılan 1024 örnekleme de FFT sonucunda çıkan değerlerin sadece 511 tanesi kullanılabiliyor.

FFT yaparken örneklemeye window'da denilir. Sinyal üzerindeki pencereyi kaydırırken, pencerelerin bir miktar çakışmasına dikkat edilir.

Örnek
Şöyle yaparız
/*
  Fast Fourier transform
  T is the precision level: float, double, long double.
  Overwrites the input.
  Only works for input sizes that are a power of 2.
*/
template<typename T>
    requires std::is_floating_point<T>
void FFT(std::vector<std::complex<T>>& input)
{
    if (input.size() == 0) {
        throw std::invalid_argument("input is empty");
    }
    if (input.size() & (input.size() - 1)) {
        throw std::invalid_argument("input length is not a power of two");
    }

    auto const table = internal::rootsOfUnity<T>(input.size());
    internal::FFT(input, table, input.size());
}
Kullanmak için şöyle yaparız.
// Test program
#include <iostream>

int main()
{
  static constexpr size_t n = 1048576;
  std::vector<std::complex<double>> input;
  for (std::size_t i = 0;  i < n;  ++i) {
    input.emplace_back(i);
  }

  // Overwrite input with its Fourier transform
  FFT<double>(input);

  // use the result, to avoid optimising out
  std::cout << input[0] << '\n';
}
internal namespace içindeki metodlar şöyledir.
#include <complex>
#include <vector>

namespace internal
{
  /*
    Creating the table of all N'th roots of unity.
    We use notation ω_i = e^(-2πi/n).
  */
  template<typename U>
  constexpr auto rootsOfUnity(std::size_t n)
  {
    constexpr auto pi = std::acos(U{-1.0});
    std::vector<std::complex<U>> table;
    table.reserve(n);

    for (std::size_t i = 0;  i < n;  ++i) {
      table.emplace_back(std::cos(-2.0 * pi * i / n), std::sin(-2.0 * pi * i / n));
    }

      return table;
  }

  template<typename V>        // V is vector of complex
  void FFT(V& input, const V& table, std::size_t total_size)
  {
    if (input.size() <= 1) {
      // The Fourier transform on one element does not do
      // anything, so nothing needed here.
      return;
    }

    const auto n2 = input.size() / 2;

    // Split up the input in even and odd components
    V evenComponents;  evenComponents.reserve(n2);
    V oddComponents;   oddComponents.reserve(n2);

    for (std::size_t i = 0;  i < input.size();  ) {
      evenComponents.push_back(input[i++]);
      oddComponents.push_back(input[i++]);
    }

    // Transform the even and odd input
    FFT(evenComponents, table, total_size);
    FFT(oddComponents, table, total_size);

    // Use the algorithm from Danielson and Lanczos
    for (std::size_t i = 0;  i < n2;  ++i) {
      // ω_n^i = (ω_N^(N/n))^i = ω_N^(Nk/n)
      auto const plusMinus = table[total_size / n2 * i] * oddComponents[i];
      input[i] = evenComponents[i] + plusMinus;
      input[i + n2] = evenComponents[i] - plusMinus;
    }
  }
}



21 Ekim 2019 Pazartesi

Zigbee

Giriş
Açıklaması şöyle
Zigbee Standard: ZigBee 3.0 based on IEEE802.15.4 Frequency: 2.4GHz Range: 10-100m Data Rates: 250kbps
Şeklen şöyle

Ana Kullanım Alanı
Açıklaması şöyle.
Low power consumption and tolerating low data rate applications like home automation, industrial automation, smart lighting, and building automation
Routed Mesh Network
 Z-wave ve Zigbee için açıklama şöyle.
The other consideration with these two is that they are both routed mesh networks. We use one node to communicate with another node using intervening nodes. In other words, we can send a message from A to B to C to D, but in practice, we’ve sent a message from A to D. As routed meshes, each node understands the path the message needs to take, and that has an in-memory cost associated with it. While Z-wave and Zigbee have a theoretical limit of 65,535 nodes on a network (the address space is a 16-bit integer), the practical limit is closer to few hundred nodes, because these devices are usually low power, low memory devices. The routing also has a time cost, so a large mesh network may manifest unacceptable latency for your use case. Another consideration, especially if you’re launching a cloud-controlled consumer product, is that these mesh networks can’t directly connect to the Internet — they require an intervening bridge (a.k.a gateway, hub, edge server) to communicate to the cloud.




Bluetooth Low Energy (BLE)

Giriş
Bu teknoloji klasik Bluetooth çok güç tükettiği için çıkarıldı. Hızı 100kbps menzili ise en fazla 150 metre civarında. Bunu 100 metre kabul etmek daha doğru. 77 metrede 10mW güç tüketiyor. Özellikleri şöyle.
Bluetooth Standard: Bluetooth 4.2 core specification Frequency: 2.4GHz (ISM) Range: 50-150m (Smart/BLE) Data Rates: 1Mbps (Smart/BLE)
Zigbee Standard: ZigBee 3.0 based on IEEE802.15.4 Frequency: 2.4GHz Range: 10-100m Data Rates: 250kbps
Z-Wave Standard: Z-Wave Alliance ZAD12837 / ITU-T G.9959 Frequency: 900MHz (ISM) Range: 30m Data Rates: 9.6/40/100kbit/s
6LowPAN Standard: RFC6282 Frequency: (adapted and used over a variety of other networking media including Bluetooth Smart (2.4GHz) or ZigBee or low-power RF (sub-1GHz) Range: N/A Data Rates: N/A
Thread Standard: Thread, based on IEEE802.15.4 and 6LowPAN Frequency: 2.4GHz (ISM) Range: N/A Data Rates: N/A
WiFi Standard: Based on 802.11n (most common usage in homes today) Frequencies: 2.4GHz and 5GHz bands Range: Approximately 50m Data Rates: 600 Mbps maximum, but 150-200Mbps is more typical, depending on channel frequency used and number of antennas (latest 802.11-ac standard should offer 500Mbps to 1Gbps)
Cellular Standard: GSM/GPRS/EDGE (2G), UMTS/HSPA (3G), LTE (4G) Frequencies: 900/1800/1900/2100MHz Range: 35km max for GSM; 200km max for HSPA Data Rates (typical download): 35-170kps (GPRS), 120-384kbps (EDGE), 384Kbps-2Mbps (UMTS), 600kbps-10Mbps (HSPA), 3-10Mbps (LTE)
NFC Standard: ISO/IEC 18000-3 Frequency: 13.56MHz (ISM) Range: 10cm Data Rates: 100–420kbps
Sigfox Standard: Sigfox Frequency: 900MHz Range: 30-50km (rural environments), 3-10km (urban environments) Data Rates: 10-1000bps
Neul Standard: Neul Frequency: 900MHz (ISM), 458MHz (UK), 470-790MHz (White Space) Range: 10km Data Rates: Few bps up to 100kbps
LoRaWAN Standard: LoRaWAN Frequency: Various Range: 2-5km (urban environment), 15km (suburban environment) Data Rates: 0.3-50 kbps.
BLE ilginç bir şekilde Stop-and-wait ARQ kullanıyor.

Topology
Broadcast, Point to Point ve Mesh olabilir.

Ana Kullanım Alanı
Açıklaması şöyle.
Use-cases that need continious streamaing of data, such as headphones, fitness band, wireless speakers, interactive displays, AssetTracking

Bağlanabilen Cihaz Sayısı
Açıklaması şöyle.
Bluetooth was originally designed for ‘personal area networks,’  with the original standard supporting 7 concurrent devices. And now we have Bluetooth low energy (BLE), which has a theoretically infinite limit.
Az Güç Tüketimi İçin Yapılanlar
Açıklaması şöyle.
They looked heavily at the amount of energy required to support communication. They considered every facet of "low energy," not just the radio — they looked at data format, packet size, how long the radio needed to be on to transmit those packets, how much memory was required to support it, what the power cost was for that memory, and what the protocol expects of the CPU, all while keeping overall BOM costs in mind. For example, they figured out that the radio should only be on for 1.5ms at a time. That’s a sweet spot — if you transmit for longer, the components heat up and thus require more power. They also figured out that button cell batteries are better at delivering power in short bursts as opposed to continuously. Further, they optimized it to be really durable against Wi-Fi interference because the protocols share the same radio space (2.4GHz).
Internet Protocol Support Profile (IPSP)
IPv6 paketlerinin BLE ile gönderilebilmesi (tunnel/tünel) içindir. Açıklaması şöyle
The Internet Protocol Support Profile (IPSP) allows devices to discover and communicate to other devices that support IPSP. The communication between the devices that support IPSP is done using IPv6 packets over the Bluetooth Low Energy transport. — Bluetooth 4.2 Specification

CMMI - Risk Yönetimi Süreci

RSKM (Risk Management) - Project Management

Risk Nedir?
Gerçekleşmesi durumunda plan veya projeye ters etkisi olacak durum.

RSKM (Türkçesi : Risk Yönetimi) CMMI Seviye 3 olan firmaların yapması gereken süreç alanlarından birisidir. Süreç aşağıdaki gibi
Specific Practices by Goal
SG 1 Prepare for Risk Management
  SP 1.1 Determine Risk Sources and Categories
  SP 1.2 Define Risk Parameters
  SP 1.3 Establish a Risk Management Strategy
SG 2 Identify and Analyze Risks
  SP 2.1 Identify Risks
  SP 2.2 Evaluate, Categorize, and Prioritize Risks
SG 3 Mitigate Risks
  SP 3.1 Develop Risk Mitigation Plans
  SP 3.2 Implement Risk Mitigation Plans
Bu listedeki mitigate kelimesi günlük İngilizcede pek karşımıza çıkmaz. Hafifletme, yumuşatma anlamına gelir.

Riskin Kaynağı ve Sınıflandırılması
Aşağıdaki cümleler CMMI belgesinden
"Identification of risk sources provides a basis for systematically examining changing situations over time to uncover circumstances that impact the ability of the project to meet its objectives. Risk sources are both internal and external to the project. As the project progresses, additional sources of risk may be identified. Establishing categories for risks provides a mechanism for collecting and organizing risks as well as ensuring appropriate scrutiny and management attention for those risks that can have more serious consequences on meeting project objectives.

Establishing categories for risks provides a mechanism for collecting and organizing risks as well as ensuring appropriate scrutiny and management attention for those risks that can have more serious consequences on meeting project objectives."
Risk kaynakları olarak ne yazılır ve riskler nasıl gruplanır, bazı örnekleri burada bulabilirsiniz.

Riskin Tanımlanması
Bu seviyede artık risklerin tanımlanır ve gruplanır. Riskin gerçekleşebilme olasılığı belirtilir, gerçekleştiği takdirde etkilerinin ne olacağı düşünülür, riskleri hafifletme ve bertaraf etme için yapılacak işler planlanır.

Riskin tanımlanması esnasından kullanılacak cümle nasıl olmalı?
Risk tanımlama (Risk Identification) esnasında kullanılacak cümlenin 3 kısımdan oluşması tavsiye ediliyor. Sebep (definitive cause), risk (uncertain event), sonuç (effect on objective veya contingent possibility)

Örnek
"X verilerinin zamanında hazır olmaması durumunda geliştirilecek algoritmanın seçimi ve performansı yetersiz kalabilir, gerçek veri geldiğinde tekrar çalışmak gerekebilir."
Ancak çoğu zaman bu dil takip edilmeden aşağıdaki gibi sadece riski içeren cümleler kullanılıyor.

Örnek
Risk : Teslim edilecek işin yetiştirilememe ihtimali
Mitigation :  X konusunda tecrübesi bulunan bir kişinin destekte bulunması, doğrulama için atanması.
En gıcık riskler gerçekleşme olasılığı düşük ancak etkisi yıkısı olan riskler :)

Bu süreçte en çok gördüğüm yanlış riskleri sadece yazıp bir izleme listesine alma ve gerçekleşinceye kadar hiç bir şey yapmama.

Risk yönetimi için Jira yazılımının başarıyla kullanıldığını gördüm.

Bir CMMI denetiminde "İşler kötü giderse ne yapmak lazım?" şeklinde bir soru sorulursa Risk Yönetimine atıfta bulunulabilir.
Benim gördüğüm kadarıyla işler kötüye giderse kısmı ele alınmış, ancak işler iyi giderse hangi sürece göre bu durumu yaygınlaştırabiliriz sorusunun cevabını bilmiyorum.

Riskin Gerçekleşmesi
Risk gerçekleşince issue'ya dönüşür ve Issue Tracking System'da bir madde açılır.

Jira'da Risk Yönetimi İçin Kullanılabilecek Alanlar
Bu alanlar yukarıda anlatılan S.G maddelerini kapsıyor.
Risk CategoryEngineering, Finance...S.P. 1.1
Risk Management MethodAvoid, Mitigate, Prevent, Monitor, Transfer, Accept S.P. 1.3
DescriptionRiskin tanımı. Riskin tanımlanması esnasından kullanılacak cümle nasıl olmalı başlığına bakabilirsiniz.S.P. 2.1
ImpactRiskin gerçekleşmesi durumunda etkisi:
Low/Medium/High
S.P. 2.2
PossibilityRiskin gerçekleşme olasılığı:
Low/Medium/High
S.P. 2.2
Risk StakeholdersCustomer, Dev. TeamS.P. 2.2
Mitigation AlternativesRiski hafifletme, yumuşatma etme seçenekleri. Bazı Mitigation Örnekleri:
  • Teknik toplantı düzenleyerek görüş alma süresinin azaltılması
  • Müşteriye kendimizi tanıtmak, koordinasyonu sağlamak
  • Resmi yollardan bilgi istemek
  • Benzer bir donanım üzerinde çalışmak
S.P. 3.1
Contingency PlanOlası İhtiyat Planı diyebiliriz. Bir çok sözleşmede Contingency Clause bulunur. Bu cümle belli bir koşulun oluşması durumunda yükümlülükleri belirtir. Contingency Plan aynı mantıkla riskin gerçekleşmesi durumunda ne yapılacağını belirtir.S.P. 3.2

Bir başka açıklama şöyle.
What is different between 'accidental' and 'contingent'?
Colloquial meanings of the two words are pretty close, accidental is "occurring unexpectedly or by chance", contingent is "subject to chance; occurring or existing only if (certain circumstances) are the case; dependent on". If there is a shade of difference, it is that contingent may well be expected as a possibility, albeit along other options, whereas accidental is something more of a "completely" unexpected. A coin landing on either heads or tails are "contingent" events,...


Depth First Search

Giriş
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.
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)
Örnek
Şö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;
}
2. Düğümün İşlenmesi
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 code
  BinarySearchTree 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));
}
2. Post-Order
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
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);
}
Örnek
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
Örnek
Elimizde şöyle bir ağaç olsun. Ağaç sıralı bir binary tree değil.
                                     9
                                  /     \
                                 5       12
                                / \     /  \
                               2   7   11   15
                              /   /   /  \    \
                             3   6   10  13    16
                                                 \
                                                  17
Bu ağacın dolaşması şöyledir.
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.

Binary Tree Node Count

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;
  }
}
Örnek - recursive
Şöyle yaparız.
int count(Node root) {
  if (root != null) {
    return 1 + count(root.left) + count(root.right);
  } else {
    return 0;
  }
}
İki Binary Tree'nin Eşit Olması
İmzasını şöyle  yaparız.
bool checkSame(Node* first, Node* second);
İçi şöyledir.
return first->data == second->data 
    && checkSame(first->left, second->left)
    && checkSame(first->right, second->right);
Binary Tree Leaves 
Elimizde şöyle bir soru olsun.
Given the preorder traversal of a binary search tree, how do we identify the leaf nodes without building the tree?
Düğümler şöyle olsun
[5,3,2,4,8,7,9]
Her düğümün iki çocuğu olduğunu varsayarsak ve pre-order dolaştığımızı tersten başlarız ve graph'ı şu hale getiririz.
[*,*,2,4,*,7,9]
Binary Tree Depth
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;
}
İkinci If'ten kurtulmak için şöyle yaparız.
public int maxDepth(TreeNode root) {
  if (root == null) {
    return 0;
  }
  return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
Binary Tree Balanced 
Şö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);
  }
}
Topological Sort
Birbirine bağlı olan işler için kullanılır.Şöyle yaparız.
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)
Açıklaması şöyle
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, A4
Sonucun şö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;
  }
}
Comparator şöyledir. stable_partition() ile elemanları kendi içinde gruplarız ve gruplama tüm elemanlar bitinceya kadar devam eder. Önce C ve A'ları gruplarız. Daha sonra A ve B'leri gruplarız.
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;
}