Вы находитесь на странице: 1из 36

Data Structures and Algorithms

C - Project

Stochitoiu Alexandru 10207B

IT-SHOP

2-3 and Trie Tree structures

CONTENTS:

1. DESCRIPTION.......................2
2. THEORETICAL CONSIDERATIONS.......................................................4 - 2-3 Tree.....4 - Trie Tree........8 3. SOURCE CODE, COMMENTS............11 4. REFERENCES...........36

2-3 Tree

A 2-3 search tree is a tree that either is empty or: 2-node, with one key and two links, a left link to a subtree with smaller keys, and a right link to a subtree with larger keys; 3-node, with two keys and three links, a left link to a subtree with smaller keys, a middle link to a subtree with keys between the nodes keys and a right link to a subtree with larger keys. As usual, we refer to a link to an empty tree as a null link. A perfectly balanced 2-3 search tree is one whose null links are all the same distance from the root. To be concise, we use the term 2-3 tree to refer to a perfectly balanced 2-3 search tree (the term denotes a more general structure in other contexts). Next, we describe the use of 2-3 trees as the underlying data structure for a symbol table. The search algorithm for keys in a 2-3 tree directly generalizes the search algorithm for BSTs. To determine whether a key is in the tree, we compare it against the keys at the root: If it is equal to any of them, we have a search hit; otherwise, we follow the link from the root to the subtree corresponding to the interval of key values that could contain the search key, and then recursively search in that subtree.

Insert into a 2-node. To insert a new node in a 2-3 tree, we might do an unsuccessful search and then hook on the node at the bottom, as we did with BSTs, but the new tree would not remain perfectly balanced. The primary reason that 2-3 trees are useful is that we can do insertions and still maintain perfect balance in the tree. It is easy to

accomplish this task if the node at which the search terminates is a 2-node: We just replace the node with a 3-node containing its key and the new key to be inserted. If the node where the search terminates is a 3-node, we have more work to do.

Local transformations. Splitting a temporary 4-node in a 2-3 tree involves one of five transformations, summarized at the top of the next page. The 4-node may be the left child or the right child of a 2-node, or it may be the left child, middle child, or right child of a 3-node. The basis of the algorithm is that all of these transformations are purely local: No part of the tree needs to be examined or modified other than the specified nodes. The number of links changed for each transformation is bounded by a small constant. In particular, the transformations are effective when we find the specified patterns anywhere in the tree, not just at the bottom. Each of the transformations passes up one of the keys from a 4-node to that nodes parent in the tree, and then restructures links accordingly. Global properties. Moreover, these local transformations preserve the global properties that the tree is ordered and balanced. For reference, a complete diagram illustrating this point for the case that the 4-node is the middle child of a 3-node is shown here.

Before the split, if the height of the subtree rooted at any node in the tree is h, then the height of the subtree rooted at its parent is h+1. Each transformation preserves this property, even while splitting the 4-node into two 2-nodes and while changing the parent from a 2-node to a 3-node. or from a 3-node into a temporary 4node, or when splitting the root into three 2-nodes and increasing the height of the whole tree by 1. Understanding that every transformation preserves order and perfect balance in the whole tree is the key to understanding the algorithm.

UNLIKE STANDARD BSTS, WHICH GROW DOWN from the top, 2-3 trees grow up from the bottom. If you take the time to carefully study the sequence of trees that are produced by our standard indexing test client and the sequence of trees that are produced when the same keys are inserted in increasing order, you will have a good understanding of the way that 2-3 trees are built. Recall that in a BST, the increasing-order sequence for 10 keys results in a worst-case tree where a search might involve examining all the keys. In the 2-3 trees, all keys can be found in every case by examining at most three nodes. THE PRECEDING DESCRIPTION IS SUFFICIENT TO define a symbol-table implementation with 2-3 trees as the underlying data structure. Analyzing 2-3 trees is different from analyzing BSTs because our primary interest is in worst-case performance, as opposed to average- case performance (where we analyze expected performance under an assumption that key values come from some random source). In symbol-table implementations, we normally have no control over the order in which clients insert keys into.

Ex:

Trie Trees

A trie (from retrieval), is a multi-way tree structure useful for storing strings over an alphabet. It has been used to store large dictionaries of English (say) words in spelling-checking programs and in natural-language "understanding" programs. Given the data: an, ant, all, allot, alloy, aloe, are, ate, be the corresponding trie would be:

