关闭

二叉查找树C语言实现及其可视化

标签: 二叉查找树二叉树的可视化数据结构和算法
1015人阅读 评论(0) 收藏 举报
分类:
0, 二叉搜索树的定义:(二叉查找树)(二叉排序树)
      (1)若左子树非空,则左子树上的所有的节点的值都小于根节点的值
      (2)若右子树非空,则右子树上的所有的节点的值都大于根节点的值

      (3)其左右子树都是二叉搜索树

                 

1,二叉查找树的表示法

struct TreeNode;
typedef struct TreeNode *PtrSearchTree;
typedef PtrSearchTree SearchTree;
struct TreeNode
{
	int value;
	PtrSearchTree left;
	PtrSearchTree right;
};

2,二叉查找树的插入:插入的元素始终位于叶子节点。

void insert(SearchTree* tree, int value)
{
	if( *tree == NULL )
	{
		if( ! ((*tree) = (PtrSearchTree)malloc(sizeof(struct TreeNode))) )
		{
			printf("insert malloc error\n");
			exit(0);
		}
		(*tree)->value = value;
		(*tree)->left = (*tree)->right = NULL;
	}
	else
	{
		if( value < (*tree)->value )
			insert(&((*tree)->left), value);
		else
			insert(&((*tree)->right), value);
	}
}
3,二叉查找树的创建,调用插入函数即可。

note:

1  SearchTree tree = NULL;其中的 “= NULL”,在window下的gcc进行编译运行时可以省略, 但是在linux编译运行时如果没有将其值设置为NULL, 则提醒了“段错误”。应该是编译器的不同造成的, 不过为每个指针赋值,而不是由其变为野指针确实是个好的习惯。

2   getchar()是为了吃掉用户输入的数字之间的空格,并且在用户输入完成按下Enter键之后可以捕获到‘\n’.

SearchTree create()
{
	SearchTree tree = NULL;
	printf("Create Binary Search Tree\nplease enter the element, seperated by space, and stop input by Enter:\n");
	int key;
	while(1)
	{
		scanf("%d", &key);
		insert(&tree, key);
		if( getchar() == '\n' )
			break;
	}
	return tree;
}
4, 二叉查找树的可视化。为了对其进行可视化,需要借助与graphviz,他的安装在上一篇中有简单的介绍,并且其中使用的dot语言可在官网查看,很容易学习。

void visualization(SearchTree tree, char* filename)
{
	FILE *fw;
	if( NULL == (fw = fopen(filename, "w")) )
	{
		printf("open file error");
		exit(0);
	}
	fprintf(fw, "digraph\n{\nnode [shape = Mrecord, style = filled, color = black, fontcolor = white];\n");
	write2dot(tree, fw);
	fprintf(fw, "}");
	fclose(fw);
}
void write2dot(SearchTree tree, FILE* fw)
{
	if(tree == NULL)
		return ;
	else
	{
		fprintf(fw, "%d [label = \"<f0> | <f1> %d | <f2> \", color = black, fontcolor = white, style = filled];\n", tree->value, tree->value);
	}
	if(tree->left)
	{
		fprintf(fw, "%d [label = \"<f0> | <f1> %d | <f2> \", color = black, fontcolor = white, style = filled];\n", tree->left->value, tree->left->value);
		fprintf(fw, "%d:f0:sw -> %d:f1;\n", tree->value, tree->left->value);
	}
	if(tree->right)
	{
		fprintf(fw, "%d [label = \"<f0> | <f1> %d | <f2> \", color = black, fontcolor = white, style = filled];\n", tree->right->value, tree->right->value);
		fprintf(fw, "%d:f2:se -> %d:f1;\n", tree->value, tree->right->value);
	}
	write2dot(tree->left, fw);
	write2dot(tree->right, fw);
}
函数注释:

         (1)  visualization函数将参数tree指定的树,使用dot语言写入到参数filename指定的文件中(文件以.dot为后缀)

         (2) write2dot函数相当于一个遍历树的过程,在遍历过程中, 构成该树的dot文件。

程序的运行过程实例如下:

运行完成后会在同目录下产生一个.dot文件,在本程序中文件名为:searchtree.dot

使用dot命令产生图片,如下图所示,就生成了名为searchtree.png的图片。

查看图片如下:

                         

5, 二叉树的删除

若删除元素为叶子节点,则直接删除,将原本指向该节点的双亲节点的相应的指针域置空,

若删除度为1的节点,将其输出节点的子树直接挂在删除节点的父节点上,

若删除度为2的节点,找其左子树的最大值或者右子树的最小值替代该节点的值,然后在其左子树或者右子树删除找到的最大值或者最小值。

SearchTree delete(SearchTree tree, int value)
{
	PtrSearchTree temp = NULL;
	if( !tree )
	{
		printf("have no element(delete): %d\n", value);
		return NULL;
	}
	else if( value < tree->value )
		tree->left = delete(tree->left, value);
	else if( value > tree->value )
		tree->right = delete(tree->right, value);
	else
	{
		if( tree->left && tree->right )
		{
			temp = find_min(tree->right);
			tree->value = temp->value;
			tree->right = delete(tree->right, temp->value);
		}
		else
		{
			temp = tree;
			if( !(tree->left) )tree = tree->right;
			else if( !(tree->right) )tree = tree->left;
			free(temp);
		}
	}
	return tree;
}
在程序中删除83,得到如下的二叉树:

                                

