⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bt_code.c

📁 b树的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		NODES(btr, s)[0] = r;		btreesplitchild(btr, s, 0, r);		r = s;	}	/* finally insert the new node */	btreeinsertnonfull(btr, r, k);}static voidbtreeinsertnonfull(struct btree *btr, struct btreenode *x, bt_data_t k){	int i;	i = x->n - 1;	if (x->leaf) {		/* we are a leaf, just add it in */		i = findkindex(btr, x, k, NULL);		if (i != x->n - 1)			memmove(KEYS(btr, x) + i + 2, KEYS(btr, x) + i + 1,			    (x->n - i - 1) * sizeof k);		KEYS(btr, x)[i + 1] = k;		x->n++;	} else {		i = findkindex(btr, x, k, NULL) + 1;		/* make sure that the next node isn't full */		if (NODES(btr, x)[i]->n == 2 * btr->t - 1) {			btreesplitchild(btr, x, i, NODES(btr, x)[i]);			if (btr->cmp(k, KEYS(btr, x)[i]) > 0)				i++;		}		btreeinsertnonfull(btr, NODES(btr, x)[i], k);	}}bt_data_tbt_delete(struct btree *btr, bt_data_t k){	struct btreenode *x;	bt_data_t r;	r = nodedeletekey(btr, btr->root, k, 0);	/*	 * remove an empty, non-leaf node from root, this is the ONLY	 * place that a tree can decrease in height	 */	if (btr->root->n == 0 && btr->root->leaf == 0) {#ifdef STATS		btr->numnodes--;#endif		x = btr->root;		btr->root = NODES(btr, x)[0];		free(x);	}	return r;}/* * remove an existing key from the tree, if the key doesn't exist in it, * unexpected results may happen. * * the s parameter is kinda special, for normal operation you need to pass * it as 0, if you want to delete the max node, pass it as 1, or if you * want to delete the min node, pass it as 2. */static bt_data_tnodedeletekey(struct btree *btr, struct btreenode *x, bt_data_t k, int s){	int i;	int r;	struct btreenode *xp, *y, *z;	bt_data_t kp;	int yn, zn;	if (x == NULL)		return 0;	if (s) {		if (!x->leaf)			switch (s) {			case 1:				r = 1;				break;			case 2:				r = -1;				break;			}		else			r = 0;		switch (s) {		case 1:			i = x->n - 1;			break;		case 2:			i = -1;			break;		default:			i = 42;			break;		}	} else		i = findkindex(btr, x, k, &r);	/*	 * Case 1	 * If the key k is in node x and x is a leaf, delete the key k from x.	 */	if (x->leaf) {		if (s == 2)			i++;		kp = KEYS(btr, x)[i];		memmove(KEYS(btr, x) + i, KEYS(btr, x) + i + 1,		    (x->n - i - 1) * sizeof k);		x->n--;		return kp;	}	if (r == 0) {		/*		 * Case 2		 * if the key k is in the node x, and x is an internal node		 */		if ((yn = NODES(btr, x)[i]->n) >= btr->t) {			/*			 * Case 2a			 * if the child y that precedes k in node x has at			 * least t keys, then find the predecessor k' of			 * k in the subtree rooted at y.  Recursively delete			 * k', and replace k by k' in x.			 *			 * Currently the deletion isn't done in a signle			 * downward pass was that would require special			 * unwrapping of the delete function.			 */			xp = NODES(btr, x)[i];			kp = KEYS(btr, x)[i];			KEYS(btr, x)[i] = nodedeletekey(btr, xp, NULL, 1);			return kp;		}		if ((zn = NODES(btr, x)[i + 1]->n) >= btr->t) {			/*			 * Case 2b			 * if the child z that follows k in node x has at			 * least t keys, then find the successor k' of			 * k in the subtree rooted at z.  Recursively delete			 * k', and replace k by k' in x.			 *			 * See above for comment on single downward pass.			 */			xp = NODES(btr, x)[i + 1];			kp = KEYS(btr, x)[i];			KEYS(btr, x)[i] = nodedeletekey(btr, xp, NULL, 2);			return kp;		}		if (yn == btr->t - 1 && zn == btr->t - 1) {			/*			 * Case 2c			 * if both y and z have only t - 1 keys, merge k			 * and all of z into y, so that x loses both k and			 * the pointer to z, and y now contains 2t - 1			 * keys.  Recersively delete k from y.			 */			y = NODES(btr, x)[i];			z = NODES(btr, x)[i + 1];			KEYS(btr, y)[y->n++] = k;			memmove(KEYS(btr, y) + y->n, KEYS(btr, z),			    z->n * sizeof k);			memmove(NODES(btr, y) + y->n, NODES(btr, z),			    (z->n + 1) * sizeof y);			y->n += z->n;			memmove(KEYS(btr, x) + i, KEYS(btr, x) + i + 1,			    (x->n - i - 1) * sizeof k);			memmove(NODES(btr, x) + i + 1, NODES(btr, x) + i + 2,			    (x->n - i - 1) * sizeof k);			x->n--;			z = freebtreenode(z);			return nodedeletekey(btr, y, k, s);		}	}	/*	 * Case 3	 * if k is not present in internal node x, determine the root x' of	 * the appropriate subtree that must contain k, if k is in the tree	 * at all.  If x' has only t - 1 keys, execute step 3a or 3b as	 * necessary to guarantee that we descend to a node containing at	 * least t keys.  Finish by recursing on the appropriate child of x.	 */	i++;	/* !x->leaf */	if ((xp = NODES(btr, x)[i])->n == btr->t - 1) {		/*		 * Case 3a		 * If x' has only t - 1 keys but has a sibling with at		 * least t keys, give x' an extra key by moving a key		 * from x down into x', moving a key from x''s immediate		 * left or right sibling up into x, and moving the		 * appropriate child from the sibling into x'.		 */		if (i > 0 && (y = NODES(btr, x)[i - 1])->n >= btr->t) {			/* left sibling has t keys */			memmove(KEYS(btr, xp) + 1, KEYS(btr, xp),			    xp->n * sizeof k);			memmove(NODES(btr, xp) + 1, NODES(btr, xp),			    (xp->n + 1) * sizeof x);			KEYS(btr, xp)[0] = KEYS(btr, x)[i - 1];			KEYS(btr, x)[i - 1] = KEYS(btr, y)[y->n - 1];			NODES(btr, xp)[0] = NODES(btr, y)[y->n];			y->n--;			xp->n++;		} else if (i < x->n &&		    (y = NODES(btr, x)[i + 1])->n >= btr->t) {			/* right sibling has t keys */			KEYS(btr, xp)[xp->n++] = KEYS(btr, x)[i];			KEYS(btr, x)[i] = KEYS(btr, y)[0];			NODES(btr, xp)[xp->n] = NODES(btr, y)[0];			y->n--;			memmove(KEYS(btr, y), KEYS(btr, y) + 1,			    y->n * sizeof k);			memmove(NODES(btr, y), NODES(btr, y) + 1,			    (y->n + 1) * sizeof x);		}		/*		 * Case 3b		 * If x' and all of x''s siblings have t - 1 keys, merge		 * x' with one sibling, which involves moving a key from x		 * down into the new merged node to become the median key		 * for that node.		 */		  else if (i > 0 &&		    (y = NODES(btr, x)[i - 1])->n == btr->t - 1) {			/* merge i with left sibling */			KEYS(btr, y)[y->n++] = KEYS(btr, x)[i - 1];			memmove(KEYS(btr, y) + y->n, KEYS(btr, xp),			    xp->n * sizeof k);			memmove(NODES(btr, y) + y->n, NODES(btr, xp),			    (xp->n + 1) * sizeof x);			y->n += xp->n;			memmove(KEYS(btr, x) + i - 1, KEYS(btr, x) + i,			    (x->n - i) * sizeof k);			memmove(NODES(btr, x) + i, NODES(btr, x) + i + 1,			    (x->n - i) * sizeof x);			x->n--;			free(xp);			xp = y;		} else if (i < x->n && (y = NODES(btr, x)[i + 1])->n ==		    btr->t - 1) {			/* merge i with right sibling */			KEYS(btr, xp)[xp->n++] = KEYS(btr, x)[i];			memmove(KEYS(btr, xp) + xp->n, KEYS(btr, y),			    y->n * sizeof k);			memmove(NODES(btr, xp) + xp->n, NODES(btr, y),			    (y->n + 1) * sizeof x);			xp->n += y->n;			memmove(KEYS(btr, x) + i, KEYS(btr, x) + i + 1,			    (x->n - i - 1) * sizeof k);			memmove(NODES(btr, x) + i + 1, NODES(btr, x) + i + 2,			    (x->n - i - 1) * sizeof x);			x->n--;			free(y);		}	}	return nodedeletekey(btr, xp, k, s);}static struct btreenode *freebtreenode(struct btreenode *x){	return FREE(x);}bt_data_tbt_max(struct btree *btr){	return findmaxnode(btr, btr->root);}bt_data_tbt_min(struct btree *btr){	return findminnode(btr, btr->root);}static bt_data_tfindmaxnode(struct btree *btr, struct btreenode *x){	if (x->leaf)		return KEYS(btr, x)[x->n - 1];	else		return findmaxnode(btr, NODES(btr, x)[x->n]);}static bt_data_tfindminnode(struct btree *btr, struct btreenode *x){	if (x->leaf)		return KEYS(btr, x)[0];	else		return findminnode(btr, NODES(btr, x)[0]);}bt_data_tbt_find(struct btree *btr, bt_data_t k){	return findnodekey(btr, btr->root, k);}static bt_data_tfindnodekey(struct btree *btr, struct btreenode *x, bt_data_t k){	int i;	int r;	while (x != NULL) {		/*(for (i = 0; i < x->n && (r = btr->cmp(k, KEYS(btr, x)[i])) > 0;		    i++);*/		i = findkindex(btr, x, k, &r);		if (i >= 0 && r == 0)			return KEYS(btr, x)[i];		if (x->leaf)			return NULL;		x = NODES(btr, x)[i + 1];	}	return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -