Линейные списки, стеки и очереди — КиберПедия 

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

Линейные списки, стеки и очереди

2021-03-17 85
Линейные списки, стеки и очереди 0.00 из 5.00 0 оценок
Заказать работу

Введение

Временная и емкостная сложность

 

 

Списки

Линейные списки, стеки и очереди

Сплошное и связное представления

 

       

 

       

 

 

 

               

 

struct List{

int data;

List *next;

};

 

 

  • Добавить q после p

q->next=p->next;

p->next=q;

 

  • Добавить q перед p

q->next=p->next;

p->next=q;

q->data<->p->data

 

  • Удалить после p

q=p->next;

p->next=q->next;

free(q);

 

  • Стеки

  • Очереди

 

  • Двусвязные и кольцевые списки

  • Списки на массивах

A c b

0 a -1
1    
2    
0 a 1
1 c -1
2    
0 a 2
1 c -1
2 b 1

Добавление с поиском

 

struct List{

       int data;

       List *next;

};

List* Add(List* p, int x)

{

       List *q=p;

       while (q!=NULL)

       {

                   if (q->data==x)

                              break;

                   else

                              q=q->next;

       }

       if (q==NULL)

              q=(List*)malloc(sizeof(List));

                   q->data=x;

                   q->next=p;

                   p=q;

       }

       return p;

}

Сортировка вставками

 

Самоорганизующийся список (программа с фиктивным элементом)

 

 

struct List{

       int key;

       List * next;

};

 

List* CreateList(void)

{

       int i;

       List *p=NULL, *q;

 

       for (i=10; i>0; i--)

       {

                   q=(List*)malloc(sizeof(List));

                   q->key=i;

                   q->next=p;

                   p=q;

       }

       q=(List*)malloc(sizeof(List));

       q->next=p;

       return q;

}

 

void PrintList(List *s)

{

       s=s->next;

       while (s!=NULL)

       {

             printf("%d ", s->key);

                   s=s->next;

       }

printf("\n");

}

 

List* Search(List *s, int key)

{

       List *p1, *p2;

           

       p2=s;

       p1=s->next;

       while (p1!=NULL)

       {

                   if (p1->key==key)

                              break;

                   p2=p1;

                   p1=p1->next;

       }

       if (p1!=NULL)

       {

                   p2->next=p1->next;

                   p1->next=s->next;

                   s->next=p1;

       }

       return p1;

}

 

int main(void)

{

       List *s=CreateList(), *q;

       PrintList(s);

       q=Search(s,5);

       if (q==NULL)

                   printf("Element is absent\n");

       else

                   printf("%d\n", q->key);

       PrintList(s);

       getch();

       return 0;

}

Подсчет числа вхождений слов в файле (программа с барьером)

Поиск 5

5 c л о в о        

 

с л о в о 0

 

struct List{

       char *word;

       int count;

       List *next;

};

static List* Last;

 

List* InitList(void)

{

       List *s;

 

       Last=s=(List*)malloc(sizeof(List));

       s->next=NULL;

       return s;

}

 

List* Add2List(List* s, char* word)

{

       List *q=s;

 

       Last->word=word;

       while (strcmp(q->word,word))

                   q=q->next;

       if (q!=Last)

                   q->count++;

       else

       {

                   q=(List*)malloc(sizeof(List));

                   q->word=word;

                   q->count=1;

                   q->next=s;

                   s=q;

       }

       return s;

}

 

void PrintList(List *s)

{

       while (s!=Last)

       {

                   printf("%s %d\n", s->word, s->count);

                   s=s->next;

       }

}

 

int main(void)

{

       List *s=NULL;

       FILE *f;

       char buf[80];

       char *word;

 

       if((f = fopen("wordlist.txt", "r")) == NULL)

                   printf("The file 'WordList' was not opened\n");

       s=InitList();

          fscanf(f, "%s", buf);

       while (!feof(f))

       {

                   word = (char *)malloc(strlen(buf)+1);

                   strcpy(word, buf);

                   s=Add2List(s, word);

       fscanf(f, "%s", buf);

       }

 

       PrintList(s);

       getch();

       return 0;

}

