二叉树的应用(1)--二叉树排序树基本操作

#include <cstdio>

struct BSTNode
{
	int m_nval;  //数据域
	BSTNode *m_pleft; // 左孩子节点
	BSTNode *m_pright;  //右孩子节点
};
/************************************************************************
功能:在二叉排序树中 查找key值,如果找到,返回true,且plast指向该节点。
	  plastfahter指向该双双亲节点。如果没找到,返回false,且plast指向最后遍历
	  的最后一个节点(也就是如果 要插入的节点话,直接new一个节点,和plast节点链接,完成插入)
输入:T:BST树 根,key:要查找的值,pfather:T的父节点,
输出:plast:保存找到的节点,或者待插入节点的父节点位置。plastfather:找到节点的父节点
返回:true or  false.
/************************************************************************/
bool  SearchBST(BSTNode * &T,int key,BSTNode * pTfather,BSTNode * &plast,BSTNode * &plastfather)
{
	if(NULL == T) //该树为空 或 到底了
	{
		plast = pTfather ; //pfather指向 plast的父节点 以NULL初始化
		return false;
	}
	if(key == T->m_nval)
	{
		plast = T;				 //如果找到 plast 指向该节点
		plastfather = pTfather;  // plastfather  指向 该节点父节点
		return  true;
	}
	else
	{
		if( key > T->m_nval ) //往右子树查找
			return SearchBST(T->m_pright,key,T,plast,plastfather);
		else
		{
			if( key < T->m_nval)//往左子树查找
				return SearchBST(T->m_pleft,key,T,plast,plastfather);
		}
	}
}
bool InsertBST(BSTNode* &T,int key)
{
	BSTNode *pToBeInsert,*pNew,*plastfather;
	if(!SearchBST(T,key,NULL,pToBeInsert,plastfather))//如果找到 就不插入
	{
		pNew = new BSTNode();
		pNew->m_nval = key;
		pNew->m_pleft = pNew->m_pright = NULL;

		if(!pToBeInsert)
			T = pNew ; //如果 ptobeinsert 为NULL 则该树为空
		else
		{
			if( key > pToBeInsert->m_nval)
				pToBeInsert ->m_pright = pNew;
			else
				pToBeInsert ->m_pleft = pNew ;
			return true;
		}
	}else return false;
}

BSTNode* CreateBST(int a[],int len)
{
	BSTNode *T = NULL;
	for(int i=0 ; i<len; i++)
		InsertBST(T,a[i]);
	return T;
}

//二叉排序树中 删除 key值节点
bool DeleteBSTNode(BSTNode *T,int key)
{
	BSTNode *pKeyNode=NULL,*pKeyNodeFather=NULL;  //初始化 指向key和其父节点指针
	//如果找到了 pkeyNode指向该key节点,pkeyNodefather指向其父节点
	if(SearchBST(T,key,NULL,pKeyNode,pKeyNodeFather))
	{
		if(pKeyNode ->m_pleft == NULL) //只有右子树 或 叶子节点
		{//直接 将其右子树 链入BST中
			if(pKeyNodeFather->m_pleft == pKeyNode)
				pKeyNodeFather->m_pleft = pKeyNode->m_pright;
			else
				pKeyNodeFather->m_pright = pKeyNode->m_pright;
			delete pKeyNode; //释放 节点内存
		}
		else
		{
			if(pKeyNode->m_pright == NULL) //只有左子树
			{
				if(pKeyNodeFather->m_pleft == pKeyNode)
					pKeyNodeFather->m_pleft = pKeyNode->m_pleft;
				else
					pKeyNodeFather->m_pright = pKeyNode->m_pleft;
				delete pKeyNode; //释放 节点内存
			}
			else // 既不是叶子节点和单孩子树。查找 前驱节点(左子树的最右节点)
			{
				BSTNode *pre=pKeyNode,*pcur=pKeyNode->m_pleft; //记录 前驱指针,和当前指针
				while(pcur -> m_pright)
				{
					pre = pcur;
					pcur = pcur->m_pright;
				} // 此时 pcur 指向 替代的节点
				pKeyNode ->m_nval = pcur ->m_nval ; //覆盖了 pkeyNode 间接删除
				//下面 就要删除pcur,之前 需要完成链接
				if(pre != pKeyNode) // now pcur并不是pkeyNodepleft.
					pre->m_pright = pcur->m_pleft ; // 将pcur左子树 链入 其父节点的右节点
				else  //pre == pkeyNode pcur为 叶子节点
					pre->m_pleft = pcur->m_pleft ;
				delete pcur;
			}
		}
		return true;
	}
	else return false;
}
void InOrderTravseBST(BSTNode *T)
{
	if(T)
	{
		InOrderTravseBST(T->m_pleft);
		printf("%d ",T->m_nval);
		InOrderTravseBST(T->m_pright);

	}
}

