看数据结构写代码(55) 二叉排序树

二叉排序树 是一种 动态 查找树,它的 创建 是在 查找中 生成的。 当 查找 失败时,它将 数 插入到 合适的 位置中去。 二叉查找树的 左子树上的值 父亲的 值 小,而 右子树上的值 总是 比 父节点 大。这样 查找 类似与 二分 查找,其 最多 查找 的 次数 等于 树的 深度。

下面的代码 主要 是 两方面:插入 节点 和 删除 节点。

下面 给出 代码, 欢迎 指出 代码 不足:

// BinarySortTree.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <cstdlib>
typedef int TreeType;

typedef struct BSTNode{
	TreeType data;
	BSTNode * leftChild;
	BSTNode * rightChild;
}*BSTree;//二叉排序树

//存在返回true,不存在返回false
//f初始值 必须为 NULL
bool searchBST(BSTree tree,TreeType key,BSTree f,BSTree * p){
	if (tree == NULL){//查找失败,肯定是 查找了 某个节点 的左子树或者 右子树为null,*p == 这个节点.
		*p = f;return false;
	}
	else{
		TreeType data = tree->data;
		if (data == key){
			return true;
		}
		else if(data > key){
			return searchBST(tree->leftChild,key,tree,p);
		}
		else{
			return searchBST(tree->rightChild,key,tree,p);
		}
	}
}

int insertBST(BSTree * tree,TreeType key){
	BSTree p;
	if (searchBST(*tree,key,NULL,&p) == false){//未找到,需要插入.
		BSTree node = (BSTree)malloc(sizeof(BSTNode));
		node->data = key;
		node->leftChild = node->rightChild = NULL;//插入的肯定是叶子节点。
		if (p == NULL){//之前 树为 空树
			*tree = node;
		}else{
			if (p->data > key){
				p->leftChild = node;
			}
			else{
				p->rightChild = node;
			}
		}
		return true;
	}
	return false;
}
//删除节点
bool deleteNode(BSTree * tree){
	BSTree p = * tree;
	if (p->leftChild == NULL){//左子树为空(叶子节点也走这步)
		*tree = p->rightChild;
		free(p);
	}
	else if(p->rightChild == NULL){//右子树为空
		*tree = p->leftChild;
		free(p);
	}
	else{//左右子树都不为空,寻找左子树最大节点,修改节点数据域为最大节点,并删除最大节点
		BSTree max ,maxPre = NULL;//max:节点左子树上,最大的节点(左子树的最右下方)
		max = p->leftChild;
		while (max->rightChild!= NULL){
			maxPre = max;//最大节点的前驱
			max= max->rightChild;
		}
		p->data = max->data;//更换最大值
		if (max == p->leftChild){//删除节点的右子树为空
			//p->leftChild = NULL;
			p->leftChild = max ->leftChild;
		}
		else{
			maxPre->rightChild = max->leftChild;
		}
		free(max);
	}
	return true;
}

bool deleteBST(BSTree * tree,TreeType key){
	BSTree p = *tree;
	if (p != NULL){
		if (p->data == key){
			return deleteNode(tree);
		}
		else if(p->data > key){
			return deleteBST(&(p->leftChild),key);
		}
		else{
			return deleteBST(&(p->rightChild),key);
		}
	}
	return false;
}

BSTree  find(BSTree tree,TreeType key){
	while (tree){
		TreeType data = tree->data;
		if (data == key){
			return tree;
		}
		else if(data > key){
			tree = tree->leftChild;
		}
		else{
			tree = tree->rightChild;
		}
	}
	return NULL;
}

