二叉排序树 -- C语言

83 篇文章 2 订阅
30 篇文章 0 订阅

数据结构

二 叉 排序 树( Binary Sort Tree) 又称 二 叉 查找 树( Binary Search Tree)。 其 定义 为: 二 叉 排序 树 或者是 空 树, 或者是 满足 如下 性 质的 二 叉 树。

(1) 若 它的 左 子 树 非 空, 则 左 子 树上 所有 节点 的 值 均 小于 根 节点 的 值。

(2) 若 它的 右 子 树 非 空, 则 右 子 树上 所有 节点 的 值 均 大于 根 节点 的 值。

(3) 左、 右 子 树 本身 又 各 是一 棵 二 叉 排序 树。 上述 性质 简称 二 叉 排序 树 性质( BST 性质), 故 二 叉 排序 树 实际上 是 满足 BST 性 质的 二 叉 树。

下图 就是 一个 简单 的 二 叉 排序 树。

首先 我们 需要 定义 节点 类 以及 二 叉 排序 树 类。 对于 节点 类 来说, 显然 每个 节点 有 向下 的 两个 指针, 而且 每个 节点 都 只有 一个 父 节点。 对于 二 叉 排序 树 类 来说, 只需 要 有数 的 根 节点, 就可以 进行 操作 了。

代码实现

#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#include "stack.h"


st_trNode * createTreeNode(int data){
	st_trNode * p = NULL;

	p = (st_trNode * ) malloc (sizeof(st_trNode));
	if(NULL ==  p){
		printf("createTreeNode alloc failed \n");
		return NULL;
	}

	p->data = data;
	p->tag = 0;
	p->left = NULL;
	p->right = NULL;
	p->parent = NULL;

	return p;
}


int createTree(st_tree ** ptree){

	st_tree * tree = NULL;

	tree = (st_tree * ) malloc (sizeof(st_tree));
	if(NULL ==  tree){
		printf("createTree alloc failed \n");
		return ALLOC_ERR;
	}

	tree->root = NULL;

	*ptree = tree;

	return SUCCESS;
}

int insertBSTNode(st_trNode ** proot, st_trNode * node){
	if(NULL == proot || NULL == node){
		printf("insertBSTNode param error\n");
		return PARAM_ERR;
	}

	st_trNode * root = *proot;	
	st_trNode * left = NULL, * right = NULL, * p = NULL;;

	/* BST的首个节点 */
	if(NULL == root){
		root = node;
#ifdef DEBUG		
		printf("1.1  root = %d\n", root->data);		
#endif
		goto out;
	}

	/*递归结束条件:叶子节点*/
	if(NULL == root->left && NULL == root->right){
#ifdef DEBUG
		printf("1.6\n");
#endif
		if(node->data < root->data)	{
			root->left = node;
			node->parent = root;
#ifdef DEBUG		
			printf("1.2  left = %d, parent = %d \n", root->left->data, node->parent->data);	
#endif
		} else {
			root->right = node;
			node->parent = root;
#ifdef DEBUG	
			printf("1.3  right = %d, parent = %d \n", root->right->data, node->parent->data);	
#endif
		}
		goto out;
	}
	
	left= root->left;
	right = root->right;

#ifdef DEBUG
	printf("1.7\n");
#endif

	/*向左子树插入*/
	if(node->data < root->data){
		if(NULL == left){
#ifdef DEBUG
			printf("1.4.1  root = %d \n", root->data);	
#endif
			root->left = node;
			node->parent = root;
		} else{
#ifdef DEBUG			
			printf("1.4.2  root = %d, left = %d \n", root->data, left->data);	
#endif
			insertBSTNode(&left, node);			
			/*左子树根可能发生变化*/
			root->left = left;
			left->parent = root;
		}
	} else { /*向右子树插入*/
		if(NULL == right){
#ifdef DEBUG			
			printf("1.5.1  root = %d \n", root->data);
#endif
			root->right = node;
			node->parent = root;
		} else {
#ifdef DEBUG	
			printf("1.5.2  root = %d, right = %d \n", root->data, right->data);	
#endif
			insertBSTNode(&right, node);
			/*右子树根可能发生变化*/
			root->right = right;
			right->parent = root;
		}		
	}
	
out:
	* proot = root;
	return SUCCESS;
	
}

int TraverseTreePreOrder(st_trNode * root){

	/*递归结束条件*/
	if(NULL == root){
		return SUCCESS;
	}

	printf(" %d ", root->data);

	/*左子树*/
	if(NULL != root->left)
		TraverseTreePreOrder(root->left);

	/*右子树*/	
	if(NULL != root->right)
		TraverseTreePreOrder(root->right);

	return SUCCESS;
}


/*
 * 对于 BST 来说,中序打印出来的是升序的
 */
int TraverseTreeInOrder(st_trNode * root){

	/*递归结束条件*/
	if(NULL == root){
		return SUCCESS;
	}

	/*左子树*/
	if(NULL != root->left)
		TraverseTreeInOrder(root->left);

	printf(" %d ", root->data);

	/*右子树*/	
	if(NULL != root->right)
		TraverseTreeInOrder(root->right);

	return SUCCESS;
}

