int hb_itor_prev(hb_itor *itor) { ASSERT(itor != NULL); if (itor->node == NULL) hb_itor_last(itor); else itor->node = node_prev(itor->node); RETVALID(itor); }
STATIC VOID MultiString_Event(void **msg) { /* struct IClass *cl = (struct IClass*)msg[0];*/ Object *obj = (Object*)msg[1]; struct object_node *obj_node = (struct object_node*)msg[2]; Object *window = (Object*)xget(obj,MUIA_WindowObject); int event = (int)msg[3]; if (event == MUIV_SingleString_Event_CursorUp && node_prev(&obj_node->node)) { set(window, MUIA_Window_ActiveObject, ((struct object_node*)node_prev(&obj_node->node))->obj); return; } if (event == MUIV_SingleString_Event_CursorDown && node_next(&obj_node->node)) { set(window, MUIA_Window_ActiveObject, ((struct object_node*)node_next(&obj_node->node))->obj); return; } if (event == MUIV_SingleString_Event_ContentsToPrevLine && node_prev(&obj_node->node)) { struct object_node *prev_node = (struct object_node*)node_prev(&obj_node->node); char *contents = (char*)xget(obj_node->obj, MUIA_UTF8String_Contents); int new_cursor_pos = strlen((char*)xget(prev_node->obj, MUIA_String_Contents)); /* is Okay */ DoMethod(prev_node->obj, MUIM_UTF8String_Insert, (ULONG)contents, MUIV_BetterString_Insert_EndOfString); set(prev_node-> obj,MUIA_String_BufferPos, new_cursor_pos); set(window, MUIA_Window_ActiveObject, prev_node->obj); node_remove(&obj_node->node); DoMethod(obj, MUIM_Group_InitChange); DoMethod(obj, OM_REMMEMBER, (ULONG)obj_node->obj); MUI_DisposeObject(obj_node->obj); free(obj_node); DoMethod(obj, MUIM_Group_ExitChange); return; } }
static ret_t node_check (chula_avl_generic_node_t *node) { int32_t left_height; int32_t right_height; int32_t balance; chula_avl_generic_node_t *tmp; if (node == NULL) return ret_ok; if (node->left_child) { tmp = node_prev (node); if (tmp->right != node) { chula_log_error ("AVL Tree inconsistency: Right child"); return ret_error; } } if (node->right_child) { tmp = node_next (node); if (tmp->left != node) { chula_log_error ("AVL Tree inconsistency: Left child"); return ret_error; } } left_height = 0; right_height = 0; if (node->left_child) left_height = node_height (node->left); if (node->right_child) right_height = node_height (node->right); balance = right_height - left_height; if (balance != node->balance) { chula_log_error ("AVL Tree inconsistency: Balance"); return ret_error; } if (node->left_child) node_check (node->left); if (node->right_child) node_check (node->right); return ret_ok; }
static ret_t node_check (http2d_avl_generic_node_t *node) { cint_t left_height; cint_t right_height; cint_t balance; http2d_avl_generic_node_t *tmp; if (node == NULL) return ret_ok; if (node->left_child) { tmp = node_prev (node); if (tmp->right != node) { LOG_ERROR_S (HTTP2D_ERROR_AVL_PREVIOUS); return ret_error; } } if (node->right_child) { tmp = node_next (node); if (tmp->left != node) { LOG_ERROR_S (HTTP2D_ERROR_AVL_NEXT); return ret_error; } } left_height = 0; right_height = 0; if (node->left_child) left_height = node_height (node->left); if (node->right_child) right_height = node_height (node->right); balance = right_height - left_height; if (balance != node->balance) { LOG_ERROR_S (HTTP2D_ERROR_AVL_BALANCE); return ret_error; } if (node->left_child) node_check (node->left); if (node->right_child) node_check (node->right); return ret_ok; }
int hb_itor_prevn(hb_itor *itor, unsigned count) { ASSERT(itor != NULL); if (count) { if (itor->node == NULL) { hb_itor_last(itor); count--; } while (count-- && itor->node) itor->node = node_prev(itor->node); } RETVALID(itor); }
int main(int argc, char** argv) { printf("testing bintree\n"); node na,nb,nc,nd; init_node(&na,"Anchor"); init_node(&nb,"Bunk"); init_node(&nc,"Corgi"); init_node(&nd,"Dapper"); node_add_child(&nb,&nd,comp_string); node_add_child(&nb,&nc,comp_string); node_add_child(&nb,&na,comp_string); printf("heythere\n"); printf("%x: %x, %x\n",nb.data,nb.left,nb.right); printf("%s: %s, %s\n",nb.data,((bintree_node*)nb.left)->data,((bintree_node*)nb.right)->data); printf("%s: %s, %s\n",nd.data,((bintree_node*)nd.left)->data,(nd.right ? ((bintree_node*)nd.right)->data : 0)); bintree_node* ns[] = {&na,&nb,&nc,&nd}; int i; for (i=0; i<4; ++i) { #define ndata(a,b) ((bintree_node*)a->b)->data printf("<%s: (%s) %s, %s, %i>\n", (ns[i]->data ? ns[i]->data : 0), (ns[i]->parent ? ndata(ns[i],parent) : 0), (ns[i]->left ? ndata(ns[i],left) : 0), (ns[i]->right ? ndata(ns[i],right) : 0), ns[i]->weight); } bintree_node* n = &na; printf("testing node_next\n"); do { printf("- %s\n",n->data); } while ((n = node_next(n))); n = &nd; printf("testing node_prev\n"); do { printf("- %s\n",n->data); } while ((n = node_prev(n))); #undef ndata #ifdef mtrace_active mtrace(); #endif bintree* b = new_bintree(comp_string); del_bintree(b,DEL_STRUCT); b = new_bintree(comp_string); bintree_add(b,"Brawn"); bintree_add(b,"Dour"); bintree_add(b,"Court"); bintree_add(b,"Acclamate"); char* s; void* h = iter_bintree(b); while (s = iter_bintree_next(&h)) printf("%s\n",s); h = iter_bintree(b); while (s = iter_bintree_next(&h)) printf("%s\n",bintree_contains(b,s)); del_bintree(b,DEL_STRUCT); #ifdef mtrace_active muntrace(); #endif return 0; }
ret_t chula_avl_generic_del (chula_avl_generic_t *avl, chula_avl_generic_node_t *key, void **value) { short re; bool is_left; chula_avl_generic_node_t *path[MAX_HEIGHT]; chula_avl_generic_node_t *parent; chula_avl_generic_node_t *pbalance; chula_avl_generic_node_t *node = avl->root; int32_t idx = 1; if (unlikely (avl->node_is_empty (key))) return ret_error; if (avl->root == NULL) return ret_not_found; path[0] = NULL; while (true) { re = avl->node_cmp (key, node, avl); if (re == 0) { if (value) *value = node->value; break; } else if (re < 0) { if (!node->left_child) return ret_not_found; path[idx++] = node; node = node->left; } else { if (!node->right_child) return ret_not_found; path[idx++] = node; node = node->right; } } pbalance = path[idx-1]; parent = pbalance; idx -= 1; is_left = (parent && (node == parent->left)); if (!node->left_child) { if (!node->right_child) { if (!parent) avl->root = NULL; else if (is_left) { parent->left_child = false; parent->left = node->left; parent->balance += 1; } else { parent->right_child = false; parent->right = node->right; parent->balance -= 1; } } else { /* right child */ chula_avl_generic_node_t *tmp = node_next (node); tmp->left = node->left; if (!parent) avl->root = node->right; else if (is_left) { parent->left = node->right; parent->balance += 1; } else { parent->right = node->right; parent->balance -= 1; } } } else { /* left child */ if (!node->right_child) { chula_avl_generic_node_t *tmp = node_prev(node); tmp->right = node->right; if (parent == NULL) avl->root = node->left; else if (is_left) { parent->left = node->left; parent->balance += 1; } else { parent->right = node->left; parent->balance -= 1; } } else { /* both children */ chula_avl_generic_node_t *prev = node->left; chula_avl_generic_node_t *next = node->right; chula_avl_generic_node_t *nextp = node; int32_t old_idx = idx + 1; idx++; /* find the immediately next node (and its parent) */ while (next->left_child) { path[++idx] = nextp = next; next = next->left; } path[old_idx] = next; pbalance = path[idx]; /* remove 'next' from the tree */ if (nextp != node) { if (next->right_child) nextp->left = next->right; else nextp->left_child = false; nextp->balance += 1; next->right_child = true; next->right = node->right; } else { node->balance -= 1; } /* set the prev to point to the right place */ while (prev->right_child) prev = prev->right; prev->right = next; /* prepare 'next' to replace 'node' */ next->left_child = true; next->left = node->left; next->balance = node->balance; if (!parent) avl->root = next; else if (is_left) parent->left = next; else parent->right = next; } } /* restore balance */ if (pbalance) { while (true) { chula_avl_generic_node_t *bparent = path[--idx]; is_left = (bparent && (pbalance == bparent->left)); if(pbalance->balance < -1 || pbalance->balance > 1) { pbalance = node_balance (pbalance); if (!bparent) avl->root = pbalance; else if (is_left) bparent->left = pbalance; else bparent->right = pbalance; } if (pbalance->balance != 0 || !bparent) break; if (is_left) bparent->balance += 1; else bparent->balance -= 1; pbalance = bparent; } } node_free (node, avl); return ret_ok; }
avl_tree_node_t *avl_tree_node_prev(avl_tree_node_t *n) { return node_prev(n); }