Сложение двух полиномов

 

2x85 + 5x3 + 1

 

3x4 + x3

 

 

struct List{

int coef;

int pow;

List *next;

};

 

struct Queue{

List *first, *last;

};

 

void InitQueue(Queue *q)

{

q->first=q->last=(List*)malloc(sizeof(List));

}

 

void Add2Queue(Queue *q, int coef, int pow)

{

List *p;

 

p=(List*)malloc(sizeof(List));

p->coef=coef;

p->pow=pow;

p->next=NULL;

q->last->next=p;

q->last=p;

}

 

void ReadPol(FILE *f, Queue *q)

{

char buf[6];

int coef, pow;

 

do {

fscanf(f,"%s", buf);

       coef=atoi(buf);

fscanf(f,"%s", buf);

       pow=atoi(buf);

       Add2Queue(q, coef, pow);

} while(!feof(f));

}

void PrintPol(Queue *q)

{

List *p=q->first;

while (p!=q->last)

{

       p=p->next;

       printf("%d %d ", p->coef, p->pow);

}

printf("\n");

}

 

void SupPol(Queue *q1, Queue *q2, Queue *q3)

{

List *p1=q1->first->next, *p2=q2->first->next;

int s;

 

while (p1!=NULL && p2!=NULL)

{

       if (p1->pow > p2->pow)

       {

             Add2Queue(q3, p1->coef, p1->pow);

             p1=p1->next;

       }

       else

       {

             if (p1->pow < p2->pow)

             {

                   Add2Queue(q3, p2->coef, p2->pow);

                   p2=p2->next;

             }

             else

             {

                   s=p1->coef+p2->coef;

                   if (s!=0)

                   {

                        Add2Queue(q3, s, p1->pow);

                        p1=p1->next;

                        p2=p2->next;

                   }

             }

}

}

while (p1!=NULL)

{

       Add2Queue(q3, p1->coef, p1->pow);

       p1=p1->next;

}

 

while (p2!=NULL)

{

       Add2Queue(q3, p2->coef, p2->pow);

       p2=p2->next;

}

}

 

int main(void)

{

FILE *f;

Queue q1, q2, q3;

 

if((f = fopen("pol1.txt", "r")) == NULL)

       printf("The file 'pol1' was not opened\n");

InitQueue(&q1);

ReadPol(f,&q1);

fclose(f);

PrintPol(&q1);

 

if((f = fopen("pol2.txt", "r")) == NULL)

       printf("The file 'pol2' was not opened\n");

InitQueue(&q2);

ReadPol(f,&q2);

fclose(f);

PrintPol(&q2);

 

InitQueue(&q3);

SupPol(&q1, &q2, &q3);

PrintPol(&q3);

 

getch();

return 0;

}

 

Блоки одинакового размера

Рис. 1.1

Рис. 1.2

Блоки произвольного размера

Рис. 1.3

      

Рис. 1.4 Фрагментация

 

Рис. 1.5 Объединение

 

Поиск подходящего блока:

    • Первый подходящий (first fit)
    • Ближайший по размеру (best fit)

Кольцевой список для исключения скопления мелких блоков в начале списка

Проверка целостности списка.

Контроль повторного освобождения блока.

 

Структуры со списками

Записная книжка

Представление матриц

 

 

Рис. 1.6 Координатный формат хранения

 

Рис. 1.7 CSR (Compressed Sparse Rows) или CRS (Compressed Row Storage)

 

y = A x

 

Массив списков

Топологическая сортировка

 

a<b, a<d, b<d, d<e, c<e

 

Рис. 1.8

Рекурсия

Порядок обработки данных

void Print1(int n)

{

       if (n>0)

       {

                   printf("%d",n);

                   Print1(n-1);

       }

}

