|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
ProblemNależy przedstawić symboliczne wyrażenie arytmetyczne jako drzewo wyrażeń. |
Drzewo wyrażeń (ang. expression tree) jest drzewem binarnym (ang. binary tree), które przedstawia sobą wyrażenie arytmetyczne. Liście drzewa reprezentują argumenty, a wewnętrzne węzły operacje arytmetyczne. Dla uproszczenia umówmy się, że argumenty będą symbolami jednoliterowymi: a, b, c. Operacje ograniczymy do: +, -, *, / oraz ^ (potęgowanie). W wyrażeniu będą mogły pojawiać się nawiasy ().
Poniżej podajemy przykłady kilku drzew wyrażeń arytmetycznych:
| a+b |
![]() |
|
| (a+b)*(c-d) |
![]() |
|
| a^(b+c*d) |
![]() |
Tworzenie drzewa wyrażeń wymaga przekształcenia wyrażenia na postać ONP, a następnie wykorzystania stosu oraz drzew binarnych. Zasada jest następująca:
Mamy dane symboliczne wyrażenie arytmetyczne:
( a * b / c ) ^ ( d - e )
Wyrażenie przekształcamy na postać ONP:
a b * c / d e - ^ =
Przygotowujemy pusty stos, na którym będziemy umieszczać wskazania węzłów drzewa. Wyrażenie ONP przeglądamy kolejno po jednym elemencie od strony lewej do prawej. Jeśli napotkamy argument, to tworzymy węzeł drzewa z tym argumentem i umieszczamy jego adres na stosie. Jeśli trafimy na operator, to tworzymy węzeł z tym operatorem, następnie ze stosu zdejmujemy dwa węzły i dołączamy je jako synów do węzła z operatorem, po czym adres tego węzła wędruje na stos. Gdy przeglądniemy całe wyrażenie ONP, na stosie będziemy mieli adres korzenia drzewa wyrażeń. Prześledźmy te działania na naszym przykładzie:
| Wyrażenie ONP | Opis | Stos |
|---|---|---|
a b * c / d e - ^
|
Elementem jest argument a. Tworzymy węzeł z tym argumentem i umieszczamy go stosie (uwaga: przez umieszczenie węzła na stosie rozumiemy umieszczenie na stosie jego wskazania). |
![]() |
a b * c / d e - ^
|
Kolejny element wyrażenia jest również argumentem. Tworzymy dla niego węzeł umieszczamy go na stosie. |
![]() |
a b * c / d e - ^
|
Teraz napotykamy na operator *. Tworzymy nowy węzeł dla operatora. Ze stosu pobieramy dwa węzły (tzn. adresy tych węzłów) i tworzymy z nich lewego i prawego syna węzła z operatorem, po czym węzeł ten umieszczamy na stosie. |
![]() |
a b * c / d e - ^
|
Argument c. Tworzymy dla niego węzeł i umieszczamy na stosie. |
![]() |
a b * c / d e - ^
|
Operator /. Tworzymy węzeł operatora. Ze stosu pobieramy dwa węzły (* oraz c) i dołączamy je do węzła operatora / jako lewy i prawy syn. Następnie węzeł operatora / umieszczamy na stosie. |
![]() |
a b * c / d e - ^
|
Argument d. Tworzymy dla niego węzeł i umieszczamy na stosie. |
![]() |
a b * c / d e - ^
|
Argument e. Tworzymy dla niego węzeł i umieszczamy na stosie. |
![]() |
a b * c / d e - ^
|
Operator -. Tworzymy węzeł dla operatora -. Ze stosu pobieramy węzły d i e i dołączamy je do węzła operatora jako lewy i prawy syn. Węzeł operatora umieszczamy na stosie. |
![]() |
a b * c / d e - ^
|
Operator ^. Tworzymy węzeł operatora, pobieramy ze stosu dwa węzły i dołączamy je jako lewy i prawy syn. Węzeł umieszczamy na stosie. |
![]() |
a b * c / d e - ^ |
Koniec wyrażenia. Na szczycie stosu mamy adres korzenia drzewa wyrażeń. |
K01: Jeśli koniec wyrażenia, ; sprawdzamy koniec wyrażenia to zakończ K02: Czytaj el ; czytamy element wyrażenia K03: Utwórz nowy węzeł K04: v ← adres nowego węzła K05: v→data ← el ; w węźle umieszczamy odczytany ; element wyrażenia K06: Jeśli el nie jest argumentem, to idź do kroku K10 K07: v→left ← nil ; dla argumentów zerujemy synów K08: v→right ← nil K09: Idź do kroku K14 K10: v→right ← S.top() ; dla operatorów pobieramy ; ze stosu dwa węzły K11: S.pop() K12: v→left ← S.top() K13: S.pop() K14: S.push(v) ; węzeł umieszczamy na stosie K15: Idź do kroku K01 ; wracamy na początek pętli
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
Do programu wprowadzamy symboliczne
wyrażenie arytmetyczne. W wyrażeniu można stosować:
Przykładowe wyrażenie: (a+b^(c-d))/e*f^g |
Pascal// Tworzenie drzewa wyrażeń
// Data: 11.05.2013
// (C)2013 mgr Jerzy Wałaszek
//---------------------------
program e_tree;
// Typ węzłów drzewa
//------------------
type
PBTnode = ^BTnode;
BTnode = record
left, right : PBTnode;
Data: char;
end;
// rozmiar dla stosów
const S_MAX = 100;
// Zmienne globalne
//-----------------
var
// łańcuchy do znaków ramek
cr, cl, cp : string;
// Zwraca priorytet operatora
// dla ONP
//---------------------------
function p(c : char) : integer;
begin
case c of
'(' : p := 0;
'+', '-' : p := 1;
'*', '/' : p := 2;
'^' : p := 3;
end;
end;
// Funkcja przekształca wyrażenie
// arytmetyczne e na ONP
//-------------------------------
function onp(e : string) : string;
var
// Stos operatorów
S : array [0..S_MAX-1] of char;
// Wskaźnik stosu
sp : integer;
// Wynik pośredni
t : string;
i : integer;
begin
// Inicjujemy stos
sp := 0;
// Zerujemy wynik
t := '';
for i := 1 to length(e) do
// Analizujemy znak wyrażenia
case e[i] of
// Spację ignorujemy
' ' : ;
// Nawias otwierający zawsze
// na stos
'(' : begin
S[sp] := '(';
inc(sp);
end;
// Nawias zamykający
')' : begin
while S[sp-1] <> '(' do
begin
// Ze stosu przesyłamy
// na wyjście
dec(sp);
// wszystkie operatory
// aż do nawiasu (
t := t+S[sp];
// Echo na ekran
write(S[sp], ' ');
end;
// Usuwamy ze stosu
// nawias otwierający
dec(sp);
end;
// Operator
'+', '-', '*', '/', '^' :
begin
while sp > 0 do
begin
if(p(e[i]) = 3) or
(p(e[i]) > p(S[sp-1])) then
break;
// Na wyjście przesyłamy
// ze stosu wszystkie
dec(sp);
// operatory o wyższych
// priorytetach
t := t+S[sp];
// Echo na ekran
write(S[sp], ' ');
end;
// Operator umieszczamy
// na stosie
S[sp] := e[i];
inc(sp);
end;
else
begin
// Inaczej znak przesyłamy
// na wyjście
t := t+e[i];
// Echo na ekran
write(e[i], ' ');
end;
end;
// Jeśli stos coś zawiera,
while sp > 0 do
begin
// to na wyjście przesyłamy
dec(sp);
// całą zawartość stosu
t := t+S[sp];
// Echo na ekran
write(S[sp], ' ');
end;
writeln; writeln;
ONP := t;
end;
// Funkcja zwraca adres korzenia
// drzewa wyrażeń, które zostaje
// utworzone na podstawie
// wyrażenia e
//------------------------------
function etree(e : string) : PBTnode;
var
// Stos
S : array [0..S_MAX-1] of PBTnode;
// Wskaźnik stosu
sp : integer;
// Adres węzła
v : PBTnode;
// Indeks
i : integer;
begin
// Zerujemy stos
sp := 0;
// Przetwarzamy wyrażenie ONP
for i := 1 to length(e) do
begin
// Tworzymy nowy węzeł
new(v);
// Umieszczamy w nim
// element wyrażenia
v^.Data:= e[i];
if e[i] in ['+', '-', '*', '/', '^'] then
// Operator
begin
// Pobieramy ze stosu węzły
// i czynimy je synami węzła
v^.right := S[sp-1];
v^.left := S[sp-2];
dec(sp, 2);
end
else
// Argument
begin
// Liść, nie ma synów
v^.left := nil;
v^.right := nil;
end;
// Węzeł umieszczamy na stosie
S[sp] := v;
inc(sp);
end;
// Zwracamy adres korzenia
etree := S[sp-1];
end;
// Procedura DFS:postorder
// usuwająca drzewo
//------------------------
procedure dfs_release(v : PBTnode);
begin
if v <> nil then
begin
// usuwamy lewe poddrzewo
dfs_release(v^.left);
// usuwamy prawe poddrzewo
dfs_release(v^.right);
// usuwamy sam węzeł
dispose(v);
end;
end;
// Procedura wypisuje drzewo
//--------------------------
procedure print_bt(sp, sn : string;
v : PBTnode);
var
s : string;
i : integer;
begin
if v <> nil then
begin
s := sp;
if sn = cr then
s[length(s)-1] := ' ';
print_bt(s+cp, cr, v^.right);
s := Copy(sp, 1, length(sp)-2);
for i := 1 to length(s) do
write(char(ord(s[i])));
for i := 1 to length(sn) do
write(char(ord(sn[i])));
writeln(v^.data);
s := sp;
if sn = cl then
s[length(s)-1] := ' ';
print_bt(s+cp, cl, v^.left);
end;
end;
//**********************
//*** PROGRAM GŁÓWNY ***
//**********************
var
// Wyrażenie
e : string;
// Korzeń drzewa
root : PBTnode;
begin
// Ustawiamy łańcuchy znakowe,
// ponieważ nie wszystkie
// edytory pozwalają wstawiać
// znaki konsoli do tworzenia
// ramek
// cr = +--
// |
// cl = |
// +--
// cp = |
// |
cr := #218#196;
cl := #192#196;
cp := #179#32;
// Czytamy wyrażenie
readln(e);
writeln;
// Tworzymy drzewo wyrażeń
root := etree(onp(e));
// Wyświetlamy drzewo
print_bt('', '', root);
// Usuwamy drzewo z pamięci
dfs_release(root);
end.
|
// Tworzenie drzewa wyrażeń
// Data: 11.05.2013
// (C)2013 mgr Jerzy Wałaszek
//---------------------------
#include <iostream>
#include <string>
using namespace std;
// Typ węzłów drzewa
//------------------
struct BTnode
{
BTnode *left, *right;
char data;
};
// rozmiar dla stosów
const int S_MAX = 100;
// Zmienne globalne
//-----------------
// łańcuchy do znaków ramek
string cr, cl, cp;
// Zwraca priorytet operatora
//---------------------------
int p (char c)
{
switch (c)
{
case '+' :
case '-' : return 1;
case '*' :
case '/' : return 2;
case '^' : return 3;
}
return 0;
}
// Funkcja przekształca wyrażenie
// arytmetyczne e na ONP
//-------------------------------
string ONP (string e)
{
// Stos operatorów
char S[S_MAX];
// Wskaźnik stosu
int sp;
// Wynik
string t;
unsigned int i;
// Inicjujemy stos
sp = 0;
// Zerujemy wynik
t = "";
for(i = 0; i < e.length(); i++)
// Analizujemy znak wyrażenia
switch(e[i])
{
// Spację ignorujemy
case ' ' : break;
// Nawias otwierający zawsze
// na stos
case '(' : {
S[sp++] = '(';
break;
}
// Nawias zamykający
case ')' : {
// Ze stosu przesyłamy
// na wyjście
while(S[sp-1] != '(')
{
t += S[--sp];
// wszystkie operatory
// aż do nawiasu (
// Echo na ekran
cout << S[sp] << " ";
}
// Usuwamy ze stosu
// nawias otwierający
sp--;
break;
}
// Operator
case '+' :
case '-' :
case '*' :
case '/' :
case '^' : {
while(sp)
{
if((p(e[i]) == 3) ||
(p(e[i]) > p(S[sp-1])))
break;
// Na wyjście przesyłamy
// ze stosu wszystkie
// operatory o wyższych
// priorytetach
t += S[--sp];
// Echo na ekran
cout << S[sp] << " ";
}
// Operator umieszczamy
// na stosie
S[sp++] = e[i];
break;
}
default : {
// Inaczej znak przesyłamy
// na wyjście
t += e[i];
// Echo na ekran
cout << e[i] << " ";
break;
}
}
// Jeśli stos coś zawiera,
// to na wyjście przesyłamy
while(sp)
{
// całą zawartość stosu
t += S[--sp];
// Echo na ekran
cout << S [sp] << " ";
}
cout << endl << endl;
return t;
}
// Funkcja zwraca adres korzenia
// drzewa wyrażeń, które zostaje
// utworzone na podstawie
// wyrażenia e
//-------------------------------
BTnode * etree(string e)
{
// Stos
BTnode * S[S_MAX];
// Wskaźnik stosu
int sp;
// Adres węzła
BTnode * v;
// Indeks
unsigned int i;
// Zerujemy stos
sp = 0;
// Przetwarzamy wyrażenie ONP
for(i = 0; i < e.length(); i++)
{
// Tworzymy nowy węzeł
v = new BTnode;
// Umieszczamy w nim
// element wyrażenia
v->data = e[i];
switch(e [i])
{
// Operator
case '+' :
case '-' :
case '*' :
case '/' :
case '^' : {
// Pobieramy ze stosu węzły
// i czynimy je synami
// węzła
v->right = S[--sp];
v->left = S[--sp];
break;
}
// Argument
default : {
// Liść, nie ma synów
v->left = v->right= NULL;
break;
}
}
// Węzeł umieszczamy na stosie
S[sp++] = v;
}
// Zwracamy adres korzenia
return S[sp-1];
}
// Procedura DFS:postorder
// usuwająca drzewo
//-----------------------------------------
void dfs_release(BTnode * v)
{
if(v)
{
// usuwamy lewe poddrzewo
dfs_release(v->left);
// usuwamy prawe poddrzewo
dfs_release(v->right);
// usuwamy sam węzeł
delete v;
}
}
// Procedura wypisuje drzewo
//--------------------------
void print_bt(string sp,
string sn,
BTnode * v)
{
string s;
if(v)
{
s = sp;
if(sn == cr)
s[s.length()-2] = ' ';
print_bt(s+cp, cr, v->right);
s = s.substr(0, sp.length()-2);
cout << s << sn << v->data << endl;
s = sp;
if(sn == cl) s[s.length()-2] = ' ';
print_bt(s+cp, cl, v->left);
}
}
//**********************
//*** PROGRAM GŁÓWNY ***
//**********************
int main()
{
// Wyrażenie
string e;
// Korzeń drzewa
BTnode * root;
// Ustawiamy łańcuchy znakowe,
// ponieważ nie wszystkie
// edytory pozwalają
// wstawiać znaki konsoli
// do tworzenia ramek.
// cr = +--
// |
// cl = |
// +--
// cp = |
// |
cr = cl = cp = " ";
cr[0] = 218; cr[1] = 196;
cl[0] = 192; cl[1] = 196;
cp[0] = 179;
// Czytamy wyrażenie
getline(cin, e);
cout << endl;
// Tworzymy drzewo wyrażeń
root = etree(onp(e));
// Wyświetlamy drzewo
print_bt("", "", root);
// Usuwamy drzewo z pamięci
dfs_release(root);
return 0;
}
|
Basic' Tworzenie drzewa wyrażeń
' Data: 11.05.2013
' (C)2013 mgr Jerzy Wałaszek
'------------------------------
' Typ węzłów drzewa
'------------------
Type BTnode
left As BTnode Ptr
right As BTnode Ptr
data As String * 1
End Type
' rozmiar dla stosów
Const S_MAX = 100
' Zmienne globalne
'-----------------
' łańcuchy do ramek
Dim Shared As String * 2 cr, cl, cp
' Zwraca priorytet operatora
'---------------------------
Function p (c As String) _
As Integer
Select Case c
Case "("
p = 0
Case "+", "-"
p = 1
Case "*", "/"
p = 2
Case "^"
p = 3
End Select
End Function
' Funkcja przekształca wyrażenie
' arytmetyczne e na ONP
'-------------------------------
Function ONP (e As string) _
As String
' Stos operatorów
Dim S(S_MAX) As String * 1
' Wskaźnik stosu
Dim sp As Integer
' Wynik
Dim t As String
Dim i As Integer
' Inicjujemy stos
sp = 0
' Zerujemy wynik
t = ""
For i = 1 To Len(e)
' Analizujemy znak
Select Case Mid(e, i, 1)
' Spację ignorujemy
Case " "
Case "("
' Nawias otwierający
' zawsze na stos
S(sp) = "("
sp += 1
Case ")"
' Nawias zamykający
While S(sp-1) <> "("
' Ze stosu przesyłamy
' na wyjście wszystkie
' operatory aż do
' nawiasu otwierającego
sp -= 1
t += S(sp)
' Echo na ekran
Print S(sp);" ";
Wend
' Usuwamy ze stosu
' nawias otwierający
sp -= 1
Case "+", "-", "*", "/", "^"
While sp > 0
If(p(Mid(e, i, 1)) = 3) OrElse _
(p(Mid(e, i, 1)) > p(S(sp-1))) _
Then Exit While
' Na wyjście przesyłamy
' ze stosu wszystkie
sp -= 1
' operatory o wyższych
' priorytetach
t += S(sp)
' Echo na ekran
Print S(sp);" ";
Wend
' Operator umieszczamy
' na stosie
S(sp) = Mid(e, i, 1)
sp += 1
Case Else
' Inaczej znak
' przesyłamy na wyjście
t += Mid(e, i, 1)
' Echo na ekran
Print Mid(e, i, 1);" ";
End Select
Next
' Jeśli stos coś zawiera,
While sp > 0
' to na wyjście przesyłamy
sp -= 1
' całą zawartość stosu
t += S(sp)
' Echo na ekran
Print S(sp);" ";
Wend
Print: Print
ONP = t
End Function
' Funkcja zwraca adres korzenia
' drzewa wyrażeń, które zostaje
' utworzone na podstawie wyrażenia e
'-----------------------------------
Function etree(e As String) _
As BTnode Ptr
' Stos węzłów
Dim As BTnode Ptr S(S_MAX)
' Wskaźnik stosu
Dim As Integer sp
' Adres węzła
Dim As BTnode Ptr v
' Indeks
Dim As Integer i
' Zerujemy stos
sp = 0
' Przetwarzamy wyrażenie ONP
For i = 1 To Len(e)
' Tworzymy nowy węzeł
v = new BTnode
' Umieszczamy w nim
' element wyrażenia
v->data = Mid(e, i, 1)
Select Case Mid(e, i, 1)
' Operator
Case "+", "-", "*", "/", "^"
' Pobieramy ze stosu
' węzły i czynimy je
' synami węzła
v->right = S(sp-1)
v->left = S(sp-2)
sp -= 2
' Argument
Case Else
' Liść, nie ma synów
v->left = 0
v->Right = 0
End Select
' Węzeł umieszczamy na stosie
S(sp) = v
sp += 1
Next
' Zwracamy adres korzenia
etree = S(sp-1)
End Function
' Procedura DFS:postorder
' usuwająca drzewo
'------------------------
Sub dfs_release(v As BTnode Ptr)
If v Then
' usuwamy lewe poddrzewo
dfs_release(v->left)
' usuwamy prawe poddrzewo
dfs_release(v->right)
' usuwamy sam węzeł
Delete v
End If
End Sub
' Procedura wypisuje drzewo
'--------------------------
Sub print_bt(sp As String, _
sn As String, _
v As BTnode Ptr)
Dim As String s
If v Then
s = sp
If sn = cr Then _
Mid(s, Len(s)-1, 1) = " "
print_bt(s+cp, cr, v->right)
s = Mid(s, 1, Len(sp)-2)
Print Using "&&&";s;sn;v->Data
s = sp
If sn = cl Then Mid(s, Len(s)-1, 1) = " "
print_bt(s+cp, cl, v->Left)
End If
End Sub
'**********************
'*** PROGRAM GŁÓWNY ***
'**********************
' Wyrażenie
Dim As string e
' Korzeń drzewa
Dim As BTnode Ptr root
' Ustawiamy łańcuchy znakowe,
' ponieważ nie wszystkie
' edytory pozwalają wstawiać
' znaki konsoli do tworzenia
' ramek.
' cr = +--
' |
' cl = |
' +--
' cp = |
' |
cr = Chr(218)+Chr(196)
cl = Chr(192)+Chr(196)
cp = Chr(179)+" "
Open Cons For Input As #1
' Czytamy wyrażenie
Line Input #1, e
Print
' Tworzymy drzewo wyrażeń
root = etree(onp(e))
' Wyświetlamy drzewo
print_bt("", "", root)
' Usuwamy drzewo z pamięci
dfs_release(root)
End
|
| Python (dodatek) |
# Tworzenie drzewa wyrażeń
# Data: 23.07.2024
# (C)2024 mgr Jerzy Wałaszek
#------------------------------
# klasa węzłów drzewa
class BTnode:
def __init__(self):
self.left = None
self.right = None
self.data = 0
# zmienne globalne
# rozmiar dla stosów
S_MAX = 100
# łańcuchy do ramek
cr = "┌─"
cl = "└─"
cp = "│ "
# Zwraca priorytet operatora
def p(c):
r = -1
match c:
case "(":
r = 0
case "+"|"-":
r = 1
case "*"|"/":
r = 2
case "^":
r = 3
return r
# Funkcja przekształca wyrażenie
# arytmetyczne e na ONP
def onp(e):
global S_MAX
# Stos operatorów
s = [""] * S_MAX
# Wskaźnik stosu
sp = 0
# Wynik
t = ""
for i in range(len(e)):
# Analizujemy znak
match e[i]:
# Spację ignorujemy
case " ":
sp = sp
case "(":
# Nawias otwierający
# zawsze na stos
s[sp] = "("
sp += 1
case ")":
# Nawias zamykający
while s[sp-1] != "(":
# Ze stosu przesyłamy
# na wyjście wszystkie
# operatory aż do
# nawiasu otwierającego
sp -= 1
t += s[sp]
# Echo na ekran
print(s[sp], end=" ")
# Usuwamy ze stosu
# nawias otwierający
sp -= 1
case "+"|"-"|"*"|"/"|"^":
while sp:
if ((p(e[i]) == 3) or
(p(e[i]) > p(s[sp-1]))):
break
# Na wyjście przesyłamy
# ze stosu wszystkie
sp -= 1
# operatory o wyższych
# priorytetach
t += s[sp]
# Echo na ekran
print(s[sp], end=" ")
# Operator umieszczamy
# na stosie
s[sp] = e[i]
sp += 1
case _:
# Inaczej znak
# przesyłamy na wyjście
t += e[i]
# Echo na ekran
print(e[i], end=" ")
# Jeśli stos coś zawiera,
while sp:
# to na wyjście przesyłamy
sp -= 1
# całą zawartość stosu
t += s[sp]
# Echo na ekran
print(s[sp], end=" ")
print()
print()
return t
# Funkcja zwraca adres korzenia
# drzewa wyrażeń, które zostaje
# utworzone na podstawie wyrażenia e
def etree(e):
global S_MAX
# Stos węzłów
s = [BTnode()] * S_MAX
# Wskaźnik stosu
sp = 0
# Przetwarzamy wyrażenie ONP
for i in range(len(e)):
# Tworzymy nowy węzeł
v = BTnode()
# Umieszczamy w nim
# element wyrażenia
v.data = e[i]
match e[i]:
# Operator
case "+"|"-"|"*"|"/"|"^":
# Pobieramy ze stosu
# węzły i czynimy je
# synami węzła
v.right = s[sp-1]
v.left = s[sp-2]
sp -= 2
# Argument
case _:
# Liść, nie ma synów
v.left = None
v.Right = None
# Węzeł umieszczamy na stosie
s[sp] = v
sp += 1
# Zwracamy adres korzenia
return s[sp-1]
# Procedura DFS:postorder
# usuwająca drzewo
def dfs_release(v):
if v:
# usuwamy lewe poddrzewo
dfs_release(v.left)
# usuwamy prawe poddrzewo
dfs_release(v.right)
# usuwamy odwołania
v.left = None
v.right = None
# procedura wypisuje drzewo
def print_bt(sp, sn, v):
global cr, cl, cp
if v:
s = sp
if sn == cr:
s = s[:-2]+' '+s[-1]
print_bt(s+cp, cr, v.right)
s = s[:-2]
print(s, sn, v.data, sep="")
s = sp
if sn == cl:
s = s[:-2]+' '+s[-1]
print_bt(s+cp, cl, v.left)
#**********************
#*** PROGRAM GŁÓWNY ***
#**********************
# Czytamy wyrażenie
e = input()
print()
# Tworzymy drzewo wyrażeń
root = etree(onp(e))
# Wyświetlamy drzewo
print_bt("", "", root)
# Usuwamy drzewo z pamięci
dfs_release(root)
|
| Wynik: |
(a+b^(c-d))/e*f^g
a b c d - ^ + e / f g ^ *
┌─g
┌─^
│ └─f
*
│ ┌─e
└─/
│ ┌─d
│ ┌─-
│ │ └─c
│ ┌─^
│ │ └─b
└─+
└─a
|
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.