二叉排序树(C与Python分别实现)

1.      什么是二叉排序树?

二叉排序树是一种特殊的二叉树,可以是一棵空树,也可以是具有下列性质的二叉树:

1.      若左子树不为空,那么左子树所有结点的值都小于它的根结点的值。

2.      若右子树不为空,那么右子树所有结点的值都大于它的根节点的值。

3.      它的左右子树也分别是二叉排序树。

二叉排序树又称二叉查找树,是一种动态查找表,所谓动态查找表是指除了查询检索操作以外,还可以进行插入、删除操作的结构;与之相对应的就是静态查找表,只能进行查询检索操作。

2.      二叉排序树的操作

对于二叉排序树的实现就是对查找、插入、删除操作的实现,因为要进行插入删除操作,所以要用链表结构来实现,操作介绍如下:

1.   查找key:从根结点出发,若key大于根结点则向根结点的右侧走,跟这个根结点的右结点比较,若key小于根结点则向根结点的左侧走,跟这个根结点做结点比较,该根结点的左右子树分别都是二叉排序树,所以重复上面的步骤,直到找到key,或者到NULL(叶子结点的子结点为空)。

2.   插入key:跟查找key步骤相同,找到key时返回,不进行插入,未找到时,在最后一个查找叶子结点下插入key值,若key大于该叶子结点的值则插入该叶子结点的右侧,作为该叶子结点的右子树,否则作为左子树。

3.   删除key:跟查找key步骤相同,若查找最终为NULL(未找到),则返回,若在结点p处找到key,则进行一下判断:

a.      若p为叶子结点,先找到p的父节点q,若p为q的左子树,则将q的左子树指针至NULL,若p为q的右子树,则将q的右子树指针至NULL,删除p

b.      若p的左子树不为空,右子树为空,则找到p的父节点q,若p是q的左子树,则将q的左子树指针指向p的左子树,若p是q的右子树,则将q的右子树指针指向p的左子树,删除p

c.      若p的右子树不为空,左子树为空,则找到p的父节点q,若p是q的左子树,则将q的左子树指针指向p的右子树,若p是q的右子树,则将q的右子树指针指向p的右子树,删除p

d.      若p的左右子树都不为空,则找到p的父节点q,将p的左子树作为p右子树的最左结点的子结点,然判断p是q的右子树还是q的左子树,若p是q的左子树,则将q的左子树指针指向p的右子树,若p是q的右子树,则将q的右子树指针指向p的右子树,删除p

3.      二叉排序树代码实现:

C代码

注意:下面的查找操作使用的是递归方式实现,既然是递归就有递归深度的问题,太深容易造成堆栈溢出,在我电脑上最多可以进行10357次递归;可用循环替代递归。