The idea is that all strings sharing a common stem or prefix hang off a common node. When the strings are words over {a..z}, a node has at most 27 children - one for each letter plus a terminator. The elements in a string can be recovered in a scan from the root to the leaf that ends a string. All strings in the trie can be recovered by a depth-first scan of the tree. One fast but rather wasteful way to implement a trie in Pascal:
type trie = ^ node; node = record subtrie :array['a'..'z'] of trie; IsEndOfWord :boolean end;

It is wasteful as a lot of nodes near the edge of the trie will have most subtries set to nil. On the other hand lookup is direct as there is random access on each level/character position in a string.
function find(word:string; length:integer; t:trie):boolean; function f(level:integer; t:trie):boolean; begin if level=length+1 then f:=t^.IsEndOfWord else if t^.subtrie[word[level]]=nil then f:=false else f:=f(level+1, t^.subtrie[word[level]]) end{f}; begin find := f( 1, t ) end{find}

A second way to implement the trie is to represent each node in the trie as a linked-list of at most 27 elements, each element being a pair <char,trie>. In this case, a search (linear, binary, ...) must be used at each level but less space is wasted at leaves; remember most trees have more leaves than forks.

SOURCE CODE
#include #include #include #include #include <stdio.h> <conio.h> <malloc.h> <iostream> <stdlib.h>

using namespace std; FILE *f;

typedef struct info { int id; char denumire[20]; char producator[20]; char categorie[20]; int garantie; int stoc; float pret; } produs; typedef struct _PArb { int k1, k2; produs i1, i2; struct _PArb *up, *st, *mij, *dr; }PArb3_2; typedef int sir[50]; #define K 32000 PArb3_2 *a; bool ok=false, exista=false; //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// /// Arbore 2-3 //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// PArb3_2 *x[50]; PArb3_2 *b, *r, *l, *c; void modificareProdus(produs &temp); void Aloca(PArb3_2 **p, int key) { (*p) = new PArb3_2; (*p)->k1 = key; (*p)->k2 = K; (*p)->up = NULL; (*p)->st = NULL; (*p)->mij = NULL; (*p)->dr = NULL; } void Ordonare(int z[50], produs y[50]) { int i, x, flag;