6,查找(递归和迭代)

                  note:函数的返回类型为指针类型。

SearchTree find_recursion(SearchTree tree, int value)
{
	if( !tree )
	{
		printf("have no element(find): %d\n", value);
		return NULL;
	}
	if( value < tree->value )
		find_recursion(tree->left, value);
	else if( value > tree->value )
		find_recursion(tree->right, value);
	else
		return tree;
}
SearchTree find_iteration(SearchTree tree, int value)
{
	while(tree)
	{
		if( value < tree->value )
			tree = tree->left;
		else if( value > tree->value )
			tree = tree->right;
		else
			return tree;
	}
	printf("have no element(find): %d\n", value);
	return NULL;
}



源码

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

struct TreeNode;
typedef struct TreeNode *PtrSearchTree;
typedef PtrSearchTree SearchTree;
struct TreeNode
{
	int value;
	PtrSearchTree left;
	PtrSearchTree right;
};

SearchTree create();
void insert(SearchTree* tree, int value);
void write2dot(SearchTree tree, FILE* fw);
void visualization(SearchTree tree, char* filename);
SearchTree find_min(SearchTree tree);
SearchTree find_max(SearchTree tree);
SearchTree find_iteration(SearchTree tree, int value);
SearchTree find_recursion(SearchTree tree, int value);
SearchTree delete(SearchTree tree, int value);

int main(int argc, char** argv)
{
	SearchTree s_tree_1 = create();
	visualization(s_tree_1, "searchtree.dot");

	PtrSearchTree min = find_min(s_tree_1);
	PtrSearchTree max = find_max(s_tree_1);
	printf("the min and max is %d, %d, respectively\n", min->value, max->value);
	int search = 83;
	PtrSearchTree find_result_1 = find_iteration(s_tree_1, search);
	PtrSearchTree find_result_2 = find_iteration(s_tree_1, search);
	if( find_result_1 && find_result_2 )
		printf("search for %d, and the result from iteration and recursion is: %d, %d\n", search, find_result_1->value, find_result_2->value);

	s_tree_1 = delete(s_tree_1, 83);
	visualization(s_tree_1, "searchtree_afterdelete.dot");
	return 0;
}

SearchTree create()
{
	SearchTree tree = NULL;
	printf("Create Binary Search Tree\nplease enter the element, seperated by space, and stop input by Enter:\n");
	int key;
	while(1)
	{
		scanf("%d", &key);
		insert(&tree, key);
		if( getchar() == '\n' )
			break;
	}
	return tree;
}
void insert(SearchTree* tree, int value)
{
	if( *tree == NULL )
	{
		if( ! ((*tree) = (PtrSearchTree)malloc(sizeof(struct TreeNode))) )
		{
			printf("insert malloc error\n");
			exit(0);
		}
		(*tree)->value = value;
		(*tree)->left = (*tree)->right = NULL;
	}
	else
	{
		if( value < (*tree)->value )
			insert(&((*tree)->left), value);
		else
			insert(&((*tree)->right), value);
	}
}
void visualization(SearchTree tree, char* filename)
{
	FILE *fw;
	if( NULL == (fw = fopen(filename, "w")) )
	{
		printf("open file error");
		exit(0);
	}
	fprintf(fw, "digraph\n{\nnode [shape = Mrecord, style = filled, color = black, fontcolor = white];\n");
	write2dot(tree, fw);
	fprintf(fw, "}");
	fclose(fw);
}
void write2dot(SearchTree tree, FILE* fw)
{
	if(tree == NULL)
		return ;
	else
	{
		fprintf(fw, "%d [label = \"<f0> | <f1> %d | <f2> \", color = black, fontcolor = white, style = filled];\n", tree->value, tree->value);
	}
	if(tree->left)
	{
		fprintf(fw, "%d [label = \"<f0> | <f1> %d | <f2> \", color = black, fontcolor = white, style = filled];\n", tree->left->value, tree->left->value);
		fprintf(fw, "%d:f0:sw -> %d:f1;\n", tree->value, tree->left->value);
	}
	if(tree->right)
	{
		fprintf(fw, "%d [label = \"<f0> | <f1> %d | <f2> \", color = black, fontcolor = white, style = filled];\n", tree->right->value, tree->right->value);
		fprintf(fw, "%d:f2:se -> %d:f1;\n", tree->value, tree->right->value);
	}
	write2dot(tree->left, fw);
	write2dot(tree->right, fw);
}
SearchTree find_min(SearchTree tree)
{
	if( !tree )
		return NULL;
	else
		if( !(tree->left) ) return tree;
		else
			find_min(tree->left);
}
SearchTree find_max(SearchTree tree)
{
	if( !tree )
		return NULL;
	else
		if( !(tree->right) ) return tree;
		else find_max(tree->right);
}
SearchTree find_recursion(SearchTree tree, int value)
{
	if( !tree )
	{
		printf("have no element(find): %d\n", value);
		return NULL;
	}
	if( value < tree->value )
		find_recursion(tree->left, value);
	else if( value > tree->value )
		find_recursion(tree->right, value);
	else
		return tree;
}
SearchTree find_iteration(SearchTree tree, int value)
{
	while(tree)
	{
		if( value < tree->value )
			tree = tree->left;
		else if( value > tree->value )
			tree = tree->right;
		else
			return tree;
	}
	printf("have no element(find): %d\n", value);
	return NULL;
}
SearchTree delete(SearchTree tree, int value)
{
	PtrSearchTree temp = NULL;
	if( !tree )
	{
		printf("have no element(delete): %d\n", value);
		return NULL;
	}
	else if( value < tree->value )
		tree->left = delete(tree->left, value);
	else if( value > tree->value )
		tree->right = delete(tree->right, value);
	else
	{
		if( tree->left && tree->right )
		{
			temp = find_min(tree->right);
			tree->value = temp->value;
			tree->right = delete(tree->right, temp->value);
		}
		else
		{
			temp = tree;
			if( !(tree->left) )tree = tree->right;
			else if( !(tree->right) )tree = tree->left;
			free(temp);
		}
	}
	return tree;
}