#include <stdio.h>
typedef struct  TNode
{
	int nKey;
	struct TNode* lchild;
	struct TNode* rchild;
	struct TNode* parent;
}TNode;
//++++++++++++++++++++++++++查找检索操作++++++++++++++++++++++++++/
bool SearchBST(TNode* BST,int key,TNode* &pSearch,TNode* &pParent)
{
	if ( !BST )
	{
		pSearch = pParent;
		return false;
	}
	if ( BST->nKey == key )
	{
		pSearch = BST;
		pParent = pSearch->parent;
		return true;
	}
	else if ( BST->nKey>key )
	{
		pParent = BST;
		return SearchBST(BST->lchild,key,pSearch,pParent);
	}
	else
	{
		pParent = BST;
		return SearchBST(BST->rchild,key,pSearch,pParent);
	}
	return false;
}
//++++++++++++++++++++++++++结点插入操作++++++++++++++++++++++++++/
bool InsertNode(TNode* &BST,int key,TNode* &pSearch)
{
	TNode* pParent = NULL;
	if ( SearchBST(BST,key,pSearch,pParent) )
		return false;
	TNode* pNode = new TNode;
	pNode->nKey = key;
	pNode->parent = pParent;
	pNode->lchild = NULL;
	pNode->rchild = NULL;
	if ( !pParent )
		BST = pNode;
	else if ( key>pParent->nKey )
		pParent->rchild = pNode;
	else
		pParent->lchild = pNode;
	pSearch = pNode;
	return true;
}
//++++++++++++++++++++++++++删除结点操作++++++++++++++++++++++++++/
bool DeleteNode(TNode* BST,int key)
{
	TNode* pSearch = NULL;
	TNode* pParent = NULL;
	if ( !SearchBST(BST,key,pSearch,pParent) )
		return false;
	if ( NULL!=pSearch->lchild && NULL!=pSearch->rchild )
	{
		TNode *pTmp = pSearch->rchild;
		while(pTmp->lchild) pTmp = pTmp->lchild;
		pTmp->lchild = pSearch->lchild;
		pSearch->lchild->parent = pTmp->lchild;
		if ( pParent->lchild == pSearch )
			pParent->lchild = pSearch->rchild;
		else
			pParent->rchild = pSearch->rchild;
		pSearch->rchild->parent=pParent;
	}
	else if ( NULL!=pSearch->lchild )
	{
		if( pParent->lchild == pSearch )
			pParent->lchild = pSearch->lchild;
		else
			pParent->rchild = pSearch->lchild;
	}
	else if ( NULL!=pSearch->rchild )
	{
		if ( pParent->lchild == pSearch )
			pParent->lchild = pSearch->rchild;
		else
			pParent->rchild = pSearch->rchild;
	}
	else
	{
		if( pParent->lchild == pSearch )
			pParent->lchild = NULL;
		else
			pParent->rchild = NULL;
	}
	delete pSearch;
	pSearch = NULL;
	return true;
}
//++++++++++++++++++++++++++释放内存操作++++++++++++++++++++++++++/
void DeleteBST(TNode* BST)
{
	if( !BST )return;
	if ( !BST->lchild && !BST->rchild )
	{
		if( !BST->parent && BST->parent->lchild == BST )
			BST->parent->lchild = NULL;
		else if( !BST->parent && BST->parent->rchild == BST )
			BST->parent->rchild = NULL;
		delete BST;
		BST = NULL;
		return;
	}
	DeleteBST(BST->lchild);
	DeleteBST(BST->rchild);
}
//++++++++++++++++++++++++++main测试++++++++++++++++++++++++++/
int main(int argc, char* argv[])
{
	TNode* BST = NULL;
	TNode* pNode = NULL;
	TNode* pParent = NULL;
	int nCount = 10358;
	for ( int i=0;i<nCount;i++ )
	{
		if( InsertNode(BST,i,pNode) )
			printf("插入%d成功\n",i);
	}
	if ( SearchBST(BST,nCount-1,pNode,pParent) )
	{
		printf("查找成功\n");
	}
	DeleteNode(BST,1);
	if ( !SearchBST(BST,1,pNode,pParent) )
	{
		printf("查找失败");
	}
	DeleteBST(BST);
	getchar();
	return 0;
}

Python代码

第一次学习Python,代码中肯定有许多不足之处,希望指正,暂时实现如下:

#BST.py
_Debug = False
#+++++++++++++++++++++struct realized by class+++++++++++++++++++++#
class TNode:
    def __init__(self,key,left,right,parent):
        self.key=key
        self.lchild=left
        self.rchild=right
        self.parent=parent
class PTNode:
    def __init__(self,TNode):
        self.TNode=TNode
#+++++++++++++++++++++++++search operation+++++++++++++++++++++++++#
def SearchBST(BST,key,search,parent):
    if None==BST or None==BST.key:
        return False
    if key==BST.key:
        parent.TNode=BST.parent
        search.TNode=BST
        return True
    elif key<BST.key:
        parent.TNode=BST
        return SearchBST(BST.lchild,key,search,parent)
    else:
        parent.TNode=BST
        return SearchBST(BST.rchild,key,search,parent)
    return False