produs x2;; do { flag = 1; for(i = 0; i < 2; i++) if(z[i] > z[i + 1]) { flag = 0; x = z[i]; x2 = y[i]; z[i] = z[i + 1]; y[i] = y[i + 1]; z[i + 1] = x; y[i + 1] = x2; } }while(!flag);

} void OrdonareP(PArb3_2 *z[50]) { int i, flag; PArb3_2 *x; do {

flag = 1; for(i = 0; i < 3; i++) if(z[i]->k1 > z[i + 1]->k1) { flag = 0; x = z[i]; z[i] = z[i + 1]; z[i + 1] = x; } }while(!flag);

void Creare(produs item) { int z[50]; produs y[50]; int i, j, t = 1, g = 0; if(a == NULL) { (a) = new PArb3_2; a->k1 = item.id; a->i1 = item; (a)->k2 = K; (a)->up = NULL; (a)->st = NULL; (a)->mij = NULL; (a)->dr = NULL; } else { b = a; while(t) { if(item.id == b->k1||item.id == b->k2) { g = 1; t = 0;

} else if(b->st == NULL) t = 0; else if(item.id < b->k1) b = b->st; else if(item.id < b->k2) b = b->mij; else b = b->dr; } if(g) { } else

//cout<<"Cheia exista in arbore!!!\n";

if(b->k2 == K) if(item.id > b->k1) { b->k2 = item.id; b->i2 = item; } else { b->k2 = b->k1; b->i2 = b->i1; b->k1 = item.id; b->i1 = item; } else { z[0] = item.id; y[0] = item; z[1] = b->k1; y[1] = b->i1; z[2] = b->k2; y[2] = b->i2; Ordonare(z, y); l = new PArb3_2; l->k1 = z[0]; l->i1 = y[0]; l->k2 = K; l->up = NULL; l->st = NULL; l->mij = NULL; l->dr = NULL; r = new PArb3_2; r->k1 = z[2]; r->i1 = y[2]; r->k2 = K; r->up = NULL; r->st = NULL; r->mij = NULL; r->dr = NULL; item.id = z[1]; item = y[1]; c = b; b = b->up; while (b != NULL && b->k2 != K) { x[0] = l; x[1] = r; x[2] = b->st;

//

x[3] = b->mij; x[4] = b->dr; for(i = 2; i < 4; i++) if(x[i] == c) for(j = i; j < 4; j++) x[j] = x[j + 1]; OrdonareP(x); z[0] = b->k1; y[0] = b->i1; z[1] = b->k2; y[1] = b->i2; z[2] = item.id; y[2] = item; Ordonare(z, y); item.id = z[1]; item = y[1]; l = new PArb3_2; l->k1 = z[0]; l->i1 = y[0]; l->k2 = K; l->up = NULL; l->st = NULL; l->mij = NULL; l->dr = NULL; r = new PArb3_2; r->k1 = z[2]; r->i1 = y[2]; r->k2 = K; r->up = NULL; r->st = NULL; r->mij = NULL; r->dr = NULL; l->st = x[0]; l->mij = x[1]; x[0]->up = l; x[1]->up = l; r->st = x[2]; r->mij = x[3]; x[2]->up = r; x[3]->up = r; free(c); c = b; b = b->up;

//

// !

} if(b!= NULL) if(c == b->st) { b->k2 = b->k1; b->i2 = b->i1; b->k1 = item.id; b->i1 = item; b->dr = b->mij; b->mij = r; b->st = l; r->up = b; l->up = b; free(c); } else { b->k2 = item.id; b->i2 = item;

} else {

b->dr = r; b->mij = l; r->up = b; l->up = b; free(c);

free(c); c = new PArb3_2; c->k1 = item.id; c->i1 = item; c->k2 = K; c->up = NULL; c->st = NULL; c->mij = NULL; c->dr = NULL; c->st = l; c->mij = r; r->up = c; l->up = c; a = c;

} } } }

void inorder(PArb3_2 *p, int i) { int o; if(p != NULL) { inorder(p->dr, i+2); for(o = 0; o < i; o++) printf(" "); if((p->k1!=K) &&(p->k2!=K)) printf(" %d %d \n", p->k1, p->k2); else if((p->k1!=K)&& (p->k2==K)) printf(" %d \n", p->k1); else if((p->k1==K) &&(p->k2!=K)) printf(" %d \n",p->k2); inorder(p->mij, i+2); inorder(p->st, i + 2); } } void afisareDetalii(produs p) { printf("ID: %d\n",p.id); printf("Denumire: %s\n",p.denumire); printf("Producator: %s\n",p.producator); printf("Categorie: %s\n",p.categorie); printf("Garantie: %d\n",p.garantie); printf("Stoc: %d\n",p.stoc); printf("Pret: %0.2f\n",p.pret); printf("\n"); } void afisareCompleta(PArb3_2 *p, int i) { int o; if(p != NULL) { afisareCompleta(p->dr, i+2);

if((p->k1!=K) &&(p->k2!=K)) { afisareDetalii(p->i1); afisareDetalii(p->i2); } else if((p->k1!=K)&& (p->k2==K)) { afisareDetalii(p->i1); } else if((p->k1==K) &&(p->k2!=K)) afisareDetalii(p->i2); afisareCompleta(p->mij, i+2); afisareCompleta(p->st, i+2);

} } void Elimina(produs item) { PArb3_2 *b, *d, *c; int t = 1, g = 0; b = a;

while(t) if((item.id == b->k1)||(item.id == b->k2)) { g = 1; t = 0; } else if(!b->st) t = 0; else if(item.id < b->k1) b = b->st; else if(item.id < b->k2) b = b->mij; else b = b->dr; if(!g) { printf("Cheia nu a fost introdusa!\n"); getch(); } else { if(b->st) { if(item.id == b->k1) c = b->mij; else c = b->dr; while(c->st) c = c->st; if(item.id == b->k1) { b->k1 = c->k1; b->i1 = c->i1; } else { b->k2 = c->k1; b->i2 = c->i1; } b = c; b->k1 = b->k2; b->i1 = b->i2; b -> k2 = K;

} else {

} while((b->up)&&(b->k1 == K)) { c = b->up; if(b == c->st) { d = c->mij; if(d->k2 != K) { b->k1 = c->k1; b->i1 = c->i1; c->k1 = d->k1; c->i1 = d->i1; d->k1 = d->k2; d->i1 = d->i2; d->k2 = K; b->mij = d->st; d->st = d->mij; d->mij = d->dr; d->dr = NULL; } else { b->k1 = c->k1; b->i1 = c->i1; b->k2 = d->k1; b->i2 = d->i1; b->mij = d->st; b->dr = d->mij; if(d->st) { d->st->up = b; d->mij->up = b; } b = c; b->k1 = b->k2; b->i1 = b->i2; b ->k2 = K; b->mij = b->dr; b->dr = NULL; free(d); } } if(b == c->mij) { d = c->st; if(d->k2 != K) { b->k1 = c->k1; b->i1 = c->i1; c->k1 = d->k2; c->i1 = d->i2; d->k2 = K;

if(item.id == b->k2 = else { b->k1 = b->i1 = b->k2 = }

b->k2) K; b->k2; b->i2; K;

} else {

b->mij = b->st; b->st = d->dr; d->dr = NULL;

d->k2 = c->k1; d->i2 = c->i1; c->k1 = c->k2; c->i1 = c->i2; c->k2 = K; c->mij = c->dr; c->dr = NULL; d->dr = b->st; if(b->st) b->st->up = d; free(b); b = c; } } if(b == c->dr) { d = c->mij; if(d->k2!=K) { b->k1 = c->k2; b->i1 = c->i2; c->k2 = d->k2; c->i2 = d->i2; d->k2 = K; b->mij = b->st; b->st = d->dr; d->dr = NULL; } else { d->k2 = c->k2; d->i2 = c->i2; c->k2 = K; c->dr = NULL; d->dr = b->st; if(b->st) b->st->up = d; free(b); b = d; } }

} if((b->k1 == K) && (b->st)) { b->st->up = NULL; a = b->st; free(b); } } }

int StergeProdus(PArb3_2 *p, int id, int i) { int o; char ch; if(p != NULL) { StergeProdus(p->dr, id, i+2);

if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost sters:\n"); getch(); Elimina(p->i1); return 0; } if(p->i2.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost sters:\n"); getch(); Elimina(p->i2); return 0; } } else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost sters:\n"); getch(); Elimina(p->i1); return 0; } } else if((p->k1==K) &&(p->k2!=K)) { if(p->i2.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost sters:\n"); getch(); Elimina(p->i2); return 0; } } StergeProdus(p->mij, id, i+2); StergeProdus(p->st, id, i+2); } }

