算法导论复习:第十二章

二叉搜索树的实现:

备注:算法导论中文版第168页中删除节点时候,y=TREE_MINIMUM(z.right)是错误的,应该寻找后继结点,为y=TREE_SUCCESSOR(z.right).

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

typedef struct TREE{
	int						data;
	struct TREE			*lchild;
	struct TREE			*rchild;
	struct TREE			*parent;
} Tree;

//中序遍历
void		inorderTreeWalk( Tree *tree );
//在二叉搜索树中进行查找
Tree		*treeSearch( Tree *tree, int value );
//返回二叉搜索树的最小值
Tree		*treeMinimum( Tree *tree );
//返回二叉搜索树的最大值
Tree		*treeMaximum( Tree *tree );
//返回指定节点的后继结点(结点x的后继是大于x.key的最小关键字的结点)
Tree		*treeSuccessor( Tree *x );
//返回指定节点的前驱结点(结点x的前驱是小于x.key的最大关键字的结点)
Tree		*treePrev( Tree *x );
//插入结点
void		treeInsert( Tree *tree, int value );
//删除结点
int			treeDelete( Tree *tree, int value );
//将树v替换为树u
void		transplant( Tree *tree, Tree *u, Tree *v );

int main( void )
{
	int		i = 0;
	Tree *tree = ( Tree * )malloc( sizeof( Tree ) );
	tree->data = INT_MIN;
	tree->lchild = tree->rchild = tree->parent = NULL;

	treeInsert( tree, 6 );
	treeInsert( tree, 3 );
	treeInsert( tree, 8 );
	treeInsert( tree, 1 );
	treeInsert( tree, 5 );
	treeInsert( tree, 7 );
	treeInsert( tree, 9 );
	treeInsert( tree, 0 );
	treeInsert( tree, 2 );
	treeInsert( tree, 4 );

	printf("the tree is:\n");
	//设计为root结点的右孩子指向这棵树
	inorderTreeWalk( tree->rchild );

	if ( treeSearch( tree->rchild, 12 ) ){
		printf("\n12 is in the tree.\n");
	}
	else{
		printf("\n12 is not in the tree\n");
	}

	printf("the tree minimum number is: %d\n", treeMinimum( tree->rchild )->data );
	printf("the tree maximum number is: %d\n", treeMaximum( tree->rchild )->data );

	for ( i = 5; i < 9; i++ ){
		treeDelete( tree, i );
	}
	printf("after delete element 5~8, the tree is:\n");
	inorderTreeWalk( tree->rchild );

	return 0;
}

void		inorderTreeWalk( Tree *tree )
{
	if ( NULL != tree ){
		inorderTreeWalk( tree->lchild );
		printf("%d ", tree->data );
		inorderTreeWalk( tree->rchild );
	}
}

Tree		*treeSearch( Tree *tree, int value )
{
	if ( NULL == tree || tree->data == value ){
		return tree;
	}
	if ( value < tree->data ){
		return treeSearch( tree->lchild, value );
	}
	else{
		return treeSearch( tree->rchild, value );
	}
}

Tree			*treeMinimum( Tree *tree )
{
	while ( NULL != tree->lchild ){
		tree = tree->lchild;
	}

	return tree;
}

Tree			*treeMaximum( Tree *tree )
{
	while ( NULL != tree->rchild ){
		tree = tree->rchild;
	}

	return tree;
}

Tree		*treeSuccessor( Tree *x )
{
	Tree *y = ( Tree * )malloc( sizeof( Tree ) );
	if ( NULL != x->rchild ){
		return treeMinimum( x->rchild );
	}
	y = x->parent;
	
	while ( NULL != y && x == y->rchild ){
		x = y;
		y = y->parent;
	}

	return y;
}

Tree		*treePrev( Tree *x )
{
	Tree *y = ( Tree * )malloc( sizeof( Tree ) );
	if ( NULL != x->lchild ){
		return treeMaximum( x->lchild );
	}

	y = x->parent;
	while ( NULL != y && x == y->lchild ){
		x = y;
		y = y->parent;
	}

	return y;
}

void		treeInsert( Tree *tree, int value )
{
	Tree *newNode = ( Tree * )malloc( sizeof( Tree ) );
	newNode->data = value;
	newNode->lchild = newNode->rchild = newNode->parent = NULL;

	if ( NULL == tree->rchild ){
		tree->lchild = tree->rchild = newNode;
	}
	else{
		Tree *prevNode = ( Tree * )malloc( sizeof( Tree ) );
		tree = tree->rchild;
		prevNode = tree;
		while ( NULL != tree ){
			prevNode = tree;
			if ( value < tree->data ){
				tree = tree->lchild;
			}
			else{
				tree = tree->rchild;
			}
		}
		newNode->parent = prevNode;
		if ( newNode->data < prevNode->data ){
			prevNode->lchild = newNode;
		}
		else{
			prevNode->rchild = newNode;
		}
	}
}