/*
 * 对于 BST 来说,中序打印出来的是升序的
 */
int TraverseTreePostOrder(st_trNode * root){

	/*递归结束条件*/
	if(NULL == root){
		return SUCCESS;
	}

	/*左子树*/
	if(NULL != root->left)
		TraverseTreePostOrder(root->left);

	/*右子树*/	
	if(NULL != root->right)
		TraverseTreePostOrder(root->right);

	printf(" %d ", root->data);

	return SUCCESS;
}



int dumpTree(st_tree * tree){

	/*递归结束条件*/
	if(NULL == tree){
		return SUCCESS;
	}
	
#if 1
	printf("========= Dump Tree PreOder: %p ===========\n\t", tree);
	TraverseTreePreOrder(tree->root);
	printf("\n===================================\n");


	printf("========= Dump Tree PreOder UnRec: %p ===========\n\t", tree);
	TraverseTreePreOrderUnrec(tree->root);
	printf("\n===================================\n");

#endif

#if 0
	printf("========= Dump Tree InOder: %p ===========\n\t", tree);
	TraverseTreeInOrder(tree->root);
	printf("\n===================================\n");

	printf("========= Dump Tree InOderUnrec: %p ===========\n\t", tree);
	TraverseTreeInOrderUnrec(tree->root);
	printf("\n===================================\n");	
#endif

#if 0
	printf("========= Dump Tree PostOrder: %p ===========\n\t", tree);
	TraverseTreePostOrder(tree->root);
	printf("\n===================================\n");

	printf("========= Dump Tree PostOrder unRec: %p ===========\n\t", tree);
	TraverseTreePostOrderUnrec(tree->root);
	printf("\n===================================\n");	
#endif


	return SUCCESS;
}

st_trNode * SearchBSTreeNode(st_trNode * root, int data){

	if(NULL == root){
		return NULL;
	}

	st_trNode * node = NULL;
	st_trNode * left = root->left, * right = root->right;
	
	if(data == root->data){
		return root;
	}

	if(NULL == left && NULL == right){
		return NULL;
	}

	if(data < root->data){
		if(NULL == left){
			return NULL;
		} else {
			node = SearchBSTreeNode(root->left, data);
		}
	} else {
		if(NULL == right){
			return NULL;
		} else {
			node = SearchBSTreeNode(root->right, data);
		}		
	}

	return node;

}


st_trNode * getMostLeftNode(st_trNode * root){
	if(NULL == root){
		return root;
	}

	st_trNode * p = NULL;

	if(NULL == root->left){
		return root;
	}

	p = root->left;
	while(NULL != p->left){
		p = p->left;
	}

	return p;
}

int removeBSTreeNode(st_trNode ** proot, int data){
	if(NULL == proot){
		printf("removeBSTreeNode param error\n");
		return PARAM_ERR;
	}

	st_trNode * root = *proot;
	st_trNode * node = NULL;
	st_trNode * left = NULL, * right = NULL, * parent = NULL;
	st_trNode * mostsubLeft = NULL; /*右子树的最左子节点*/
	int atLeft = 0, atRight = 0;

	/* 1. 找data对应的节点 */
	node = SearchBSTreeNode(root, data);
	if(NULL == node){
		printf("removeBSTreeNode can not find %d \n", data);
		return PARAM_ERR;
	}

	left = node->left;
	right = node->right;
	parent = node->parent;

	if(NULL != right){
		mostsubLeft = getMostLeftNode(right);
	}

	/* 非根节点 */
	if(NULL != parent){

		/*1. 摘下node和它的子树*/
		if(node->data < parent->data){
			parent->left = NULL;
			node->parent = NULL;
			atLeft = 1;
		} else {
			parent->right = NULL;
			node->parent = NULL;
			atRight = 1;
		}

		/*2. 挂子树*/
		
		/*node 是叶子节点,什么也不用做 */
		if(NULL == left && NULL == right){
		}

		/*非叶子节点*/

		/*有左子没右子*/
		if(NULL != left && NULL == right){ 
			if(1 == atLeft){
				parent->left = left;
				left->parent = parent;
			}  else if(1 == atRight) {
				parent->right = left;
				left->parent = parent;
			}
		}

		/*没左子有右子*/
		if(NULL == left &&  NULL != right){ 
			if(1 == atLeft){
				parent->left = right;
				right->parent = parent;
			}  else if(1 == atRight) {
				parent->right = right;
				right->parent = parent;
			}	
		}

		/*有左子有右子, 左子挂在右子的最左边节点的左边, 右子树根节点继承原来节点位置*/
		if(NULL != left && NULL != right){
			mostsubLeft->left = left;
			left->parent = mostsubLeft;
		
			if(1 == atLeft){
				parent->left = right;
				right->parent = parent;
			}  else if(1 == atRight) {
				parent->right = right;
				right->parent = parent;
			}	
			
		}
	} else { /* 根节点 */

		/*node 是叶子节点,什么也不用做 */
		if(NULL == left && NULL == right){
			root = NULL;
		}

		/*有左子没右子*/
		if(NULL != left && NULL == right){ 
			root = left;
		}

		/*没左子有右子*/
		if(NULL == left &&  NULL != right){ 	
			root = right;
		}		

		/*没左子有右子*/
		if(NULL == left &&  NULL != right){ 
			if(1 == atLeft){
				parent->left = right;
				right->parent = parent;
			}  else if(1 == atRight) {
				parent->right = right;
				right->parent = parent;
			}	
		}

		/*有左子有右子, 左子挂在右子的最左边节点的左边, 右子树根节点继承原来节点位置*/
		if(NULL != left && NULL != right){
			mostsubLeft->left = left;
			left->parent = mostsubLeft;
			/*更新根节点*/
			root = right;			
		}
		
		*proot = root;
	}

	free(node);
	node = NULL;

	return SUCCESS;
}


