Реализация
Сайт: | Информатикс |
Курс: | Структуры данных |
Книга: | Реализация |
Напечатано:: | Гость |
Дата: | Пятница, 15 Август 2025, 14:48 |
//(C) Igor Kvasov
type pnode=^node;
node=record
l,r,p:pnode;
x,y:longint;
end;
procedure split(t:pnode;x:longint;var l,r:pnode);
begin
if t=nil then begin l:=nil; r:=nil end else
if x<t^.x then begin split(t^.l,x,l,r); t^.l:=r; r:=t end
else begin split(t^.r,x,l,r); t^.r:=l; l:=t end;
end;
function merge(l,r:pnode):pnode;
begin
if l=nil then merge:=r else
if r=nil then merge:=l else
if l^.y>r^.y then begin l^.r:=merge(l^.r,r); merge:=l end
else begin r^.l:=merge(l,r^.l); merge:=r end;
end;
procedure insert(var t:pnode;x,y:longint);
var
tmp:pnode;
begin
if (t=nil) or (y>t^.y) then begin
new(tmp); split(t,x,tmp^.l,tmp^.r); t:=tmp; t^.x:=x; t^.y:=y
end else if x<t^.x then insert(t^.l,x,y)
else insert(t^.r,x,y);
end;
procedure delete(var t:pnode;x:longint);
var
tmp:pnode;
begin
if t=nil then exit else
if x<t^.x then delete(t^.l,x) else
if x>t^.x then delete(t^.r,x) else begin
tmp:=t; t:=merge(t^.l,t^.r); dispose(tmp);
end;
end;
function search(var t:pnode;x:longint):pnode;
var
tmp:pnode;
begin
search:=nil;
if t=nil then exit else
if x<t^.x then search:=search(t^.l, x) else
if x>t^.x then search:=search(t^.r, x) else
search:=t;
end;
function minimum(t:pnode):pnode;
begin
while t^.l<>nil do t:=t^.l;
minimum:=t;
end;
function maximum(t:pnode):pnode;
begin
while t^.r<>nil do t:=t^.r;
maximum:=t;
end;
begin
end.
Artem Voroztsov - 02 Mar 2005
#include <stdio.h>
#include <malloc.h>
#define UNIQ_KEYS 1
typedef int mvalue_t;
typedef int mkey_t;
typedef enum {
BT_ADDED,
BT_UPDATED,
BT_DELETED,
BT_FOUND,
BT_NOTFOUND,
BT_ERROR,
} dt_result_t;
typedef struct dt {
mvalue_t v;
mkey_t x;
int y;
struct dt *l, *r;
} dt_t;
dt_t*
dt_search(dt_t *t, mkey_t x) {
if ( t == NULL ) return NULL;
if ( x < t->x ) return dt_search(t->l, x);
if ( x > t->x ) return dt_search(t->r, x);
return t;
}
void
dt_split(dt_t *t, mkey_t x, dt_t **l, dt_t **r) {
if(t == NULL) {
*r = *l = NULL;
} else {
if(x < t->x) {
dt_split(t->l, x, l, r);
t->l = *r; *r = t;
} else {
dt_split(t->r, x, l, r);
t->r = *l; *l = t;
}
}
}
dt_t*
dt_merge(dt_t *l, dt_t *r) {
if (l == NULL) return r;
if (r == NULL) return l;
if (l->y > r->y) {
l->r = dt_merge(l->r,r);
return l;
} else {
r->l = dt_merge(l,r->l);
return r;
}
}
inline dt_t* dt_newnode(mkey_t x, int y, mvalue_t v) {
dt_t *t = (dt_t*) malloc(sizeof(dt_t));
t->x = x; t->y = y, t->v = v;
return t;
}
int
dt_insert(dt_t **t, mkey_t x, int y, mvalue_t v) {
dt_t *tmp;
#ifdef UNIQ_KEYS
tmp = dt_search(*t, x);
if(tmp) {
// printf("Replaced key %d value %d changed to %d\n", x, (*t)->v, v);
tmp->v = v;
return BT_UPDATED;
}
#endif
if (*t == NULL || y > (*t)->y) {
tmp = dt_newnode(x, y, v);
dt_split(*t, x, &(tmp->l), &(tmp->r));
*t = tmp;
return BT_ADDED;
} else if ( x < (*t)->x) {
return dt_insert(&((*t)->l), x, y, v);
} else {
return dt_insert(&((*t)->r), x, y, v);
}
}
int
dt_delete(dt_t **t, mkey_t x) {
if ( *t == NULL ) return BT_NOTFOUND;
if ( x < (*t)->x ) {
return dt_delete( &((*t)->l), x);
} else if ( x > (*t)->x) {
return dt_delete( &((*t)->r), x);
} else {
dt_t *tmp = *t;
*t = dt_merge((*t)->l, (*t)->r);
free(tmp);
return BT_ADDED;
}
}
dt_t* dt_left(dt_t *t) {
while(t->l != NULL) t = t->l;
return t;
}
dt_t* dt_right(dt_t *t) {
while(t->r != NULL) t = t->r;
return t;
}
- Вход: Число элементов n, а затем n строчек пар ( x , y ). Пары должны идти в порядке возрастания ключей x.
- Выход: Префиксное изображение декартового дерева.
Пример использования:
bash$ gcc ct.c -o ct
bash$ ./ct
7
0 5
1 3
2 2
3 9
4 11
5 4
6 6
(4,11)
(3,9)
(0,5)
( nil )
(1,3)
( nil )
(2,2)
( nil )
( nil )
( nil )
(6,6)
(5,4)
( nil )
( nil )
( nil )
Artem Voroztsov - 02 Aug 2006
/* file: ct.c
* Cartesian Tree
*
*/
#include <stdio.h>
#include <malloc.h>
typedef int dkey_t;
typedef struct node {
struct node *l,*r,*p;
dkey_t x;
dkey_t y;
int size;
} node_t;
int count_size(node_t *root) {
if(root) {
return (root->size = 1 + count_size(root->l) + count_size(root->r));
} else {
return 0;
}
}
node_t*
dt_new_node(dkey_t x, dkey_t y) {
node_t *node = (node_t*)calloc(1, sizeof(node_t));
node->x = x; node->y = y;
return node;
}
node_t*
dt_add_right(node_t **root, node_t *old_right, dkey_t x, dkey_t y) {
node_t *new_right = dt_new_node(x,y);
while( old_right != *root && old_right->y < y ) {
old_right = old_right->p;
}
if(old_right && old_right->y >= y) {
new_right->l = old_right->r;
old_right->r = new_right;
new_right->p = old_right;
} else {
new_right->l = *root;
*root = new_right;
}
return new_right;
}
void
prefix_traverse(node_t *root, void f(node_t*, int), int level) {
if(root) {
f(root, level);
prefix_traverse(root->l, f, level+1);
prefix_traverse(root->r, f, level+1);
} else {
f(root, level);
}
}
void print_indented(node_t *node, int level) {
int i;
for(i=0; i < level; i++) printf(" ");
if(node) printf("(%d,%d)\n", node->x, node->y);
else printf("( nil )\n");
}
int main(int argc, char *argv[])
{
int n, i, x, y;
node_t *root = 0;
node_t *left = 0;
scanf("%d", &n);
for(i = 0 ; i < n ; i++) {
scanf("%d%d", &x, &y);
left = dt_add_left( &root, left, x, y );
}
prefix_traverse(root, print_indented, 0);
count_size(root);
while(scanf("%d%d", &x, &y) == 2) {
printf("%d\n", count_lefter_and_lower(root, x, y, 0) );
}
return 0;
}