///////////////////////////////////////////////////////////////////////// Cauta produse ///////////////////////// void cautareId(PArb3_2 *p, int id, int i) { int o; char ch; if(p != NULL) { cautareId(p->dr, id, i+2); if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost gasit:\n");

afisareDetalii(p->i1); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i1); } } if(p->i2.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost gasit:\n"); afisareDetalii(p->i2); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i2); } } } else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost gasit:\n"); afisareDetalii(p->i1); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i1); } } else } if((p->k1==K) &&(p->k2!=K)) { if(p->i2.id == id) { ok = true; printf("Produsul cu id-ul cautat a fost afisareDetalii(p->i2); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i2); } } } cautareId(p->mij, id, i+2); cautareId(p->st, id, i+2);

gasit:\n");

} }

void cautareDenumire(PArb3_2 *p, char* denumire, int i) { int o; char ch; if(p != NULL) { cautareDenumire(p->dr, denumire, i+2); if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.denumire == denumire) { ok = true; printf("Produsul cu denumirea cautata a fost gasit:\n"); afisareDetalii(p->i1); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i1); } } if(p->i2.denumire == denumire) { ok = true; printf("Produsul cu denumirea cautata a fost gasit:\n"); afisareDetalii(p->i2); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i2); } } } else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.denumire == denumire) { ok = true; printf("Produsul cu denumirea cautata a fost gasit:\n"); afisareDetalii(p->i1); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i1); } } else } if((p->k1==K) &&(p->k2!=K)) { if(p->i2.denumire == denumire) { ok = true; printf("Produsul cu denumirea cautata a fost afisareDetalii(p->i2); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch());

gasit:\n");

if(ch=='D') { modificareProdus(p->i2); } } } cautareDenumire(p->mij, denumire, i+2); cautareDenumire(p->st, denumire, i+2);

} }

void cautareProducator(PArb3_2 *p, char* producator, int i) { int o; char ch; if(p != NULL) { cautareProducator(p->dr, producator, i+2); if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.producator == producator) { ok = true; printf("Produsul cu producatorul cautat a fost gasit:\n"); afisareDetalii(p->i1); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i1); } } if(p->i2.producator == producator) { ok = true; printf("Produsul cu producatorul cautat a fost gasit:\n"); afisareDetalii(p->i2); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i2); } } } else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.producator == producator) { ok = true; printf("Produsul cu producatorul cautat a fost gasit:\n"); afisareDetalii(p->i1); printf("Modificati detaliile produsului? (D/N)\n"); ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i1); } } }

else

gasit:\n"); (D/N)\n");