int			treeDelete( Tree *tree, int value )
{
	Tree *deleteNode = ( Tree * )malloc( sizeof( Tree ) );
	deleteNode = treeSearch( tree->rchild, value );

	if ( NULL == deleteNode ){
		return 0;
	}
	if ( NULL == deleteNode->lchild ){
		transplant( tree, deleteNode, deleteNode->rchild );
	}
	else if ( NULL == deleteNode->rchild ){
		transplant( tree, deleteNode, deleteNode->lchild );
	}
	else{
		Tree *y = ( Tree * )malloc( sizeof( Tree ) );
		y = treeSuccessor( deleteNode );
		if ( deleteNode != y->parent ){
			transplant( tree, y, y->rchild );
			y->rchild = deleteNode->rchild;
			y->rchild->parent = y;
		}
		transplant( tree, deleteNode, y );
		y->lchild = deleteNode->lchild;
		y->lchild->parent = y;
	}

	return 1;
}

void		transplant( Tree *tree, Tree *u, Tree *v )
{
	if ( NULL == u->parent ){
		tree->rchild = tree->lchild = v;
	}
	else if ( u == u->parent->lchild ){
		u->parent->lchild = v;
	}
	else{
		u->parent->rchild = v;
	}
	if ( NULL != v ){
		v->parent = u->parent;
	}
}



程序输出:

用随机产生的数来构建二叉搜索树,main函数如下:

int main( void )
{
	int		i = 0;
	Tree *tree = ( Tree * )malloc( sizeof( Tree ) );
	tree->data = INT_MIN;
	tree->lchild = tree->rchild = tree->parent = NULL;

	srand( ( unsigned int )time( NULL ) );
	for ( i = 0; i < 10; i++ ){
		treeInsert( tree, rand() % 20 );
	}

	printf("the tree is:\n");
	//设计为root结点的右孩子指向这棵树
	inorderTreeWalk( tree->rchild );

	if ( treeSearch( tree->rchild, 12 ) ){
		printf("\n12 is in the tree.\n");
	}
	else{
		printf("\n12 is not in the tree\n");
	}

	printf("the tree minimum number is: %d\n", treeMinimum( tree->rchild )->data );
	printf("the tree maximum number is: %d\n", treeMaximum( tree->rchild )->data );

	for ( i = 5; i < 9; i++ ){
		treeDelete( tree, i );
	}
	printf("after delete element 5~8, the tree is:\n");
	inorderTreeWalk( tree->rchild );

	return 0;
}



程序输出:

为什么6没被删除呢?实际上有两个6,删除了其中的一个.一般的二叉搜索树是不允许重复的.如果重复,则删除节点的操作+插入的操作都得重新修改.


转载于:https://my.oschina.net/voler/blog/190506

目录(Table of Contents)   前言(Preface)   第一部分(Part I) 基础(Foundations)   第一章 计算中算法的角色(The Role of Algorithms in Computing)   第二章 开始(Getting Started)   第三章 函数的增长率(Growth of Functions)   第四章 递归(Recurrences)   第五章 概率分析随机化算法(Probabilistic Analysis and Randomized Algorithms)   第二部分(Part II) 排序顺序统计(Sorting and Order Statistics)   第六章 堆排序(Heapsort)   第七章 快速排序(Quicksort)   第八章 线性时间中的排序(Sorting in Linear Time)   第九章 中值顺序统计(Medians and Order Statistics)   第三部分(Part III) 数据结构(Data Structures)   第十章 基本的数据结构(Elementary Data Structures)   第十一章 散列表(Hash Tables)   第十二章 二叉查找树(Binary Search Trees)   第十三章 红-黑树(Red-Black Trees)   第十四章 扩充的数据结构(Augmenting Data Structures)   第四部分(Part IV) 高级的设计分析技术(Advanced Design and Analysis Techniques)   第十五章 动态规划(Dynamic Programming)   第十六章 贪婪算法(Greedy Algorithms)   第十七章 分摊分析(Amortized Analysis)   第五部分(Part V) 高级的数据结构(Advanced Data Structures)   第十八章 B-树(B-Trees)   第十九章 二项式堆(Binomial Heaps)   第二十章 斐波纳契堆(Fibonacci Heaps)   第二十一章 不相交集的数据结构(Data Structures for Disjoint Sets)   第六部分(Part VI) 图算法(Graph Algorithms)   第二十二章 基本的图算法(Elementary Graph Algorithms)   第二十三章 最小生成树(Minimum Spanning Trees)   第二十四章 单源最短路径(Single-Source Shortest Paths)   第二十五章 全对的最短路径(All-Pairs Shortest Paths)   第二十六章 最大流(Maximum Flow)   第七部分(Part VII) 精选的主题(Selected Topics)   第二十七章 排序网络(Sorting Networks)   第二十八章 矩阵运算(Matrix Operations)   第二十九章 线性规划(Linear Programming)   第三十章 多项式快速傅里叶变换(Polynomials and the FFT)   第三十一章 数论算法(Number-Theoretic Algorithms)   第三十二章 字符串匹配(String Matching) ......................................................
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值