/*********************测试代码********************************/
void Test()
{
	// 测试1 创建
	/*
	       10
		 /             2       13
	  	 \	   /   		  7   11   78
		 /   /   		6	 9   23
	  / 	/	/
	4	  8    12
	 */
	int a[]={10,13,11,2,7,9,8,6,4,78,23,12,8};
	int len = sizeof(a)/sizeof(int);
	BSTNode *T = CreateBST(a,len);
	printf("中序遍历创建的BST:\n");
	InOrderTravseBST(T);
	printf("\n");

	//测试2 查找
	BSTNode *pfind=NULL,*pfindfather=NULL;
	printf("查找 key == 4:\n");
	int key = 4;
	if(SearchBST(T,key,NULL,pfind,pfindfather))
	{
		printf("查找成功,pfind->m_nval=%d,pfindfater->m_nval=%d\n",pfind->m_nval,pfindfather->m_nval);
	}else
		printf("查找key = %d 失败\n",key);

	//测试3 插入
	key = 15;
	if(InsertBST(T,key))
		printf("插入key = %d成功\n中序遍历为:\n",key);
	else  printf("插入key = %d失败\n中序遍历为:\n",key);
	InOrderTravseBST(T);
	printf("\n");

	//测试4  删除 根节点
	key = 10;
	if(DeleteBSTNode(T,key))
	{
		printf("删除key = %d 节点成功\n",key);
	}else printf("删除key = %d 节点失败\n",key);
	printf("中序遍历为:\n");
	InOrderTravseBST(T);
	printf("\n");

	//测试5 删除 只有右子树
	key = 2;
	if(DeleteBSTNode(T,key))
	{
		printf("删除key = %d 节点成功\n",key);
	}else printf("删除key = %d 节点失败\n",key);
	printf("中序遍历为:\n");
	InOrderTravseBST(T);
	printf("\n");

	//测试6  删除 只有左子树
	key = 9;
	if(DeleteBSTNode(T,key))
	{
		printf("删除key = %d 节点成功\n",key);
	}else printf("删除key = %d 节点失败\n",key);
	printf("中序遍历为:\n");
	InOrderTravseBST(T);
	printf("\n");

	//测试7  删除 叶子节点
	key = 78;
	if(DeleteBSTNode(T,key))
	{
		printf("删除key = %d 节点成功\n",key);
	}else printf("删除key = %d 节点失败\n",key);
	printf("中序遍历为:\n");
	InOrderTravseBST(T);
	printf("\n");

}

int main()
{
	Test();
	return 0;
}


二叉树的应用(1)--二叉树排序树基本操作,布布扣,bubuko.com

时间: 2024-10-22 18:43:58

二叉树的应用(1)--二叉树排序树基本操作的相关文章

6. 蛤蟆的数据结构进阶六之二叉树排序树