if((p->k1==K) &&(p->k2!=K)) { if(p->i2.producator == producator) { ok = true; printf("Produsul cu producatorul cautat a fost afisareDetalii(p->i2); printf("Modificati detaliile produsului? ch=toupper(getch()); if(ch=='D') { modificareProdus(p->i2); } } } cautareProducator(p->mij, producator, i+2); cautareProducator(p->st, producator, i+2);

//////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// void citireFisier() { produs it; if((f=fopen("produs.txt","r"))==NULL) { printf("A aparut o eroare la deschiderea fisierului!"); getch(); exit(0); } else { while(!feof(f)) { fread(&it,1,sizeof(produs),f); Creare(it); } printf("Datele au fost incarcate din fisier"); fclose(f); getch(); } } void salveaza(PArb3_2 *p, int i) { if(p != NULL) { salveaza(p->dr, i+2); if((p->k1!=K) &&(p->k2!=K)) { fwrite(&p->i1,1,sizeof(produs),f); fwrite(&p->i2,1,sizeof(produs),f); } else if((p->k1!=K)&& (p->k2==K)) fwrite(&p->i1,1,sizeof(produs),f); else if((p->k1==K) &&(p->k2!=K))

} }

fwrite(&p->i2,1,sizeof(produs),f); salveaza(p->mij, i+2); salveaza(p->st, i+2);

void salvareFisier() { if((f=fopen("produs.txt","w"))==NULL) { printf("A aparut o eroare la deschiderea fisierului!"); getch(); exit(0); } else { salveaza(a, 0); printf("Datele au fost descarcate cu succes!"); getch(); fclose(f); } } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// void modificareProdus(produs &temp) { printf("Introduceti noile informatii:\n"); printf("id: ");// fflush(stdin); scanf("%d",&temp.id); printf("denumire: ");// fflush(stdin); gets(temp.denumire); printf("producator: ");// fflush(stdin); gets(temp.producator); printf("categorie: ");// fflush(stdin); gets(temp.categorie); printf("garantie: ");// fflush(stdin); scanf("%d",&temp.garantie); printf("stoc: ");// fflush(stdin); scanf("%d",&temp.stoc); printf("pret: ");// fflush(stdin); scanf("%f",&temp.pret); } void afisarePretMaiMic(PArb3_2 *p, float pret, int i) { int o; char ch; if(p != NULL) { afisarePretMaiMic(p->dr, pret, i+2); if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.pret < pret)

} if(p->i2.pret < pret) { ok = true; afisareDetalii(p->i2); } } else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.pret < pret) { ok = true; afisareDetalii(p->i1); } } else if((p->k1==K) &&(p->k2!=K)) { if(p->i2.pret < pret) { ok = true; afisareDetalii(p->i2); } } afisarePretMaiMic(p->mij, pret, i+2); afisarePretMaiMic(p->st, pret, i+2);

ok = true; afisareDetalii(p->i1);

} }

void afisarePretMaiMare(PArb3_2 *p, float pret, int i) { int o; char ch; if(p != NULL) { afisarePretMaiMare(p->dr, pret, i+2); if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.pret > pret) { ok = true; afisareDetalii(p->i1); } if(p->i2.pret > pret) { ok = true; afisareDetalii(p->i2); } } else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.pret > pret) { ok = true; afisareDetalii(p->i1);

} } else if((p->k1==K) &&(p->k2!=K)) { if(p->i2.pret > pret) { ok = true; afisareDetalii(p->i2); } } afisarePretMaiMare(p->mij, pret, i+2); afisarePretMaiMare(p->st, pret, i+2);

} } void afisareNumeDorit(PArb3_2 *p, char* denumire, int i) { int o; char ch; if(p != NULL) { afisareNumeDorit(p->dr, denumire, i+2); if((p->k1!=K) &&(p->k2!=K)) { if(p->i1.denumire == denumire) { ok = true; afisareDetalii(p->i1); } if(p->i2.denumire == denumire) { ok = true; afisareDetalii(p->i2); } }

else if((p->k1!=K)&& (p->k2==K)) { if(p->i1.denumire == denumire) { ok = true; afisareDetalii(p->i1); } else } if((p->k1==K) &&(p->k2!=K)) { if(p->i2.denumire == denumire) { ok = true; afisareDetalii(p->i2); } } afisareNumeDorit(p->mij, denumire, i+2); afisareNumeDorit(p->st, denumire, i+2); } }

void meniuAfisare()