Print1(3)

 

void Print2(int n)

{

       if (n>0)

       {

                   Print2(n-1);

                   printf("%d",n);

       }

}

 

Print2(3)

 

Рис. 2.1

 

Порядок обработки данных

void Print1(int n)

{

       if (n>0)

       {

                   printf("%d",n);

                   Print1(n-1);

                   Print1(n-1);

       }

}

Print1(3)

Рис. 2.2

 

 

Print1(0)=;

Print1(1)=1;

Print1(2)=211;

Print1(3)=3211211;

 

void Print2(int n)

{

       if (n>0)

       {

                   Print2(n-1);

                   printf("%d",n);

                   Print2(n-1);

       }

}

void Print3(int n)

{

       if (n>0)

       {

                   Print3(n-1);

                   Print3(n-1);

                   printf("%d",n);

       }

}

2.2.2 Задача о “ханойской башне”

 

 

 

 


void Hanoy(int n, char x, char y, char z)

{

       if (n>0)

       {

                   Hanoy(n-1,x,z,y);

                   printf("%c to %c ",x,y);

                   Hanoy(n-1,z,y,x);

       }

}

void main(void)

{

Hanoy(3,'x','y','z');

getch();

}

       Сложность:

           

           

T(n)=2(2T(n-2)+1)+1=22T(n-2)+2+1=…2nT(n-n)+2n-1+…+2+1     

T(n)=2n+2n-1+…+2+1=2n+1+1=O(2n)

 

 

Синтаксический анализ

Expression::=letter | (Expression Sign Expression)

 

a a+b (a+b) ((a+b)*(c-d))

 

char ch;

void Expression(FILE *f)

{

if (ch>='a' && ch<='z')

ch=fgetc(f);

else

{

if (ch=='(')

{

ch=fgetc(f);

Expression(f);

if (ch == '+' || ch == '-' || ch == '*' || ch == '/')

{

       ch=fgetc(f);

       Expression(f);

       if (ch==')')

       ch=fgetc(f);

       else

       exit(1);

}

else

       exit(1);

}

else

exit(1);

}

}

int main()

{

FILE *f;

 

if ((f = fopen("Expres.txt", "rt")) == NULL)

{

printf("Cannot open Expres.txt\n");

return 1;

}

ch=fgetc(f);

Expression(f);

printf("OK\n");

fclose(f);

return 0;

}

Сортировка слияниями

void sort(int i, int j)

{

       int k;

       if (i<j)

       {

                   k=(i+j)>>1;

                   sort(i,k);

                   sort(k+1,j);

                   merging(i,k,j);

       }

}

 

Рис. 2.3

merging(n)=O(n)

 

T(n)=2(2T(n/4)+n/2)+n=22T(n/22)+2n=…2kT(n/2k)+kn       

n=2k

T(n) =n+kn=n+log(n)n =O(nlog(n)) 

 

Числа Фибоначчи

 

int fib(int n)

{

       if (n==0)

                   return 0;

       else

       {

                   if (n==1)

                              return 1;

                   else

                              return fib(n-1)+fib(n-2);

       }

}

T(n)=O(2n)

 

x=0;

       y=1;

       for (int i=0; i<n; i++)

       {

                   z=y+x;

                   x=y;

       }

T(n)=O(n)

 

 

int fib(int n)

{

       if (F[n]>=0)

                   return F[n];

       else

                   return F[n]=fib(n-1)+fib(n-2);

}

 

     

Косвенная рекурсия

Кривые Гильберта

An+1: D n<-A n | A n ->B n   

B n+1: C n | B n ->B n | A n

C n+1: B n ->C n | C n <-D n

D n+1: A n | D n <-D n | C n

 

 

void A(int n)

{

       if (n>0)

       {

                   D(n-1); line(...);

                   A(n-1); line(...);

                   A(n-1); line(...);

                   B(n-1);

       }

}

void B(int n)

