Qidiruv algoritmlari. Axborot izlashning asosiy tamoyillari. Kеtma-kеt izlash. Izlashning tеzlashtiririlgan usullari

Qidiruv   algoritmlari.   Axborot   izlashning   asosiy   tamoyillari.   K е tma-k е t
izlash. Izlashning t е zlashtiririlgan usullari.
Reja:
  Laboratoriya ishi nazariy ma’lumotlarini o’rganish;
    Berilgan topshiriqning algoritmini ishlab chiqish;
    C++ dasturlash muhitida dasturni yaratish; 
  Natijalarni tekshirish;
    Hisobotni tayyorlash va topshirish.  2.1.   Ma’lumotlarni   tuzilmadan   qidirish   Kompyuterda   ma’lumotlarni   qayta   ishlashda
qidiruv   asosiy   amallardan   biri   hisoblanadi.   Uning   vazifasi   berilgan   argument   bo’yicha
massiv ma’lumotlari ichidan mazkur argumentga mos ma’lumotlarni topish yoki bunday
ma’lumot yo’qligini aniqlashdan iborat. Ixtiyoriy ma’lumotlar majmuasi jadval yoki fayl
deb   ataladi.   Ixtiyoriy   ma’lumot   (yoki   tuzilma   elementi)   boshqa   ma’lumotdan   biror   bir
belgisi   orqali   farq   qiladi.   Mazkur   belgi   kalit   deb   ataladi.   Kalit   noyob   bo’lishi,   ya’ni
mazkur   kalitga   ega   ma’lumot   jadvalda   yagona   bo’lishi   mumkin.   Bunday   noyob   kalitga
boshlang’ich   (birinchi)   kalit   deyiladi.   Ikkinchi   kalit   bir   jadvalda   takrorlansada   u   orqali
ham   qidiruvni   amalga   oshirish   mumkin.   Ma’lumotlar   kalitini   bir   joyga   yig’ish   (boshqa
jadvalga)   yoki   yozuv   sifatida   ifodalab   bitta   maydonga   kalitlarni   yozish   mumkin.   Agar
kalitlar   ma’lumotlar   jadvalidan   ajratib   olinib   alohida   fayl   sifatida   saqlansa,   u   holda
bunday kalitlar tashqi kalitlar deyiladi. Aks holda, ya’ni yozuvning bir maydoni sifatida
jadvalda   saqlansa   ichki   kalit   deyiladi.   Kalitni   berilgan   argument   bilan   mosligini
aniqlovchi algoritmga berilgan argument bo’yicha qidiruv deb ataladi.
  Qidiruv   algoritmi   vazifasi   kerakli   ma’lumotni   jadvaldan   topish   yoki   yo’qligini
aniqlashdan   iboratdir.   Agar   kerakli   ma’lumot   yo’q   bo’lsa,   u   holda   ikkita   ishni   amalga
oshirish mumkin: 
1. Ma’lumot yo’qligini indikatsiya qilish (belgilash) 
2.   Jadvalga   ma’lumotni   qo’yish.   Faraz   qilaylik,   k  –   kalitlar  massivi.  Har   bir  k(i)   uchun
r(i)   –   ma’lumot   mavjud.   Key   –   qidiruv   argumenti.   Unga   rec   -   informatsion   yozuv   mos
qo’yiladi.   Jadvaldagi   ma’lumotlarning   tuzilmasiga   qarab   qidiruvning   bir   necha   turlari
mavjud. 
2.2. Ketma-ket qidiruv algoritmi Mazkur ko’rinishdagi qidiruv agar ma’lumotlar tartibsiz
yoki   ular   tuzilishi   noaniq   bo’lganda   qo’llaniladi.   Bunda   ma’lumotlar   butun   jadval
bo’yicha operativ xotirada kichik adresdan boshlab, to katta adresgacha ketma-ket qarab
chiqiladi.   Massivda   ketma-ket   qidiruv   (search   o’zgaruvchi   topilgan   element   tartib
raqamini saqlaydi). Ketma-ket qidiruv algoritmi C++ tilida quyidagicha bo’ladi: 
int qidiruv(int key){ for (int i=0;i<n; i++)
If (k[i]==key) {search=I; return search;}
Search=-1;
Return search; }}
Massivda   ketma-ket   qidiruv   algoritmi   samaradorligini   bajarilgan   taqqoslashlar   soni   M
bilan aniqlash mumkin.
  Mmin  = 1, Mmax =  n. Agar ma’lumotlar  massiv  yacheykasida bir  xil  ehtimollik  bilan