void testBSTree(void){

	printf("\n************  testBSTree ************ \n");

	st_trNode * p  = NULL;
	st_trNode * root = NULL;
	st_trNode * mostLeft = NULL;

	gBSTree = NULL;	
	createTree(&gBSTree);

	root = gBSTree->root;

	printf("insert 5\n");
	p = createTreeNode(5);		
	insertBSTNode(&root, p);

	printf("insert 3\n");
	p = createTreeNode(3);
	insertBSTNode(&root, p);

	printf("insert 7\n");
	p = createTreeNode(7);
	insertBSTNode(&root, p);

	printf("insert 2\n");
	p = createTreeNode(2);
	insertBSTNode(&root, p);

	printf("insert 4\n");
	p = createTreeNode(4);
	insertBSTNode(&root, p);

	printf("insert 6\n");
	p = createTreeNode(6);
	insertBSTNode(&root, p);

	printf("insert 8\n");
	p = createTreeNode(8);
	insertBSTNode(&root, p);

	printf("insert 1\n");
	p = createTreeNode(1);
	insertBSTNode(&root, p);


	gBSTree->root = root;
	dumpTree(gBSTree);

	p = NULL;
	p = SearchBSTreeNode(gBSTree->root, 5);
	if(NULL != p){
		printf("node[%p] = %d\n", p, p->data);
	} else {
		printf("Cannot find this node\n");
	}

	p = SearchBSTreeNode(gBSTree->root, 10);
	if(NULL != p){
		printf("node[%p] = %d\n", p, p->data);
	} else {
		printf("Cannot find this node\n");
	}

	p = SearchBSTreeNode(gBSTree->root, 8);
	if(NULL != p){
		printf("node[%p] = %d\n", p, p->data);
	} else {
		printf("Cannot find this node\n");
	}

	mostLeft = getMostLeftNode(gBSTree->root);
	if(NULL != mostLeft){
		printf("mostLeft[%p] = %d\n", mostLeft, mostLeft->data);
	} else {
		printf("Null Tree\n");
	}	

	mostLeft = getMostLeftNode(gBSTree->root->right);
	if(NULL != mostLeft){
		printf("mostLeft[%p] = %d\n", mostLeft, mostLeft->data);
	} else {
		printf("Null Tree\n");
	}	


	/*删除在最后测试*/
	root = gBSTree->root;
	//removeBSTreeNode(&root, 3);
	//removeBSTreeNode(&root, 1);	
	//removeBSTreeNode(&root, 4);
	//removeBSTreeNode(&root, 7);
	//removeBSTreeNode(&root, 8); /*删除右子树*/
	removeBSTreeNode(&root, 5); /*删除根节点*/
	gBSTree->root = root;
	dumpTree(gBSTree);	

	return;
}

代码编译

gcc main.c stack.c list.c tree.c -g -o a.exe -DDEBUG

调试输出


************  testBSTree ************
insert 5
1.1  root = 5
insert 3
1.6
1.2  left = 3, parent = 5
insert 7
1.7
1.5.1  root = 5
insert 2
1.7
1.4.2  root = 5, left = 3
1.6
1.2  left = 2, parent = 3
insert 4
1.7
1.4.2  root = 5, left = 3
1.7
1.5.1  root = 3
insert 6
1.7
1.5.2  root = 5, right = 7
1.6
1.2  left = 6, parent = 7
insert 8
1.7
1.5.2  root = 5, right = 7
1.7
1.5.1  root = 7
insert 1
1.7
1.4.2  root = 5, left = 3
1.7
1.4.2  root = 3, left = 2
1.6
1.2  left = 1, parent = 2
========= Dump Tree PreOder: 0x18ba010 ===========
         5  3  2  1  4  7  6  8
===================================
========= Dump Tree PreOder UnRec: 0x18ba010 ===========
         5  3  2  1  4  7  6  8
===================================
node[0x18ba030] = 5
Cannot find this node
node[0x18ba150] = 8
mostLeft[0x18ba180] = 1
mostLeft[0x18ba120] = 6
========= Dump Tree PreOder: 0x18ba010 ===========
         7  6  3  2  1  4  8
===================================
========= Dump Tree PreOder UnRec: 0x18ba010 ===========
         7  6  3  2  1  4  8
===================================

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值