#+++++++++++++++++++++++++Insert operation+++++++++++++++++++++++++#
def InsertNode(BST,key,search):
    Pparent=PTNode(BST)
    Psearch=PTNode(BST)
    if _Debug==True:
        import pdb
        pdb.set_trace()
    if SearchBST(BST,key,Psearch,Pparent):
       return False
    parent=Pparent.TNode
    search=Psearch.TNode
    Node=TNode(key,None,None,None)
    if None==parent or None==parent.key:
        BST=Node
        return True
    if key>parent.key:
        parent.rchild=Node
    else:
        parent.lchild=Node
    Node.parent=parent
    search=Node
    return True
#+++++++++++++++++++++++++Delete operation+++++++++++++++++++++++++#
def DeleteNode(BST,key):
    Pparent=PTNode(BST)
    Psearch=PTNode(BST)
    if False==SearchBST(BST,key,Psearch,Pparent):
        return False
    parent=Pparent.TNode
    search=Psearch.TNode
    if None!=search.lchild and None!=search.rchild:
        tmp=search
        while(None!=tmp.lchild):
            tmp=tmp.lchild
        tmp.lchild=search.lchild
        if None!=parent and search==parent.lchild:

            parent.lchild=search.rchild
            search.rchild.parent=parent
        elif None!=parent and search==parent.rchild:
            parent.rchild=search.rchild
            search.rchild.parent=parent

    elif None!=search.lchild:
        if None!=parent and search==parent.lchild:
            parent.lchild=search.lchild
            search.lchild.parent=parent
        elif None!=parent and search==parent.rchild:
            parent.rchild=search.lchild
            search.lchild.parent=parent
    elif None!=search.rchild:
        if None!=parent and search==parent.lchild:
            parent.lchild=search.rchild
            search.rchild.parent=parent
        elif None!=parent and search==parent.rchild:
            parent.rchild=search.rchild
            search.rchild.parent=parent
    else:
        parent.lchild=None
        parent.rchild=None
    del search
    search=None
    return True
#+++++++++++++++++++++++++Release operation+++++++++++++++++++++++++#
def DeleteBST(BST):
    if None!=BST:
        if None==BST.lchild and None==BST.rchild:
            tmp=BST.parent
            if tmp!=None and tmp.lchild==BST:
                tmp.lchild=None
            elif tmp!=None and tmp.rchild==BST:
                tmp.rhicld=None
            del BST
            BST=None
            return
        DeleteBST(BST.lchild)
        DeleteBST(BST.rchild)

#+++++++++++++++++++++++++Print  operation+++++++++++++++++++++++++#
def PrintBST(BST):
    if None==BST:
        return
    print BST.key
    PrintBST(BST.lchild)
    PrintBST(BST.rchild)
#++++++++++++++++++++++++++Test operation++++++++++++++++++++++++++#
if __name__=='__main__':
    BST=TNode(0,None,None,None)
    Pparent=PTNode(BST)
    Psearch=PTNode(BST)
    for i in range(1,4):
        if False==InsertNode(BST,i,Psearch.TNode):
            print 'Insert Number %d Failed.'%(i)
    print 'print BST:'
    PrintBST(BST)
    if True==SearchBST(BST,1,Psearch,Pparent):
        print 'Find 1 in BST Sucess.'
    if True==DeleteNode(BST,1):
            print 'Delete 1 Success.'
    if False==SearchBST(BST,1,Psearch,Pparent):
        print 'Find 1 in BST Failed.'

    DeleteBST(BST)
    print 'Done'

4.      二叉排序树的查找复杂度

最坏复杂度为O(n),最好为O(1)

参考:《数据结构(C语言版)》严蔚敏 吴为民

时间: 2024-10-29 05:02:00

二叉排序树(C与Python分别实现)的相关文章

Python 常用查找数据结构及算法

