二叉搜索树

/*
 * Copyright 2014 YU Heng-yang. All rights reserved.
 *  
 * binary_tree.c - Binary Search Tree.
 *
 * Modify key to any other types as you like, note also the
 *  prototype of the interface functions and key compare
 *  function.
 *
 * 2014-7-6 YU Heng-yang.
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define ALLOC(size) malloc(size)
#define FREE(p)     free(p)

typedef struct BinTree *BinTree;
struct BinTree {
	int key;
	BinTree left, right;
};

BinTree bintree_new(void);
BinTree bintree_insert(BinTree  t, int key);
BinTree bintree_remove(BinTree  t, int key);
BinTree bintree_find(BinTree  t, int key);
BinTree bintree_destroy(BinTree  t);
void bintree_traversal(BinTree  t, void (*apply) (BinTree , void *arg),
		       void *arg);

void print(BinTree  t, void *arg)
{
	assert(arg);
	printf((char *)arg, t->key);
}

int main(int argc, char *argv[])
{
#define N 6

	int n, i;
	BinTree tree = bintree_new();

	/* insert */
	for (i = 0; i < N; i++) {
		scanf("%d", &n);
		tree = bintree_insert(tree, n);
		printf("After insert %d: ", n);
		bintree_traversal(tree, print, "%d ");
		putchar('\n');
	}

	/* find */
	for (i = 0; i < N; i++) {
		scanf("%d", &n);
		printf("%s\n", bintree_find(tree, n) ? "Found" : "Not Found");
	}

	/* remove */
	for (i = 0; i < N; i++) {
		scanf("%d", &n);
		tree = bintree_remove(tree, n);
		printf("After remove %d: ", n);
		bintree_traversal(tree, print, "%d ");
		putchar('\n');
	}

	tree = bintree_destroy(tree);
	assert(NULL == tree);
	bintree_traversal(tree, print, "");
	assert(NULL == bintree_find(tree, -100));
	assert(NULL == bintree_remove(tree, 100));
	return 0;
}

BinTree bintree_new(void)
{
	return NULL;
}

BinTree bintree_insert(BinTree  t, int key)
{
	if (NULL == t) {
		BinTree tree = ALLOC(sizeof(*tree));
		tree->left = tree->right = NULL;
		tree->key = key;
		t = tree;
	} else if (t->key < key)
		t->right = bintree_insert(t->right, key);
	else if (t->key > key)
		t->left = bintree_insert(t->left, key);

	return t;
}

BinTree bintree_remove(BinTree  t, int key)
{
	if (t) {
		if (t->key < key)
			t->right = bintree_remove(t->right, key);
		else if (t->key > key)
			t->left = bintree_remove(t->left, key);
		else {
			/* draw a picture and you will have the insight */
			BinTree largest;

			if (t->left && t->right) {
				/* find the left subintree's largest element */
				BinTree *plargest;
				for (plargest = &t->left; (*plargest)->right; plargest = &(*plargest)->right) 
                                        ;
				largest = *plargest;
				*plargest = NULL;
				largest->left = t->left;
				largest->right = t->right;
			} else if (!t->left)
				largest = t->right;
			else
				largest = t->left;

			FREE(t);
			return largest;

		}
	}

	return t;
}

BinTree bintree_find(BinTree  t, int key)
{
	if (t) {
		if (t->key > key)
			return bintree_find(t->left, key);
		if (t->key < key)
			return bintree_find(t->right, key);
	}
	return t;
}

void bintree_traversal(BinTree  t, void (*apply) (BinTree , void *arg),
		       void *arg)
{
	if (t) {
		bintree_traversal(t->left, apply, arg);
		apply(t, arg);
		bintree_traversal(t->right, apply, arg);
	}
}

static void bintree_do_destroy(BinTree  t)
{
	if (t) {
		bintree_do_destroy(t->left);
		bintree_do_destroy(t->right);
		t->left = t->right = NULL;
		FREE(t);
	}
}

BinTree bintree_destroy(BinTree  t)
{
	bintree_do_destroy(t);
	return NULL;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值