float pret; char nume[20], opt; do { system("cls"); printf("Cautare produs:\n"); printf("1 - Afisare produse cu pretul mai mic decat o valoare\n"); printf("2 - Afisare produse cu pretul mai mare decat o valoare\n"); printf("3 - Afisare produse dupa numele dorit\n"); printf("0 - Exit!\n"); opt=getch(); switch(opt) { case '1': system("cls"); printf("Pret: "); scanf("%f",&pret); printf("Produsele cu pretul mai mic de %0.2f sunt: \n",pret); ok=false; afisarePretMaiMic(a, pret, 0); if(ok==false) printf("Nu exista produse cu pretul mai mic de %0.2f! \n",pret); getch(); break; case '2': system("cls"); printf("Pret: "); scanf("%f",&pret); printf("Produsele cu pretul mai mare de %0.2f sunt: \n",pret); ok=false; afisarePretMaiMare(a, pret, 0); if(ok==false) printf("Nu exista obiecte cu pretul mai mare de %0.2f! \n",pret); getch(); break; case '3': system("cls"); printf("Nume: "); scanf("%s",nume); printf("Obiectele cu numele %s sunt: \n",nume); ok=false; afisareNumeDorit(a, nume, 0); if(ok==false) printf("Nu exista obiecte avand numele %s! \n",nume); getch(); break; } } while(opt!='0'); } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// /// Arbore Trie //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// #define NR 27 // the American alphabet(26 letters) plus blank. typedef char var_type; // the key is a set of characters

typedef struct trie_node { bool NotLeaf; // indicates if the trie_node struct is a leaf or an intern node trie_node *pChildren[NR]; // a list of pointers corresponding to the used alphabet var_type word[40]; // the string stored in node produs item; }node; trie_node *trie = NULL; //function for creating a leaf node trie_node *NewLeaf(produs item) { trie_node *t_node; int count; //allocating the necessary memory t_node = (trie_node *)malloc(sizeof(trie_node)); for(count = 0; count < 27; count++) //the terminal nodes don't have children t_node->pChildren[count] = NULL; t_node->NotLeaf = false; // the node is a leaf strcpy(t_node->word,item.denumire); //store in the structure(node->word) the string t_node->item = item; return t_node; } //function for creating a intern node trie_node *NewIntern() { trie_node *t_node; int count; //allocating the necessary memory t_node = (trie_node *)malloc(sizeof(trie_node)); for(count = 0; count < 27; count++) // initial the intern node don't have children t_node->pChildren[count] = NULL; t_node->NotLeaf = true; //it isn't a leaf t_node->word[0] = 0; //so we store the null string in node return t_node; } //function performs a search in the TRIE when a string or key is passed. void Find(trie_node *trie, char keyWord[20]) { trie_node *next, *index, *data; int count; next = trie; //start searching from the trie root if(next == NULL) //trie is empty { cout << "Produsul cu denumirea introdusa nu a fost gasit." << endl ; exit(1); } else index = next;// index - the current node from trie count = 0; // start searching for the first letter of the word(index of letter in word is 0) while((index->NotLeaf == true) && (count < strlen(keyWord)) && (index>pChildren[keyWord[count]-'a'] != NULL)) { next = index->pChildren[keyWord[count]-'a']; index = next; count ++ ; }

if(next == NULL) cout << "Produsul cu denumirea introdusa nu a fost gasit." << endl; else { data = next; //the string is in a leaf if(!strcmp(data->word,keyWord)) cout << "Produsul cu denumirea introdusa a fost gasit." << endl; else//the string is in the blank pointer(prefix for others words stored in trie) if((data->pChildren[26]) && !strcmp(data->pChildren[26]>word,keyWord)) cout << "Produsul cu denumirea introdusa a fost gasit." << endl ; else cout << "Produsul cu denumirea introdusa nu a fost gasit." << endl ; } } //function for inserting a string into the trie trie_node *Insert(trie_node *trie, produs item) { trie_node *next, *index, *parent; trie_node *new_leaf, *data, *new_index; trie_node *oldChildren, *newWord, *intern; int inWordIndex, prefixLenght, lenght = strlen(item.denumire); next = trie; if(next == NULL) //trie empty { trie = NewIntern(); new_leaf = NewLeaf(item); trie->pChildren[item.denumire[0]-'a'] = new_leaf; return trie; } else index = next; inWordIndex = 0; while((inWordIndex < lenght) &&(index->NotLeaf == true)&&(index>pChildren[item.denumire[inWordIndex]-'a'] != NULL)) { parent = next; next = index->pChildren[item.denumire[inWordIndex]-'a']; index = next; inWordIndex++; } if((inWordIndex < lenght) && (index>pChildren[item.denumire[inWordIndex]-'a'] == NULL) && (index->NotLeaf == true)) { new_index = NewLeaf(item); index->pChildren[item.denumire[inWordIndex]-'a'] = new_index; return trie; } else data=next; if(!strcmp(data->word,item.denumire)) cout << "Un produs cu aceasta denumire exista deja in baza de date." << endl; else { oldChildren = parent->pChildren[item.denumire[inWordIndex-1]-'a']; newWord = NewLeaf(item); prefixLenght= strlen(item.denumire); if(data->word[0] != '\0')

if(strlen(data->word) < prefixLenght) prefixLenght = strlen(data->word); } bool createIntern = false; while((inWordIndex <= prefixLenght)&&(((data->word[0] != '\0' )&& (data>word[inWordIndex-1] == item.denumire[inWordIndex-1])) || (data->word[0] == '\0'))) { intern = NewIntern(); parent->pChildren[item.denumire[inWordIndex-1]-'a'] = intern; parent->NotLeaf = true; parent = intern; inWordIndex++; createIntern = true; } if(createIntern) inWordIndex--; if((inWordIndex != prefixLenght) || ((inWordIndex == prefixLenght)&&(strlen(item.denumire) == strlen(data->word)))) { parent->pChildren[data->word[inWordIndex]-'a'] = oldChildren; parent->pChildren[item.denumire[inWordIndex]-'a'] = newWord; } else if(data->word[0] != '\0')// doar un cuv care il are ca prefix pe keyWord sau invers if(strlen(data->word) <= prefixLenght) { parent->pChildren[26] = oldChildren; parent->pChildren[item.denumire[prefixLenght]-'a'] = newWord; } else { parent->pChildren[26] = newWord; parent->pChildren[data->word[prefixLenght]-'a'] = oldChildren; } else// 2 sau mai multe cuv care au acelasi prefix { for (int count = 0 ; count < 27;count++) parent->pChildren[count] = oldChildren>pChildren[count]; parent->pChildren[26] = newWord; } return trie; } //function for displaying the words stored in the trie void DisplayTrie(trie_node *trie, int nivel) { int count; if(trie) { if (trie->NotLeaf != true) // if trie_node is a leaf(a word is stored in) { // display the string at his level for (count = 0; count <= nivel; count++) cout << " "; cout << trie->word << endl; } // display all the words stored through trie children for (count = 26; count >= 0; count--) DisplayTrie(trie->pChildren[count], nivel + 4); }

} void DisplayTrieComplete(trie_node *trie, int nivel) { int count; if(trie) { if (trie->NotLeaf != true) // if trie_node is a leaf(a word is stored in) { printf("ID: %d\n",trie->item.id); printf("Denumire: %s\n",trie->item.denumire); printf("Producator: %s\n",trie->item.producator); printf("Categorie: %s\n",trie->item.categorie); printf("Garantie: %d\n",trie->item.garantie); printf("Stoc: %d\n",trie->item.stoc); printf("Pret: %0.2f\n",trie->item.pret); printf("\n"); } // display all the words stored through trie children for (count = 26; count >= 0; count--) DisplayTrieComplete(trie->pChildren[count], nivel + 4); } } void salvareTrie(trie_node *trie, int nivel) { int count; if(trie) { if (trie->NotLeaf != true) // if trie_node is a leaf(a word is stored in) { // display the string at his level fwrite(&trie->item,1,sizeof(produs),f); fflush(f); } // display all the words stored through trie children for (count = 26; count >= 0; count--) salvareTrie(trie->pChildren[count], nivel + 4); } } void mainTrie() { produs temp; char opt, ch; do { system("cls"); printf("\n Meniu arbore Trie:\n\n"); printf("1) printf("2) printf("3) printf("4) printf("5) printf("0) Inserare\n"); Afisare arbore pe nivele\n"); Afisare completa arbore\n"); Cautare\n"); Salvare \n"); Iesire\n");

opt=getch(); switch(opt) { case '1': do {

system("cls"); printf("- Arbore Trie -:\n");

printf("\n"); printf("1) Adaugare element nou!\n"); printf("0) Revenire meniu principal!\n"); ch=getch(); printf("\n"); if (ch=='1') { printf("id: ");// fflush(stdin); scanf("%d",&temp.id); printf("denumire: ");// fflush(stdin); gets(temp.denumire); printf("producator: ");// fflush(stdin); gets(temp.producator); printf("categorie: ");// fflush(stdin); gets(temp.categorie); printf("garantie: ");// fflush(stdin); scanf("%d",&temp.garantie); printf("stoc: ");// fflush(stdin); scanf("%d",&temp.stoc); printf("pret: ");// fflush(stdin); scanf("%f",&temp.pret); trie=Insert(trie, temp); }while (ch!='0'); break; case '2': printf("- Arbore Trie -:\n\n"); DisplayTrie(trie,0); getch(); break; case '3': printf("- Arbore Trie -:\n\n"); DisplayTrieComplete(trie,0); getch(); break; case '4': char denumire[20]; system("cls"); printf("Denumirea: "); fflush(stdin); gets(denumire); Find(trie, denumire); getch(); break; case '5': if((f=fopen("produs.txt","w"))==NULL) { printf("A aparut o eroare la deschiderea fisierului!"); getch(); exit(0); } else { salvareTrie(trie, 0); printf("Datele au fost descarcate cu succes!"); getch(); }

} }

} break;

fclose(f);

}while(opt!='0'); //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// void transforma(PArb3_2 *p, int i) { int o; if(p != NULL) { transforma(p->dr, i+2); if((p->k1!=K) &&(p->k2!=K)) { trie=Insert(trie, p->i1); trie=Insert(trie, p->i2); } else if((p->k1!=K)&& (p->k2==K)) trie=Insert(trie, p->i1); else if((p->k1==K) &&(p->k2!=K)) trie=Insert(trie, p->i2); transforma(p->mij, i+2); transforma(p->st, i+2); } } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// int { main() char optiune, opt; produs temp; do { system("cls"); printf("\n Main menu:\n"); printf("1 - Incarcare date din fisier\n"); printf("2 - Salvare date in fisier\n"); printf("3 - Inserare produse in arbore\n"); printf("4 - Stergere produse din arbore\n"); printf("5 - Afisare arbore pe nivele\n"); printf("6 - Afisare completa arbore\n"); printf("7 - Cautare produs \n"); printf("8 - Afisare produs \n"); printf("9 - Operatii cu arbori trie \n"); printf("Esc - Iesire\n"); optiune=getch(); switch(optiune) { case '1': system("cls"); citireFisier(); break; case '2':

system("cls"); salvareFisier(); break; case '3': do { system("cls"); printf("2-3 Tree:\n\n"); inorder(a, 0); printf("\n"); printf("1) Adaugare.\n"); printf("0) Revenire.\n"); opt=getch(); printf("\n"); if (opt=='1') { printf("id: ");// fflush(stdin); scanf("%d",&temp.id); printf("denumire: ");// fflush(stdin); gets(temp.denumire); printf("producator: ");// fflush(stdin); gets(temp.producator); printf("categorie: ");// fflush(stdin); gets(temp.categorie); printf("garantie: ");// fflush(stdin); scanf("%d",&temp.garantie); printf("stoc: ");// fflush(stdin); scanf("%d",&temp.stoc); printf("pret: ");// fflush(stdin); scanf("%f",&temp.pret); Creare(temp); } }while (opt!='0'); break; case '4': do { int id; system("cls"); printf("2-3 Tree:\n"); inorder(a, 0); printf("\n"); printf("1) Stergere.\n"); printf("0) Revenire.\n"); opt=getch(); printf("\n"); if (opt=='1') { printf("ID: "); scanf("%d",&id); ok=false; StergeProdus(a, id, 0); if (!ok) { printf("Nu exista produs cu acest ID!"); getch();

fost gasit!");

}while (opt!='0'); break; case '5': system("cls"); printf("2-3 Tree:\n"); inorder(a, 0); getch(); break; case '6': system("cls"); printf("2-3 Tree:\n"); afisareCompleta(a, 0); getch(); break; case '7': do { system("cls"); printf("Cauta produse in functie de:\n"); printf("1) ID\n"); printf("2) Denumire\n"); printf("3) Producator\n"); printf("0) Revenire \n"); opt=getch(); switch(opt) { case '1': int id; system("cls"); printf("ID: "); fflush(stdin); scanf("%d",&id); ok=false; cautareId(a, id, 0); if (!ok) { printf("Obiectul cu id-ul cautat nu a getch(); } break; case '2': char denumire[20]; system("cls"); printf("Dati denumirea: "); fflush(stdin); gets(denumire); ok=false; cautareDenumire(a, denumire, 0); if(ok==false) printf("Nu exista obiecte cu denumirea getch(); break; case '3': char producator[20]; system("cls"); printf("Dati producatorul: "); fflush(stdin); gets(producator); ok=false; cautareProducator(a, producator, 0);

%s! \n",denumire);

if(ok==false) printf("Nu exista produse cu producatorul %s! \n",producator); getch(); break;

} } while(opt!='0'); break; case '8': meniuAfisare(); break; case '9': trie = NULL; transforma(a, 0); mainTrie(); break;

} }while(optiune!=27);

REFERENCES
"Structuri de date si algoritmi" - Dumitru Dan Burdescu, Marian Cristian Mihaescu "Introduction to algorithms" - Thomas H. Cormen http://vjmr.files.wordpress.com/2009/11/slide22.pdf

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