一.基本概念 二.无序表查找 三.有序表查找 3.1 二分查找(Binary Search) 3.2 插值查找 3.3 斐波那契查找 四.线性索引查找 4.1 稠密索引 4.2 分块索引 4.3 倒排索引 五.二叉排序树 六. 平衡二叉树 七.多路查找树(B树) 7.1 2-3树 7.2 2-3-4树 7.3 B树 7.4 B+树 八.散列表(哈希表) 8.1 散列函数的构造方法 8.2 处理散列冲突 8.3 散列表查找实现 8.4 散列表查找性能分析 参考书目<大话数据结构> 一.基本概念

判断一棵树是否为二叉搜索树(二叉排序树) python

输入一棵树,判断这棵树是否为二叉搜索树.首先要知道什么是排序二叉树,二叉排序树是这样定义的,二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有键值相等的节点 #方法1,直接判断 直接判断的关键在于不能只是单纯地判断根.左.右三个节点的大小关系,左子树的右节点不仅要大于父节点,还要小于父节点的父节点,右子树的左节点

python 二叉排序树

class BSTNode: def __init__(self, data, left=None, right=None): self.data = data self.left = left self.right = right class BinarySortTree: def __init__(self): self._root = None def is_empty(self): return self._root is None def search(self, key): bt =

各种排序算法python和java实现(二)

第一篇博客实现了三种最基本最简单的排序算法,本篇文章将在这三种算法的基础上稍微演变一下. 1.快排 光从名字看就知道速度肯定不差,前一篇讲的冒泡排序,怎么看都不算是一种好的排序算法,里面充斥了太多的无谓的交换动作,时间复杂度倒是很稳定o(n^2),但对于排序算法实在说不过去.快排是冒泡排序的改进版,思路就是分治,将一个序列随机按照某个值分成两个子序列,子序列A里面的值全部比该值大,另一个子序列B的值全部比该值小,这听起来像是二叉排序树.然后依次对子序列进行如上操作,很明显快排最简单的实现就是用递

Python之路,Day21 - 常用算法学习

Python之路,Day21 - 常用算法学习 本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一个算法的优劣可以用空间复杂度与时间复杂度来衡量. 一个算

python实现二叉树和它的七种遍历

介绍: 树是数据结构中非常重要的一种,主要的用途是用来提高查找效率,对于要重复查找的情况效果更佳,如二叉排序树.FP-树.另外可以用来提高编码效率,如哈弗曼树. 代码: 用python实现树的构造和几种遍历算法,虽然不难,不过还是把代码作了一下整理总结.实现功能: 树的构造 递归实现先序遍历.中序遍历.后序遍历 堆栈实现先序遍历.中序遍历.后序遍历 队列实现层次遍历 #coding=utf-8 class Node(object): """节点类""&qu

C语言强化(一)二叉排序树转成排序的双向链表

几乎每一位码士的编程起点都是C,在玩过了Java.C#.PHP.Python之后,重回C语言,又是什么样的一种感觉呢? 此篇博文作为 [C语言强化]系列文章的第一篇,来聊聊曾让许多码士抓耳挠腮的二叉树. 通过这道题,你可以掌握 如何创建二叉树 如何遍历二叉树 如何创建二叉链表 怎样使用递归算法 这是一道非常老土但又十分经典的数据结构题,或许很多人会说自己之前已经做过了,但又有多少人回过头来做的时候,可以不借助任何参考资料把解题思路写出来? 题目要求:二叉排序树->双向链表排序 不能新增结点,只能

python学习之第十九天

本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一个算法的优劣可以用空间复杂度与时间复杂度来衡量. 一个算法应该具有以下七个重要的特征: ①有穷性(Fin

python中文语料分词处理,按字或者词cut_sentence

cut_sentence.py import string import jieba import jieba.posseg as psg import logging #关闭jieba日制 jieba.setLogLevel(logging.INFO) jieba.load_userdict("./corpus/keywords.txt") stopwords_path = "./corpus/stopwords.txt" stopwords = [i.strip