6. 蛤蟆的数据结构进阶六之二叉树排序树 本篇名言:"有些人因为贪婪,想得更多的东西,却把现在所有的也失掉了. -- 伊索" 关于理论知识已经在上篇中进行描述,这篇我们主要来看下如何是实现二叉排序树. 欢迎转载,转载请标明出处: 1.  二叉排序树的定义 二叉排序树(BinarySort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ①若它的左子树非空,则左子树上所有结点的值均小于根结点的值: ②

二叉树排序树的的构造和查找

/********************************************************* 二叉树排序树的的构造和查找 *********************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <stack&g

(转)数据结构:树、二叉树、最优二叉树

来源:http://www.cnblogs.com/coder2012/archive/2013/06/05/3102868.html 树 树形结构是一类非常重要的非线性结构,它可以很好地描述客观世界中广泛存在的具有分支关系或层次特性的对象,因此在计算机领域里有着广泛应用,如操作系统中的文件管理.编译程序中的语法结构和数据库系统信息组织形式等. 树的相关定义 节点的度:一个节点含有的子树的个数称为该节点的度: 树的度:一棵树中,最大的节点的度称为树的度: 叶节点或终端节点:度为零的节点: 非终端

07_2.二叉数,二叉树的简单应用:表达式树

""" 二叉树的list实现 """ def BinTree(data, left=None, right=None): """ 二叉树 :param data: 根结点的元素 :param left: 左子树元素 :param right: 右子树元素 :return: """ return [data, left, right] def is_empty_BinTree(btree)

HLG 2040 二叉树的遍历 (二叉树遍历之间的转换)

链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2040 Description: 给出一棵二叉树的中序和前序遍历,输出它的后序遍历. Input 本题有多组数据,输入处理到文件结束. 每组数据的第一行包括一个整数n,表示这棵二叉树一共有n个节点. 接下来的一行每行包括n个整数,表示这棵树的中序遍历. 接下来的一行每行包括n个整数,表示这棵树的前序遍历. 3<= n <= 1

二叉树(一)——二叉树的基本实现(数组实现和链表实现)

1.树是一种数据结构,树的一些相关的术语: 结点的度:一个结点的后继结点的个数. 树的度:树中度值最大的结点的度被称为树的度. 树的深度:树的层次数. 分支结点:度值大于0的结点,分支结点至少含有一个后继,分支结点也称为非终端结点. 叶子结点:树中的度值为0的结点. 双亲结点:树中某个结点的前驱结点,也成为父节点. 子女结点:树中某结点的后继结点. 兄弟结点:树中同一层的结点. 2.二叉树 (1)二叉树是一种特殊的树,树的度值最大为2. (2)二叉树的表示: A /      \ B     

二叉树详解及二叉树的前序、中序、后序遍历(递归和非递归)

介绍二叉树之前先介绍一下树相关的概念. 树的定义:树是n(n>=0)个有限个数据的元素集合,形状像一颗倒过来的树. 树的概念: 节点:结点包含数据和指向其它节点的指针. 根节点:树第一个结点称为根节点. 结点的度:结点拥有的子节点个数. 叶节点:没有子节点的节点(度为0). 父子节点:一个节点father指向另一个节点child,则child为孩子节点,father为父亲节点 兄弟节点:具有相同父节点的节点互为兄弟节点. 节点的祖先:从根节点开始到该节点所经的所有节点都可以称为该节点的祖先. 子

完美二叉树, 完全二叉树和完满二叉树(国内教材到处是坑啊)

树在数据结构中占有非常重要的地位.本文从树的基本概念入手,给出完美(Perfect)二叉树,完全(Complete)二叉树和完满(Full)二叉树的区别.如果学习过二叉树,但是对这三种二叉树并没有深入的理解,或者完全被国产数据结构教科书所误导(只听说过满二叉树和完全二叉树)的朋友不妨花点时间耐着性子将本文仔细阅读N(>=1)遍. 1. 树(Tree)的基本概念 1.1 树的定义 A tree is a (possibly non-linear) data structure made up of

二叉树学习一:二叉树创建与遍历

二叉树的遍历有三种方式: 1)先序遍历:若二叉树为空,则空操作:不为空,则先访问根结点,先序遍历左子树,先序遍历右子树. 2)后序遍历:若二叉树为空,则空操作:不为空,则中序遍历左子树,访问根结点,中序遍历右子树. 3)后序遍历:若二叉树为空,则空操作:不为空,则后序遍历左子树,后序遍历右子树,访问根结点. 例: 1)先序遍历结果为:ABDECF 2)中序遍历结果为:DBEAFC 3)后序遍历结果为:DEBFCA 二叉树输出的思想是将树转换成线性结构输出,一般采用递归方式,非递归方式是使用栈实现