{

       if (n>0)

       {

                   C(n-1); line(...);

                   B(n-1); line(...);

                   B(n-1); line(...);

                   A(n-1);

       }

}

void C(int n)

{

       if (n>0)

       {

                   B(n-1); line(...);

                   C(n-1); line(...);

                   C(n-1); line(...);

                   D(n-1);

       }

}

void D(int n)

{

       if (n>0)

       {

                   A(n-1); line(...);

                   D(n-1); line(...);

                   Dn-1); line(...);

                   C(n-1);

       }

}

Рекурсия в цикле

Перебор

a a a

a a b

a a c

a b a

 

char a[n];

       for (int i0=0; i0<n; i0++)

       {

                   a[0]=буква(i0);

                   for (int i1=0; i1<n; i1++)

                   {

                              a[1]=буква(i1);

                              for (int i2=0; i2<n; i2++)

                                          a[2]=буква(i2);

                             ......     

                                          for (int in-1=0; in-1<n; in-1++)

                                          {

                                                      a[in-1]=буква(in-1);

                                                      Print (a);

                                          }

                             ......

                   }

       }

0 …. k    
         

 

void per(int k)

{

 a[k]='a';

        while (a[k]<'c')

{

                   if (k==n-1) printA(a);

else per(k+1);

a[k]++;

}

}

void main()

{

per(0);

}

 

Перестановки

 

1. <1, 2, 3, 4>   7. <2, 1, 3, 4>   13. <3, 1, 2, 4>   19. <4, 1, 2, 3>

2. <1, 2, 4, 3>    8. <2, 1, 4, 3>  14. <3, 1, 4, 2>   20. <4, 1, 3, 2>

3. <1, 3, 2, 4>    9. <2, 3, 1, 4>   15. <3, 2, 1, 4>   21. <4, 2, 1, 3>

4. <1, 3, 4, 2>  10. <2, 3, 4, 1>   16. <3, 2, 4, 1>   22. <4, 2, 3, 1>

5. <1, 4, 2, 3>  11. <2, 4, 1, 3>   17. <3, 4, 1, 2>   23. <4, 3, 1, 2>

6. <1, 4, 3, 2>  12. <2, 4, 3, 1>   18. <3, 4, 2, 1>   24. <4, 3, 2, 1>

 

<15, 2, 4, 3, 1, 13, 7, 10, 14, 12, 11, 9, 8, 6, 5>,

<15, 2, 4, 3, 1, 13, 7, 11, 5, 6, 8, 9, 10, 12, 14>.

 

void Lec(int k)

{

int i;

if (k==n-1)

print p;

else

for (i=n-1; i>=k; i--)

{

       Lec(k+1);

       if (i>k)

       {

             p[i]<->p[k];

             Invert(k+1);

       }

}

}

void main()

{

for (int i=0; i<n; i++)p[i]=i;

Lec(0);

}

 

Синтаксический анализ

Expression::= Exp{знак Exp }

Exp::=x|(Expression)

x::=целое

знак::=+ | - | * | /

 

FILE *f;

char ch;

void Exp(void);

void Expression(void)

{

Exp();

while (ch == '+' || ch == '-' || ch == '*' || ch == '/')

{

ch=fgetc(f);

Exp();

}

}

void Exp(void)

{

if (ch>='a' && ch<='z')

ch=fgetc(f);

else

{

if (ch=='(')

{

ch=fgetc(f);

Expression();

if (ch==')')

       ch=fgetc(f);

else

       exit(1);

}

else

exit(1);

}

}

 

int main()

{

………………….

ch=fgetc(f);

Expression();

………………….

}

выражение::= слагаемое{знак1 слагаемое}

слагаемое::=множетель{знак2 множетель}

множетель::=x|(выражение)

x::=целое

знак1::=+ | -

знак2::=* | /

Сокращение перебора

N ферзей.

 