0
0
查看评论

数据结构之 二叉查找树(C语言实现)

数据结构之 二叉查找树1. 二叉查找树的定义二叉查找树(binary search tree)是一棵二叉树,或称为二叉搜索树,可能为空;一棵非空的二叉查找树满足一下特征: 每个元素有一个关键字,并且任意两个元素的关键字都不同;因此,所有的关键字都是唯一的。 在根节点的左子树中,元素的关键字(如果存在...
  • men_wen
  • men_wen
  • 2017-03-28 20:42
  • 595

数据结构之---二叉树C实现

学过数据结构的都知道树,那么什么是树? 树(tree)是包含n(n>0)个结点的有穷集,其中: (1)每个元素称为结点(node); (2)有一个特定的结点被称为根结点或树根(root)。 (3)除根结点之外的其余数据元素被分为m(m≥0)个互不相交的集合T...
  • morixinguan
  • morixinguan
  • 2016-03-06 20:33
  • 3584

C语言实现二叉查找树(BST)的基本操作

我们在上一篇博客中讲解了二叉树,这一次我们来实现二叉树的进阶——二叉查找树(Binary Search Tree),又称二插排序树(Binary Sort Tree)。所以简称为BST。二插查找树的定义如下:1.若左子树不为空,则左子树上所有节点的值均小于它的根节点的值;2.若右子树不为空,则右子树...
  • CHENYUFENG1991
  • CHENYUFENG1991
  • 2016-03-16 00:23
  • 7446

c语言实现二叉树的插入、查找、删除、打印树

c语言实现二叉树的插入、查找、删除、打印树
  • biglamp
  • biglamp
  • 2017-08-10 11:38
  • 1830

查找二叉树的c语言实现

  • 2012-01-03 16:15
  • 2KB
  • 下载

C/C++生成二叉树并搜索

直接上干货: #include "targetver.h" using namespace std; //定义节点 struct BiNode { int data; BiNode * lchild; BiNode * rchild; }; //插入结点 BiNode ...
  • FENGQIYUNRAN
  • FENGQIYUNRAN
  • 2014-11-06 21:33
  • 939

创建二叉查找树的完整C代码

基本概念 二叉查找树(Binary Search Tree),又称二叉排序树(Binary Sort Tree),亦称二查搜索书。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于...
  • u014488381
  • u014488381
  • 2014-12-02 20:30
  • 3314

二叉查找树(BST)及其C语言实现

二叉查找树         对任何节点x,其左子树中的关键字最大不超过key[x],右子树中的关键字最小不小于key[x]。         二叉查找树这种数据结构,它支持多种动态集合操作,search,m...
  • cgz372619
  • cgz372619
  • 2013-05-22 17:33
  • 863

二叉树的建立、节点查找以及节点删除C和C++实现

程序是建立一颗二叉排序树,查找节点找到了返回其父节点,失败的时候返回NULL,删除节点分为四种情况:1、左子树和右子树都为空;2、左子树为空,右子树不为空;3、左子树不为空,右子树为空;4、左子树和右子树都不为空。 C语言版本(利用结构体实现): #include #include ty...
  • w397090770
  • w397090770
  • 2012-05-03 11:23
  • 24275

c语言二叉树和二叉搜索树的实现

// // main.c // DataStructure // // Created by 仁和 on 16/8/30. // Copyright © 2016年 wfw. All rights reserved. //#include <stdio.h> #incl...
  • zhhwww12
  • zhhwww12
  • 2016-09-06 14:34
  • 285
    个人资料
    • 访问:219617次
    • 积分:3189
    • 等级:
    • 排名:第12760名
    • 原创:95篇
    • 转载:0篇
    • 译文:0篇
    • 评论:65条
    最新评论