taqsimlangan bo’lsa, u holda Mo’ (n + 1)/2 bo’ladi. Agar kerakli element jadvalda yo’q
bo’lib,   uni   jadvalga   qo’shish   lozim   bo’lsa,   u   holda   yuqorida   keltirilgan   algoritmdagi
oxirgi ikkita operator quyidagicha almashtiriladi.
n=n+1; 
k[n-1]:=key; 
r[n-1]:=rec; 
search:=n-1;
return search;
Agar ma’lumotlar jadvali bir bog’lamli ro’yhat ko’rinishida berilgan bo’lsa (2.1- rasm), u
holda ketma-ket qidiruv ro’yhatda amalga oshiriladi.
2.1-rasm.   Bir   bog’lamli   ro’yhatning   ko’rinishi   Chiziqli   bir   bog’lamli   ro’yhatdan   key
kalitga mos elementni ketma-ket qidiruv usuli yordamida izlab topish dasturi.
Node *q=NULL; 
Node *p=lst;
 while (p !=NULL)
{ if (p->k == key)
{ search = p; return search; } 
q = p; p = p->nxt; }
 Node *s=new Node;; 
s->k=key; s->r=rec; s->nxt= NULL;
 if (q == NULL){ s->nxt=lst; lst = s; }
else q->nxt = s; search= s; return search;  
Ro’yhatli   tuzilmaning   afzalligi   shundan   iboratki,   ro’yhatga   elementni   qo’shish   yoki
o’chirish   tez   amalga   oshadi,   bunda   qo’shish   yoki   o’chirish   element   soniga   bog’liq
bo’lmaydi,   massivda   esa   elementni   qo’shish   yoki   o’chirish   o’rta   hisobda   barcha
elementlarning   yarmini   siljitishni   talab   qiladi.   Ro’yhatda   qidiruvning   samaradorligi
taxminan   massivniki   bilan   bir   xil   bo’ladi.   Teng   bo’lish   orqali   qidiruv   (ikkilik   qidiruv)
algoritmi 
Faraz   qilaylik,   o’sish   tartibida   tartiblangan   sonlar   massivi   berilgan   bo’lsin.   Ushbu
usulning asosiy g’oyasi shundan iboratki, tasodifiy qandaydir AM element olinadi va u X
qidiruv argumenti bilan taqqoslanadi. Agar AM=X bo’lsa, u holda qidiruv yakunlanadi;
agar   AM   X   bo’lsa,   u   holda   indekslari   M   dan   katta   bo’lgan   barcha   elementlar   kelgusi
qidiruvdan chiqarib yuboriladi. M ixtiyoriy tanlanganda ham taklif qilinayotgan algoritm
korrekt ishlaydi. Shu sababali M ni shunday tanlash lozimki, tadqiq qilinayotgan algoritm
samaraliroq natija bersin, ya’ni uni shunday tanlaylikki, iloji boricha kelgusi jarayonlarda
ishtirok  etuvchi elementlar  soni kam bo’lsin. Agar biz o’rtacha elementni, ya’ni  massiv
o’rtasini tanlasak yechim mukammal bo’ladi. 
Misol   uchun   butun   sonlardan   iborat,   o’sish   bo’yicha   tartiblangan   massivdan   ikkilik
qidiruv   usuli   yordamida   key   kalitga   mos   elementni   izlash   dasturini   ko’rib   chiqamiz.
Dastur kodi:
#include<iostream>
#include<string.h>
using namespace std; 
int main()
{ int n;cout<<"n=";cin>>n; 
int k[n]; for(int i=0;i>k[i]; 
int   key,   search;   cout<<"qidirilayotgan   elementni
kiriting=";cin>>key; 
int low = 0; int hi = n-1; int j=0; 
while (low <= hi)
{ int mid = (low + hi) / 2;j++;  if (key == k[mid]){ search = mid; 
cout<<"qidirilayotgan   element   "<<search+1<<"   o’rinda
turibdi va u "<<j<<" ta solishtirishda toplidi\n"; 
system("pause"); exit(0); } 
if (key < k[mid]) hi = mid - 1; else low = mid + 1; } 
search=-1; 
cout<<j<<"   ta   solishtirish   amalga   oshirildi   va
qidirilayotgan element topilmadi\n"; 
system("pause"); }  
Dastur natijasi  n=6 1 2 3 4 5 6
qidirilayotgan   elementni   kiriting=6   qidirilayotgan   element   6   o'rinda   turibdi   va   u   3   ta
solishtirishda toplidi
  Qidiruv jadvalini qayta tartibga keltirish  
Umuman olganda, jadvalda har bir elementni qidirish ehtimolligini qandaydir bir qiymat
bilan izohlash mumkin. Faraz qilaylik jadvalda qidirilayotgan element mavjud. U holda
qidiruv amalga oshirilayotgan jadvalni diskret holatga ega tizim sifatida qarash mumkin
hamda unda qidirilayotgan elementni topish ehtimolligi – bu tizim i-chi holati ehtimolligi
p(i) deb olish mumkin.
Jadvalni diskret tizim sifatida qaraganimizda, undagi taqqoslashlar soni diskret tasodifiy
miqdorlar qiymatlarini matematik kutilmasini ifodalaydi.
Ma’lumotlar jadvalda quyidagi ko’rinishda tartiblangan bo’lishi lozim:
Bu   shart   taqqoslashlar   sonini   kamaytirib,   samaradorlikni   oshiradi.   Sababi,   ketma-ket
qidiruv   birinchi   elementdan   boshlanganligi   uchun   eng   ko’p   murojaat   qilinadigan
elementni   birinchiga   qo’yish   lozim.   Qidiruv   jadvalini   qayta   tartibga   keltirishning   eng ko’p   ishlatiladigan   ikkita   usuli   mavjud.   Ularni   bir   bog’lamli   ro’yhatlar   misolida   ko’rib
chiqamiz. 
1. Topilgan elementni ro’yhat boshiga qo’yish orqali qayta tartibga keltirish. 
2. Transpozitsiya usuli.  Topilgan elementni ro’yhat boshiga qo’yish orqali qayta tartibga
keltirish
Topilgan element 2.2-rasmdagidek birdaniga ro’yhat boshiga joylashtiriladi. Tuzilmadan
har   safar   birorta   element   izlab   topilsa   va   u   ro’yhat   boshiga   olib   borib   qo’yilaversa,
natijada   oxirgi   izlangan   elementlar   ro’yhat   boshiga   joylashib   qoladi   va   biz   oxirgi
vaqtlarda   izlangan   elementlarni   tez   izlab   topish   imkoniga   ega   bo’lamiz.   Boshida   q
ko’rsatkich bo’sh, p esa ro’yhat boshini ko’rsatadi; p ikkinchi elementni ko’rsatganda, q
birinchini   ko’rsatadi.   Ro’yhat   boshi   ko’rsatkichi   (table)   birinchi   elementni   ko’rsatadi.
Ro’yhatda key kalitli element topilsa, u p ko’rsatkich bilan, undan oldingi element esa q
ko’rsatkich bilan belgilanadi. 
Shu topilgan p elementni ro’yhat boshiga joylashtiriladi. 
Dastur kodi
  node *q=NULL; 
node *p=table; 
while (p !=NULL){ if (key == p->k){ if (q == NULL) 
{ //o‘rinlashtirish shart emas search = p; exit(0); } 
q->nxt = p->nxt; p->nxt = table; table = p; 
exit(0); } q = p; p = p->nxt; } 
search = NULL; exit(0);
                          Transpozitsiya usuli  Ushbu usulda topilgan element ro’yhatda bitta oldingi element bilan o’rin almashtiriladi.
Agarda   mazkur   elementga  ko’p  murojaat  qilinsa,   bittadan  oldinga  surilib   borib   natijada
ro’yhat boshiga kelib qoladi.
  Ushbu   usulning   afzalligi   shundaki,   tuzilmada   ko’p   murojaat   qilinadigan   elementlar
ro’yhat boshiga bitta qadam bilan intiladi. Ushbu usulning qulayligi u nafaqat ro’yhatda,
balki tartiblanmagan massivda ham samarali ishlaydi (sababi faqatgina ikkita yonma-yon
turgan element o’rin almashtiriladi). Bu usulda uchta ko’rsatkichdan foydalanamiz (2.3-
rasm): p – ishchi ko’rsatkich q – yordamchi ko’rsatkich, p dan bitta qadam orqada bo’ladi
s – yordamchi ko’rsatkich, p dan ikkita qadam orqada bo’ladi.
2.3-rasm. Transpozitsiya usuli bilan ro’yhatni qayta tartibga keltirish Biz tomonimizdan
topilgan   uchinchi   element   ro’yhat   boshiga   bir   qadam   suriladi   (ya’ni   ikkinchi   bo’lib
qoladi).   Birinchi   element   ko’rsatkichi   uchinchi   elementga   joylashtiriladi,   ikkinchi
element ko’rsatkichi to’rtinchi, shunday qilib uchinchi element ikkinchi joyga joylashib
qoladi. Agar mazkur elementga yana bir bor murojaat qilinsa, u holda u ro’yhat boshida
bo’lib qoladi.
node *s=NULL;
 node *q=NULL;
 node *p=table; while (p != NULL)
{ if (key == p->k){ //transponerlaymiz if( q ==NULL)
{//o‘rinlashtirish shart emas search=p; 
exit(0); } q->nxt=p->nxt; p->nxt=q; 
if (s == NULL) table = p; else s->nxt = p; search=p; 
exit(0); } s=q; q=p; p=p->nxt; } search=NULL; exit(0);
Ishni bajarishga oid namuna Talabalar ma’lumotlaridan – FIO va adresdan iborat jadval
berilgan.   Binar   qidiruvdan   foydalanib   TTJ   da   yashaydigan   talabalar   ro’yhatini   hosil
qiling.  Algoritm 
1. Jadvalga n ta talaba FIO va adreslarini kiritamiz. 
2.   Binar   qidiruvni   jadvalning   birorta   maydonida   amalga   oshirish   uchun   jadvalni   shu
maydoni   bo’yicha   tartiblab   olish   kerak.   Shuning   uchun   masalaning   qo’yilishida   adresi
TTJ   bo’lgan   talabalarni   topish   kerakligi   sababli   jadval   ma’lumotlarini   adres   maydoni
bo’yicha saralab olamiz. Masalani yechishda to’g’ridan-to’g’ri tanlash orqali saralashdan
foydalanilgan. 
3. key kalitga mos elementni izlash chegaralarini aniqlab olamiz. 
Dastlab u [0,n] oralig’ida, ya’ni low=0,hi=n.
 4. Agar low<=hi bo’lsa, oraliq o’rtasini hisoblaymiz. mid=(low+hi)/2
5.   Agar  mid   o’rnida   turgan  talaba   adresi  TTJ  bo’lsa,   element   topildi,  search=mid   va  7-
qadamga o’tiladi, aks holda keyingi qadamga o’tiladi. 
6.  Agar  “TTJ” so’zi alifbo  bo’yicha mid  o’rnida  turgan talaba  adresi  qiymatidan  kichik
bo’lsa, izlash quyi chegarasi o’zgaradi, ya’ni mid o’rnida turgan elementdan bitta oldingi
elementgacha   olinadi,   ya’ni   hi=mid-1.   Aks   holda,   yuqori   chegara   o’zgaradi   –   mid   dan
keyingi   elementdan   to   oxirgi   elementlar   oralig’i   olinadi,   ya’ni   low=mid+1.   4-qadamga
o’tiladi. 
7. Agar topilgan elementdan oldin turgan elementning (mid-1) ham adres maydoni TTJ
bo’lsa,   search--,   ya’ni   bitta   oldingi   elementga   o’tamiz   va   shu   qadamni   boshidan
bajaramiz. Aks holda keyingi qadamga o’tiladi. 
8. Joriy (search ko’rsatayotgan) elementdan boshlab adresi “TTJ” ga teng bo’lgan talaba
ma’lumotlarini   ekranga  chiqaramiz.   Agar   adresi   “TTJ”   dan  farq   qiladigan   talaba   chiqib
qolsa, algoritm tugallanadi.
Dastur kodi
 #include<ostream>
using namespace std; 
int main()
{ int n;cout<<"n=";
cin>>n; struct Guruh{ string fio,adres; }
talaba[n]; for(int i=0;i<<i+1<<"-talabaning fio=";
cin>>talaba[i].fio;  cout<<"adres=";
cin>>talaba[i].adres; }
//jadval   binar   qidiruv   olib   boriladigan   maydoni   bo‘yicha
tartiblangan //bo‘lishi kerak 
for(int i=0;italaba[j].adres)
{ Guruh h=talaba[i];
 talaba[i]=talaba[j];
 talaba[j]=h; } 
for(int i=0;i<<talaba[i].fio<<" "<<talaba[i].adres<<<=hi)
{ int mid = (low + hi) / 2; 
q++; if (key == talaba[mid].adres)
{ search = mid; break; }
 if (key < talaba[mid].adres)
 hi = mid - 1; else low = mid + 1; }
 if(search!=-1) 
cout<<"qidirilayotgan   el   "<<search+1<<"   –   o‘rinda   turibdi
va   "<<q<<"   ta   solishtirishda   topildi"<<”<<q<<"   ta
solishtirish amalga oshirildi va topilmadi"<<endl;
system("PAUSE"); 
return EXIT_SUCCESS; } 
while(talaba[search-1].adres==key)   search--;
while(talaba[search].adres==key) 
{   cout<<talaba[search].fio<<"
"<<talaba[search].adres<<endl;
Search++;
}
System(“pause”) }
Dastur natijasi :
 n=5 
1-talabaning fio=fam1 
adres=Toshkent 
2-talabaning fio=fam2 
adres=TTJ
 3-talabaning fio=fam3 adres=ijarada 
4-talabaning fio=fam4 adres=uchastkada
 5-talabaning fio=fam5 
adres=TTJ fam2 
TTJ fam5 TTJ
 fam1 Toshkent 
fam3 ijarada
 fam4 uchastkada qidirilayotgan el 1-orinda turubdi va 2 ta solishtirishda topildi 
fam2 TTJ
 fam5 TTJ