procedure полный_перебор(m: integer);

 var i: integer; begin if m > n  then    <проверка построенной позиции> else    for i:= 1  to n  do begin      ферзь[m]:= i;     полный_перебор(m+1);    end; end; Алгоритм с возвратом   procedure перебор_с_возвратом(m: integer); var i: integer; begin if m > n  then   <найдено решение> else    for i:= 1  to n  do begin       ферзь[m]:= i;       if <ферзь[m] не бьёт предыдущих>  then       перебор_с_возвратом(m+1);    end; end;

Использование симметрии

Раскраска карты

   procedure перебор_с_возвратом(m: integer);   var i: integer;  begin if m > n  then   <найдено решение>  else   for i:= 1  to k  do begin      цвет[m]:= i;     if <цвета стран 1,...,m-1 соседних с m -ой не i>  then       перебор_с_возвратом(m+1);     end;   end ; 1,2,3,3 = 3,2,1,1  procedure перебор_возвратом(m: integer);  var i: integer;  begin if m > n  then    <найдено решение>  else begin     for i:= 1  to кол_красок  do begin        цвет[m]:= i;       if <цвета стран 1,...,m-1 соседних с m -ой не i>  then            перебор_с_возвратом(m+1);    end;     if кол_красок < k  then begin        кол_красок:= кол_красок+1;       цвет[m]:= кол_красок;       перебор_с_возвратом(m+1);       кол_красок:= кол_красок-1;    end;  end;  end;

Распространение ограничений

 

Рис. 2.4

 procedure распространение_ограничений(m: integer);   var i: integer;  if m > n  then     <найдено решение>  else     for i:= 1  to n  do          if пространство[m,i] = 0  then begin              ферзь[m]:= i;             сократить_пространство_перебора(m,i);             распространение_ограничений(m+1);             восстановить_пространство_перебора(m,i);         end;  end;

Изменение порядка перебора

 

 

Рис. 2.5

 

Метод ветвей и границ

Укладка рюкзака. Из заданных n предметов выбрать такие, чтобы их суммарная стоимость была не менее чем S, а суммарный объём не превосходил V.

Неизвастна длина результата.

 procedure перебор_с_возвратом(m: integer);   var i: integer;  begin if m > n  then     <найдено решение>   else begin    x[m]:= 0;   потерянная_стоимость:= потерянная_стоимость+стоимость[m];   if полная_стоимость - потерянная_стоимость => S  then        перебор_с_возвратом(m+1);   потерянная_стоимость:= потерянная_стоимость-стоимость[m];   x[m]:= 1;   сумм_объём:= сумм_объём+объём[m];   if сумм_объём <= V  then        перебор_с_возвратом(m+1);   сумм_объём:= сумм_объём-объём[m];  end;  end;

Деревья

Определения

 

Бинарные деревья

Обходы

  1. Обходы в прямом, внутреннем и обратном порядке

void PrintTree(tree *t)

{

if (t!=NULL)

{

             printf("%c",t->ch);

             PrintTree(t->left);

             PrintTree(t->right);

}

}

void PrintTree(tree *t)

{

if (t!=NULL)

{

             PrintTree(t->left);

             printf("%c",t->ch);

             PrintTree(t->right);

}

}

void PrintTree(tree *t)

{

if (t!=NULL)

{

             PrintTree(t->left);

             PrintTree(t->right);

             printf("%c",t->ch);

}

}

  1. Раскрытие рекурсии

tree *st[10];

int s=0;

void PrintTree(tree *t)

{

s++; st[s]=t;

while (s)

{

             t=st[s]; s--;

             while (t!=NULL)

             {

                        printf("%c",t->ch);

                        s++; st[s]=t->right;

                        t=t->left;

             }

}

}

 

struct stackT{

int type;

tree *t;

};

stackT stk[20];

int s=0;

 

void PrintTree(tree *t)

