Stack +++
.pdf
11
Реализация стека списком
Структура узла:
struct STACK { int data, size;
STACK *next, *prev; // двусвязный список
};
В программе определяем указатель стека
STACK *stack=0;
// указатель на последний элемент стека stack.size=0;
12
Реализация стека списком
Добавление элемента:
STACK *Push (STACK *&stack, int x) { STACK *s; // s = new top node
s=(STACK*)malloc( sizeof(STACK) ); s->data = x;
s->next=0; s->prev=stack; s->size=stack->size + 1; if(stack) stack->next = s; stack=s;
return s;
}
13
Реализация стека списком
Снятие элемента с вершины:
int Pop (STACK *&stack, int &x)
{int size;
STACK *s=stack; // to remember for free x=stack->data;
stack->prev->next=0; stack=stack->prev; size= stack->size; free(s);
return size;
}
14
Реализация стека списком
в основной программе:
STACK *stack=0;
int k, n;
………………………………………………….
push(stack,3);
push(stack,5);
push(stack,7);
………………………………………………….
n=pop(stack, k); // k=7 n=2
15
Вычисление арифметических выражений
Инфиксная запись:
знак операции между операндами, скобки! (a + b) / (c + d – 1)
польская нотация, Lukasiewicz 1920 г скобки не нужны, можно однозначно вычислить!
Постфиксная запись знак операции после операндов
a b + c d + 1 - /
Префиксная запись знак операции до операндов
/ - + c d 1 + a b
Преобразование инфиксной формы записи в |
16 |
|
|
постфиксную |
|
|
|
знак |
приоритет |
приоритет |
|
|
операции |
в стеке |
в строке |
|
|
|
Q |
P |
|
|
|
|
|
|
|
( |
0 |
- |
или inf |
|
|
|
|
|
|
) |
- |
0 |
|
|
|
|
|
|
|
+ - |
1 |
1 |
|
|
* / |
2 |
2 |
|
|
^ |
3 |
3 |
|
a^b^c=a^(b^c) |
|
|
4 |
|
a^b^c=a^(bc) |
|
|
|
|
|
Алгоритм преобразования инфиксной |
17 |
|
|
формы записи в постфиксную |
|
1.Выбрать символ из входной инфиксной строки и удалить его из строки
2.Если выбранный символ – знак операнда (не знак операции), переместить его в выходную – постфиксную строку
Иначе – обработка знака операции:
3.Если стек пуст, то переместить выбранный знак операции в стек и перейти к № 1
Иначе - если стек не пуст
4.Если ( , то поместить в стек и перейти к № 1
Иначе – обработка других знаков операции
Алгоритм преобразования инфиксной |
18 |
|
|
формы записи в постфиксную |
|
5. Сравнить приоритеты знаков операций:
P – в строке и Q – в стеке (на его вершине) Если P > Q , то поместить знак операции в стек
Иначе – если P <= Q – удалить знак операции из стека и переместить его в выходную строку.
При этом обрабатываемый знак операции из входной
строки остаётся тем же. Перейти к №5
Особый случай: ( ) удалить обе скобки и перейти к №1
6. Если все символы входной строки исчерпаны, выбрать все символы из стека по одному и
переместить их в выходную строку
19
Infix To Post
int InfixToPost( char s[ ], char post[ ] )
{ int i, top, j; |
|
int P[256], Q[256]; |
// priority string & stack |
char q[100]; |
// operation stack |
// priority in string |
|
P[ '(‘ ] = 255; P[')']=0; P['+']=1; P['-']=1; P['*']=2; P['/']=2; P['^']=4;
// priority in stack
Q['(']=0; Q[')']=100; Q['+']=1; Q['-']=1; Q['*']=2; Q['/']=2; Q['^']=3;
top=0; // top q stack operation
j=0; |
// top p string postfix |
20
Infix To Post 2
for( i = 0; s[i]; i++)
{ if ( isalpha( s[i] ) ) { post[j] = s[i]; j++; } else if( s[i] == ‘ ’ ) continue; // blank ignore else
while( top >= 0)
{ if(k == 0) { q[k] = s[i]; top = 1; break; } if( Q [q [top-1]] < P[s[i]] )
{ q[top] = s[i]; top++; break; }
else |
// if(Q[q[top-1]]>=P[s[i]]) |
if ( q[top-1] == '(' && s[i] == ‘)‘ ) |
|
{top--; break; } |
// from for |
else { post[j]=q[top-1]; j++; top--; }
}// while(top>=0)
}// for i
