Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...
Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ - конструкции, предназначенные для поддерживания проводов на необходимой высоте над землей, водой...
Топ:
Эволюция кровеносной системы позвоночных животных: Биологическая эволюция – необратимый процесс исторического развития живой природы...
Генеалогическое древо Султанов Османской империи: Османские правители, вначале, будучи еще бейлербеями Анатолии, женились на дочерях византийских императоров...
Когда производится ограждение поезда, остановившегося на перегоне: Во всех случаях немедленно должно быть ограждено место препятствия для движения поездов на смежном пути двухпутного...
Интересное:
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Аура как энергетическое поле: многослойную ауру человека можно представить себе подобным...
Национальное богатство страны и его составляющие: для оценки элементов национального богатства используются...
Дисциплины:
2021-03-17 | 87 |
5.00
из
|
Заказать работу |
|
|
Введение
Временная и емкостная сложность
Списки
Линейные списки, стеки и очереди
Сплошное и связное представления
|
struct List{
int data;
List *next;
};
q->next=p->next;
p->next=q;
q->next=p->next;
p->next=q;
q->data<->p->data
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 Объединение
Поиск подходящего блока:
Кольцевой список для исключения скопления мелких блоков в начале списка
Проверка целостности списка.
Контроль повторного освобождения блока.
Структуры со списками
Записная книжка
Представление матриц
Рис. 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;Деревья
Определения
Бинарные деревья
Обходы
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);
}
}
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;
}
}
}
}
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;
|
|
Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...
Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...
Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!