{

int type;

 

s++; stk[s].type=1; stk[s].t=t;

while (s)

{

             t=stk[s].t; type=stk[s].type; s--;

             if (t!=NULL)

             {

                        if (type==0)

                                    printf("%c",t->ch);

                        else

                        {

                                    s++; stk[s].type=1; stk[s].t=t->right;

                                    s++; stk[s].type=0; stk[s].t=t;

                                    s++; stk[s].type=1; stk[s].t=t->left;

                        }

             }

}

}

  1. Обход в ширину

 

void PrintTree(tree *t)

{

S<-t;

while (S не пусто)

{

             t<-S;

             if (t!=NULL)

             {

                        printf("%c",t->ch);

                        S<- t->right;

                        S<- t->left;

             }

}

}

 

void PrintTree(tree *t)

{

Q<-t;

while (Q не пусто)

{

             t<-Q;

             if (t!=NULL)

             {

                        printf("%c",t->ch);

                        Q<- t->left;

                        Q<- t->right;

             }

}

}

 

Счетчики

a) Число узлов

int n=0;

void Count(tree *t)

{

if (t!=NULL)

{

       n++;

             Count(t->left);

             Count(t->right);

}

}

int Count(tree *t)

{

int r1, r2;

if (t==NULL) return 0;

else

{

             r1=Count(t->left); // t->nl = r1

             r2=Count(t->right); // t->nr = r1

             return (r1+r2+1);

}

}

 

b) Высота

int h=0;

int CountH(tree *t, int n)

{

if (t!=NULL)

{

             if (t->left==NULL && t->right==NULL)

             {

                        if (n>h) h=n;

             }

             CountH(t->left, n+1);

             CountH(t->right, n+1);

}

}

CountH(t, 0);

 

int CountH(tree *t)

{

int r1, r2, r;

if (t==NULL) return 0;

else

{

             if (t->left==NULL && t->right==NULL) return 0;

             else

             {

                        r1=CountH(t->left); // t->nl = r1

                        r2=CountH(t->right); // t->nr = r2

                        if (r1>r2) r=r1+1;

                        else r=r2+1;

                        return r;

             }

}

}

 

Представление в памяти

Tree:

Int key;

Tree* brother;

Tree* child;

 

Обходы

a) Дерево

Q – stack или очередь

 

Q<-t;

While (Q!=пусто)

{

t<-Q; обработать(t);

t=t->child;

while (t!=NULL)

{

Q<-t; t=t->brother;

}

}

 

b) Граф

Q – stack или очередь

for(всех u)

u->flag=0;

u->flag=1;

Q<-u;

While (Q!=пусто)

{

u<-Q;

обработать(u);

for (v связанных с u)

{

if (v->flag==0)

{

Q<-v;

v->flag=1;

                   }

}

}

 

 

Деревья двоичного поиска

struct tree{

       int key;

       tree * left;

tree * right;

};

 

tree* Add(tree *t, int x)

{

       if (t==NULL)

       {

                   t=(tree *)malloc(sizeof(tree));

                   t->key=x;

                   t->left=t->right=NULL;

       }

       else

       {

                   if (x<t->key)

                              t->left=Add(t->left,x); 

                   else

                   {

                              if (x>t->key)

                                          t->right=Add(t->right,x); 

                   }

       }

       return t;

}

 

 

tree* del1(tree* &q, tree *p)

{

       tree *r;

 

       if (q->right!=NULL)

       r=del1(q->right,p);

       else

       {

                   p->key=q->key;

                   r=q;

                   q=q->left;

       }

       return r;

}

 

tree* del(tree *t, int x)

{

tree *p;

 

if (t!=NULL)

{

       if (x<t->key)

        t->left=del(t->left,x);

       else

       {

       if (x>t->key)

                    t->right=del(t->right,x);

       else

       {

                    p=t;

                    if (p->right==NULL)

                   t=p->left;

                    else

                    {

                   if (p->left==NULL)

                               t=p->right;

                   else

                               p=del1(p->left,p);

                    }

 

                    free(p);

       }

       }

}

return t;

}

 

