二叉查找树

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;

typedef struct treeItem {
	ElementType e;
	struct treeItem *left;
	struct treeItem *right;
} TreeItem;

typedef TreeItem *Tree;

TreeItem *Find(Tree t, ElementType e)
{
// 	if (t == NULL)
// 		return NULL;
// 	else if (e < t->e)
// 		return Find(t->left, e);
// 	else if (e > t->e)
// 		return Find(t->right, e);
// 	else
// 		return t;

// 	if (t == NULL || e == t->e) 
// 		return t;
// 	else if (e < t->e)
// 		return Find(t->left, e);
// 	else 
// 		return Find(t->right, e);

	while (t != NULL && e != t->e) {
		if (e < t->e)
			t = t->left;
		else/* if (e > t->e) */
			t = t->right;
	}

	return t;
}

TreeItem *FindMin(Tree t)
{
// 	if (t == NULL)
// 		return NULL;
// 	else if (t->left == NULL) // 注意递归结束条件
// 		return t;
// 	else
// 		return FindMin(t->left);

	while (t && t->left) {
		t = t->left;
	}

	return t;
}

void PreorderTraversal(Tree t)
{
	if (t != NULL) {
		printf("%d\t", t->e);
		PreorderTraversal(t->left);
		PreorderTraversal(t->right);
	}
}

void InorderTraversal(Tree t)
{
	if (t != NULL) {
		InorderTraversal(t->left);
		printf("%d\t", t->e);
		InorderTraversal(t->right);
	}
}

void PostorderTraversal(Tree t)
{
	if (t != NULL) {
		printf("%d\t", t->e);
		PostorderTraversal(t->left);
		PostorderTraversal(t->right);
	}
}

// search tree
Tree STreeInsert(Tree t, ElementType e)
{
	if (t == NULL) { // 找到出入的位置进行插入
		t = (TreeItem *)malloc(sizeof(TreeItem));
		if (!t) {
			printf("malloc error\n");
			return NULL;
		}
		t->e = e;
		t->left = t->right = NULL;	
	} else if (e < t->e) { // 当插入元素小于根时,插入左边
		t->left = STreeInsert(t->left, e);
	} else { 
		t->right = STreeInsert(t->right, e);
	}

	return t;
}

Tree STreeDelete(Tree t, ElementType e)
{
 	TreeItem *px;	
	
	if (t == NULL) {
		printf("the tree is empty!\n");
	} else if (e < t->e) {
		t->left = STreeDelete(t->left, e);
	} else if (e > t->e) {
		t->right = STreeDelete(t->right, e);
	} else if (t->left && t->right) { // 有两个孩子
		px = FindMin(t->right);
		t->e = px->e;
		t->right = STreeDelete(t->right, t->e);
	} else { // 只有一个孩子或没有孩子
		px = t;
		if (t->left == NULL)
			t = t->right; 
		else if (t->right == NULL)
			t = t->left;
		free(px);
	}
	
	return t;
}

// 非递归的插入
Tree STreeInsert1(Tree t, ElementType e)
{
	TreeItem *p = (TreeItem *)malloc(sizeof(TreeItem));
	if (!p) {
		printf("malloc error\n");
		return NULL;
	}
	p->e = e;
	p->left = p->right = NULL;	

	TreeItem *px = t;
	TreeItem *py = NULL; // 保存父节点

	while (px) { // 找到插入点
		py = px;
		if (e < px->e)
			px = px->left;
		else
			px = px->right;
	}

	if (!py)
		t = p;
	else if (e < py->e)
		py->left = p;
	else
		py->right = p;

	return t;
}

// 非递归的删除
Tree STreeDelete1(Tree t, ElementType e)
{
	TreeItem *px = t;
	TreeItem *py = NULL; // 记录父节点

	while (px && e != px->e) { // 找到删除点
		py = px;
		if (e < px->e)
			px = px->left;
		else // e > px->e
			px = px->right;
	}

	if (!px) { 
		printf("该元素不存在!\n");
		return NULL;
	}

	if (px->left == NULL) { // 最多只有一个孩子
		if (py == NULL) {   // 考虑父节点为空的情况
			t = px->right;
		} else {            // 确定左孩子还是右孩子
			if (py->left == px)
				py->left = px->right;
			else
				py->right = px->right;
		}
	} else  if(px->right == NULL) {
		if (py == NULL) {
			t = px->left;
		} else {
			if (py->left == px)
				py->left = px->left;
			else
				py->right = px->left;
		}
	} else {  // 有两个孩子
		TreeItem *p = px; // 记录当前节点
		TreeItem *pc = px->right;

		while (pc->left) { // 找出右树最小节点
			p = pc;
			pc = pc->left;
		}
		// 对孩子进行处理
		if (pc == p->right)
			p->right = pc->right;
		else 
			p->left = pc->right;
		// 用pc替换掉px
		pc->left = px->left;
		pc->right = px->right;
		// 确定父节点
		if (py == NULL) {
			t = pc;
		} else {
			if (py->left == px) 
				py->left = pc;
			else 
				py->right = pc;
		}
	}
	free(px);

	return t;
}

#define BUFSIZE 10

int main()
{
	int arr[BUFSIZE] = {12, 9, 34, 7, 4, 76, 123, 45, 2, 86};
	Tree t = NULL;

	printf("insert element:\n");
	for (int i = 0; i < BUFSIZE; i++) {
		t = STreeInsert1(t, arr[i]);
		InorderTraversal(t);
		printf("\n");
	}

	printf("delete element:\n");
	for (int i = 0; i < BUFSIZE; i++) {
		t = STreeDelete1(t, arr[i]);
		InorderTraversal(t);
		printf("\n");
	}

	getchar();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值