Searching
      and Sorting
    Searching
    Boolean search: does the element belong to the set
        ("yes-no") vs. place search  if "place" is defined (index).
      Linear search.
      Binary search (bisection of
        interval).
      Hashtable: hash function
        (hashcode), collision, collision handling schemes, separate
        chaining, open addressing, linear probing, double hashing.
      Running time of different
        operations for different methods.
      
Sorting
      Abstract properties - time
        complexity and space complexity, average and worst case, running
        time in practice, ease of programming.
      Stable and unstable
        methods.
      "Slow" methods - quadratic:
        insertion sort
      "Quick" general methods -
        nlogn: quicksort (unstable), merge sort (extra memory), binary
        insertion sort (homework!), heapsort (discussed later). Divide
        and conquer strategies.
      Special methods: counting
        sort, radix sort, bucket sort.
      
      
    
    Otsimine ja järjestamine
     Otsimise ülesanne
     Tuvastada etteantud elemendi
        kuuluvus etteantud struktuuri. 
      Tulemuseks võib sõltuvalt ülesandest olla:
        tõeväärtus (kuulub-ei kuulu), "asukoht"
        struktuuris (või signaal mittekuulumise kohta), element
        ise vms. 
      Meie näidetes üritame leida elemendi asukohta. 
     Kahendotsimine (Binary Search)
      
     "Lõigu poolitamine"
        matemaatikas. On rakendatav kahel eeltingimusel: 
    
       
      -  vaadeldav struktuur on järjestatud
 
       
      -  elemendid on indekseeritavad
 
       
    
     O(log n)
       /**
    * Leida etteantud listist etteantud element kahendotsimise abil.
    * @param a list.
    * @param e otsitav element.
    * @returns otsitava elemendi indeks või -1, kui elementi ei leidu.
    */
   
   static public int otsi (List a, Comparable e) {
      int j = -1;
      int l = 0;              // vasakpoolne otspunkt
      int r = a.size() - 1;   // parempoolne otspunkt
      while (l <= r) {
         j = (l + r) / 2;
         if (e.compareTo ((Comparable)a.get (j)) == 0)
            return j;
         if (e.compareTo ((Comparable)a.get (j)) > 0)
            l = j+1; // vasak otspunkt nihkub paremale
         else
            r = j-1; // parem otspunkt nihkub vasakule
      };
      return -1;
   } // otsi lopp
     Paisktabel
    Lugeda vastav peatükk
        õpikust!
        
        Võtmed, võtmeruum, paisktabel, paiskfunktsioon,
        kollisioonid, välisahelad, lahtine adresseerimine,
        topeltpaiskamine
      
      Lisamine ja otsimine: O(1)
     Järjestamismeetodid
     Abstraktne keerukus,
        konkreetne keerukus (keskmine, halvim), mäluvajadus,
        algoritmi lihtsus, stabiilsus, ... 
    "Aeglased" meetodid: O(n2)
      
    
       
      -  lihtne pistemeetod
 
       
      -  mullimeetod
 
       
      -  valikumeetod
 
       
      -  ...
 
       
    
    
          "Kiired" meetodid: O(nlogn) 
    
    
       Erimeetodid (kitsendustega): O(n) 
    
    Positsioonimeetodi
        programm
    
    Vaata ka www.sorting-algorithms.com
       
    Pistemeetod (Insertion Sort):
     Jada jagatakse
        "järjestatud osaks" (algselt tühi) ja
        "järjestamata osaks" (algselt kogu jada). 
      Järjestatud osa pikkust suurendatakse järjekordse
        elemendi paigutamisega õigele kohale järjestatud
        osas. 
        
       /**
    * Sorteerida pistemeetodil List, mille elemendid realiseerivad
    * liidest Comparable.
    * @param a sorteeritav list.
    */
   static public void pisteSort (List a) {
      if (a.size() < 2) return;
      for (int i=1; i<a.size(); i++) {
         Comparable b = (Comparable) a.remove (i);
         int j;
         for (j=0; j<i; j++) {
            if (b.compareTo ((Comparable)a.get (j)) < 0) break;
         }
         a.add (j, b); // pistame b kohale j
      }
   } // pisteSort() lopp
/**
 * Sorteerime massiivi, mille elemendid realiseerivad
 * liidest Comparable.
 * @param a sorteeritav massiiv.
 */
   static public void pisteSort (Comparable[] a) {
      if (a.length < 2) return;
      for (int i=1; i<a.length; i++) {
         Comparable b = a[i];
         int j;
         for (j=i-1; j>=0; j--) {
            if (a[j].compareTo (b) <= 0) break;
            a[j+1] = a[j]; // vabastame pistekoha
         }
         a[j+1] = b; // pistame b kohale
      }
   } // pisteSort() lopp
 
     Kahendpistemeetod:
     "Õige" koht leitakse
        kahendotsimisega: O(nlogn), kui "pistmine" oleks O(1)
      
      
      
    Ühildusmeetod (Merge Sort):
    "Jaga ja valitse" : jagatakse
        kogu aeg pooleks (kuni pikkus < 2), pooled ühendatakse
        lineaarse keerukusega ühildamise abil, kasutatakse
        lisamälu mahuga O(n)
        
      
         static public <T extends Object
          & Comparable<? super T>> void
             
mergesort
          (List<T> massiiv, int l, int r) {
                
if
(massiiv.size()
          < 2) return;
                
if
((r-l)<2)
          return;
                
int
k
          = (l+r)/2;
                
mergesort
(massiiv,
          l, k);
                
mergesort
(massiiv,
          k, r);
                
merge
(massiiv,
          l, k, r);
           } //
          mergesort() lopp
        
           static public
          <T extends Object & Comparable<? super T>>
          void
             
merge
          (List<T> massiiv, int l, int k, int r) {
                
if
(massiiv.size()
          < 2) return;
                
if
((r-l)
          < 2) return;
                
if
(k<=l)
          return;
                
if
(k>=r)
          return;
                
List<T>
abi
          = new ArrayList<T>(r-l);
                
int
n1
          = l;
                
int
n2
          = k;
                
T
elem
          = null;
                
while
(true)
          {
                   
if
((n1
          < k) && (n2 < r)) {
                      
if
(massiiv.get
          (n1).compareTo (massiiv.get (n2)) > 0) {
                         
elem
=
          massiiv.get (n2);
                         
          n2++;
                      
}
else
          {
                         
elem
=
          massiiv.get (n1);
                         
          n1++;
                      
          }
                      
          abi.add (elem);
                   
}
else
          {
                      
if
(n1
          >= k) {
                         
for
(int
          i = n2; i < r; i++) {
                            
abi.add
(massiiv.get
          (i));
                         
          }
                         
          break;
                      
}
else
          {
                         
for
(int
          i = n1; i < k; i++) {
                            
abi.add
(massiiv.get
          (i));
                         
          }
                         
          break;
                      
          }
                   
          }
                
          }
                
for
(int
          i=l; i < r; i++) {
                   
massiiv.set
(i,
          abi.get (i-l));
                
          }
           } 
      
      
      
     
     Kiirmeetod (Quicksort):
     (Osa)jada jagatakse kaheks
        lühemaks osajadaks nii, et ükski element esimeses osas
        ei oleks suurem ühestki elemendist teises osas. Siis
        võib kummagi osa sorteerida eraldi (nad on
        sõltumatud). "Jaga ja valitse" 
        
       /**
    * Sorteerida massiiv kiirmeetodil.
    * @param massiiv sorteeritav massiiv.
    * @param l vasakpoolne otspunkt.
    * @param r parempoolne otspunkt.
    */
   static public void sort (Comparable[] massiiv, int l, int r) {
      if (massiiv.length < 2) return;
      int i = l; int j = r;
      Comparable x = massiiv [(i+j) / 2];
      do {
         while (massiiv [i].compareTo (x) < 0) i++;
         while (x.compareTo (massiiv [j]) < 0) j--;
         if (i <= j) {
            Comparable tmp = massiiv [i];
            massiiv [i] = massiiv [j]; massiiv [j] = tmp;
            // selle koha peal on väljatrükk silumiseks: "veelahe" ja vahetatavad
            i++; j--;
         }
      } while (i < j);
      if (l < j) sort (massiiv, l, j+1); // rekursioon
      if (i < r-1) sort (massiiv, i, r); // rekursioon
   } // sort() lopp
    Otsimisel ja järjestamisel
        on abiks
       
      java.util.Arrays, java.util.Collections 
        
        
    
    J. Pöial