Пример: таблица перекрестных ссылок.

 

К-й наименьший

tree* k_min (tree* t, int k)

{

       int r;

           

       if (t->left)

       {

                   r=t->left->number + 1;

       }

       else

                   r=1;

       if (r!=k)

       {

                   if (k<r)

                              t=k_min(t->left,k);

                   else

                              t=k_min(t->right,k-r);

       }

       return t;

}

Порядковый номер

struct tree{

       int key;

       int number; //число узлов в поддереве

       tree* left;

tree* right;

tree* father;

};

 

int Number(tree *t)

{

       tree *f;

       int r = Size(t); //t->left->number + 1;

           

       while (t!=root)

       {

                   f=t->father;    

                   if (t==f->right)

                              r+=Size(f->left)+1;

                   t=t->father;

       }

       return r;

}         

Рис. 3.1

Пересекающиеся отрезки

struct tree{

       int l;

       int r;

int r_max;

       tree* left;

tree* right;

};

tree* Intersect(tree *t, int l, int r)

{

       tree *p;

       while (t!=NULL && (t->l > r || t->r < l))

       {

                   p=t->left;

                   if (p!=NULL && (p->r_max > l))

                              t=t->left;

                   else

                              t=t->right;

       }

       return t;

}         

 

BSP-tree

 

 

Oct-tree, quad-tree

 

 

Конвейер

Рис. 4.1

 

S1j-1, S2j-1  => Sij

Оптимальное решение задачи строится из оптимальных решений подзадач – оптимальная подструктура.

Разделяй и властвуй – независимые подзадачи. Оптимальная подструктура - зависимые

 

fi [j] минимальное время прохождения Sij.

 

T1[n] = T2[n] = T1[n-1] + T2[n-1] + 1=

= (T1[n-2] + T2[n-2] + 1)+ (T1[n-2] + T2[n-2] + 1) + 1= 2T1[n-2] + 2T2[n-2]+2+1=

= 2kT1[n-k] + 2kT2[n-k]+2k-1+…+1=O(2n)

 

Вычисление минимального времени

Вычисление минимального пути

 

Умножение матриц

A*B p*q q*r => p*q*r

A1A2A3  10*100, 100*5, 5*50

(A1A2)A3  - 7500

A1(A2A3)  - 75000

 

AiAi+1…Aj

Ai. … Ak Ak+1…Aj

Ai - pi-1pi

m[i,j] = m[i,k]+ m[k+1,j]+pi-1pkpj

 

m[i,j] = mink(m[i,k]+ m[k+1,j]+pi-1pkpj) i<j

(m[i,i]=0)

О(2n), O(n3)

 

Рис. 4.2

A1. … Ak и Ak+1…Aj не подходит

 

В строке 8 добавить s[i,j]=k

Тогда

A1. … Ak1 и Ak1+1…An  где k1=s[1,n]

A1. … Ak2 и Ak2+1…Ak1  где k2=s[1,k1]

 

Скобки(i,j)

{

 if (i==j) print “Aj”;

else

           {

           print “(“;

                   Скобки(i,s[i,j]);

                   Скобки(s[i,j]+1,j);

print “)“;

}

}

 

 

Рис. 4.3

 

m[i,j] = 0 i=j

m[i,j] = min i<=k<j {m[i,k] + m[k+1,j] + } i<j,

 

 

Рис. 4.4

Cбалансированные деревья

АВЛ дерево

Балансировка

 

Рис. 5.1

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

 

Рис. 5.2

 

 

Рис. 5.3

Рис. 5.4

 

 

 

Рис. 5.6

 

 

Добавление

struct_tree{

       int key;

       int bal;

       tree * left;

        tree * right;

};

 

void Add(tree* &t, int x, int flag)

{

       tree * t1;

 

       if (t==NULL)

       {

                   t=malloc(...);

...

                   t->bal=0;

                   flag=1;


Поделиться с друзьями:

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰)...

Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.884 с.