//中序遍历
void inOrderTraverse(BSTree tree){
	if (tree != NULL){
		inOrderTraverse(tree->leftChild);
		printf("%d\t",tree->data);
		inOrderTraverse(tree->rightChild);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	//BSTree tree;
	BSTree tree = NULL;//必须等于NULl
	int array[] = {88,22,33,55,66,77,44,11,99};
	for (int i = 0; i < 9; i++){
		insertBST(&tree,array[i]);
	}
	//由定义可知,中序 是 按 从 小 到大的
	printf("-------------中序遍历--------------\n");
	inOrderTraverse(tree);
	BSTree f = find(tree,88);
	printf("88 == %d\n",f->data);
	printf("-------------删除88中序遍历--------------\n");
	deleteBST(&tree,88);
	inOrderTraverse(tree);
	printf("\n-------------删除11中序遍历--------------\n");
	deleteBST(&tree,11);
	inOrderTraverse(tree);
	printf("\n-------------删除99中序遍历--------------\n");
	deleteBST(&tree,99);
	inOrderTraverse(tree);
	printf("\n-------------删除55中序遍历--------------\n");
	deleteBST(&tree,55);
	inOrderTraverse(tree);
	printf("\n-------------删除44中序遍历--------------\n");
	deleteBST(&tree,44);
	inOrderTraverse(tree);
	printf("\n-------------删除33中序遍历--------------\n");
	deleteBST(&tree,33);
	inOrderTraverse(tree);
	printf("\n-------------删除22中序遍历--------------\n");
	deleteBST(&tree,22);
	inOrderTraverse(tree);
	printf("\n-------------删除66中序遍历--------------\n");
	deleteBST(&tree,66);
	inOrderTraverse(tree);
	printf("\n-------------删除77中序遍历--------------\n");
	deleteBST(&tree,77);
	inOrderTraverse(tree);
	return 0;
}

运行截图:

时间: 2024-10-10 13:29:03

看数据结构写代码(55) 二叉排序树的相关文章

看数据结构写代码(32) 赫夫曼树编码以及译码

杂谈:最近有点慵懒,不好不好.好几天都没写代码,原本准备上星期完结 树 这一章节的.现在 又耽误了.哎.要抓紧时间啊. 下面直接上代码: 可以到我的网盘下载源代码,或者 直接拷贝下面的源代码 运行 网盘地址:点击打开链接 // HuffmanTree.cpp : 定义控制台应用程序的入口点. //哈弗曼编码,译码 #include "stdafx.h" #include <stdlib.h> #include <cstring> enum E_State { E

看数据结构写代码(44) 判断无向图是否有环路

在 看 严蔚敏的 数据结构 一书 7.5小节时,书上 说" 判断有向图是否存在环要不无向图复杂.对于无向图来说,深度优先遍历过程中遇到回边(即指向已访问过的顶点的边),则必定存在环路". 看的不明白,所以 网上 百度了一下. 有了思路:故写下算法 和思路,以便以后 温故. 思路: 1.一个n个顶点,e条边的 无向图,若 e>= n,必有环路. 2.若 e < n ,需要 深度 遍历,并把 父节点传入 参数中,如果 遇到 一个 节点 被访问过 并且 不是 父节点,那么 就有环

看数据结构写代码(63) 堆排序

// HeapSort.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <cstdlib> #define LIST_MAX_SIZE 100 //顺序表 struct sqList{ int base[LIST_MAX_SIZE]; int len; }; typedef sqList Heap;//顺序表作为堆排序的基本类型 //初始化顺序表 void initHeap(Heap * list,int * arr

看数据结构写代码(67) 置换 _ 选择排序(完结篇)

杂谈: 严蔚敏版<数据结构(C语言版)> 一书 终于看完了.这是 一个完结,也是 一个新的开端.<算法导论> 已到手. 置换选择排序的思想 是 将 归并段 尽量 变的 更大,而不是根据 内存 大小 限制在 固定的 大小. 这样 可以 利用赫夫曼树 来 进行 最优归并树,从而 使 外存 读写次数 最少. 下面给出 具体 代码:欢迎指出代码不足. // Replace_Selcetion.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&q

看数据结构写代码(50)伙伴系统

伙伴系统 是一种 只 可以 分配 2的 幂次方 个 空间的 ,回收 内存 时 只 合并 "伙伴空间" 的一种 动态内存管理方式. 例如 一个 空间 大小 为 64 的 内存,伙伴 系统 为 这 64 的内存  建立 一组 双向循环 链表,分别 管理着  2的 0 次方,2的1 次方幂,2的 2 次方幂...2的6次方幂的 可用空间. 即使 我们 只想分配 一个 大小 为3的 空间,系统 却 只能 返回 一个 内存 大小 为 4(2的2次方)的 一个空间. 系统 在 初始化的 时候 ,并

看数据结构写代码(15)链式队列的实现

队列 和 栈 是 一种 受限制的 线性表.所以 他们的 实现方式 都 相差 无几.之前有过  链栈 和 链式线性表 的 实现经验,自然 写 链队 ,也毫无问题. 下面详细讲解每一段代码 的技术要点 下面是队列节点的数据结构 struct QueueNode { ElementType data; QueueNode * next; }; //生成一个节点 QueueNode * queueNodeMake(ElementType data){ QueueNode * pNode = (Queue

看数据结构写代码(61) 哈希表

前面说的 各种查找都是 基于 "比较" 的基础 来进行 查找的.查找的 效率 要 看 比较的 次数.那么 有没有 不需要 比较,就可以 找到 想要的数据的 方法呢? 哈希表 就是 这样的 一种方法,它用  数组 作为 保存 关键字的 数据原型,通过 一个 哈希 函数f(k),来找到 关键字 存储的位置,从而 找到想要的信息. 例如 我们 想要解决 这样的一个问题: 假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些.什么方法能最快的查出所有小

看数据结构写代码(35) 图的邻接矩阵表示法

杂谈:最近清明小长假,好好的放松了一下.节前 和 节后 都有点 松懈.不好,不好.贵在坚持.加油. 图的邻接矩阵表示法是用 两个数组 来表示 图的数据结构.一个是顶点数组,另一个是邻接矩阵数组.邻接矩阵 里存放着 顶点的关系. 用邻接矩阵表示图,在 看 顶点之间 是否有边,或者 求顶点的度等操作时比较简单.但空间浪费巨大,在插入,删除 顶点 和边 操作时 需要 移动大量数据,造成不便.所以在插入删除比较多,节点数比较多的时候 不宜 使用这种结构. 下面上代码: 源代码网盘地址:点击打开链接 //

看数据结构写代码(58) B-树

B-树 一种 自平衡的 多路 查找树.它在文件系统里很有用. 一个m阶的B-树,要么是空树,要么是满足这些特性的树.. 1.树 最多 有 m个分支. 2.树的根 最少 两个子树. 3. 树的非终端叶子节点 最少  m/2 向上 取整   个 子树. 4.所有叶子节点 都在 一层. 它的节点 结构:  (N,P0,K1,P1,K2,p2......Kn,Pn) 其中 N 是 节点的 关键字个数,p0~pn 是 指向子树的指针,K1~Kn是关键字 #define M 3 //B树的阶数.. type