zoukankan      html  css  js  c++  java
  • 二叉排序树

    二叉排序树(Binary Sort Tree):或者是一颗空树,或者是具有下面性质的树:(1)若它的左子树不空,则左子树上所以结点的值均小于它的根节点的值;(2)若它的右子树不空,则右子树上的所以结点的值均大于它的根节点的值;(3)它的左、右子树也各自是二叉排序树。

    二叉排序树的基本操作均能够在O(h)时间内完毕(算法导论p165)。

    相关操作代码例如以下:

    int InsertBST(BiTree &T, int key)//递归插入
    {
    	if (T == NULL)
    	{
    		T = new BiNode;
    		T->data = key;
    		T->lchild = T->rchild = NULL;
    		return 1;
    	}
    	else
    	{
    		if (key == T->data)
    			return 0;
    		else if (key < T->data)
    			return InsertBST(T->lchild, key);
    		else
    			return InsertBST(T->rchild, key);
    	}
    }
    
    int InsertBST_(BiTree &T, int key)//迭代插入
    {
    	//find the insert position
    	BiNode *f = T, *p = T;
    	while (p != NULL)
    	{
    		if (key == p->data)
    			return 0;
    		f = p;	//记录上一次訪问的结点
    		p = key < p->data ? p->lchild : p->rchild;
    	}
    
    	//分配新结点
    	BiNode *q = new BiNode;
    	q->lchild = q->rchild = NULL;
    	q->data = key;
    
    	//插入
    	if (T == NULL)	//若根为空
    	{
    		T = q;
    		return 1;
    	}
    	if (key < f->data)
    		f->lchild = q;
    	else
    		f->rchild = q;
    	return 1;
    }
    
    BiNode *SearchBST(BiTree T, int key)//递归搜索
    {
    	if (!T)
    		return NULL;
    	else
    	{
    		if (key == T->data)
    			return T;
    		else if (key < T->data)
    			return SearchBST(T->lchild, key);
    		else
    			return SearchBST(T->rchild, key);
    	}
    }
    
    BiNode* SearchBST_(BiTree T, int key)//迭代搜索
    {
    	while (T != NULL)
    	{
    		if (key == T->data)
    			break;
    		T = key < T->data ? T->lchild : T->rchild;
    	}
    	return T;
    }
    
    int DeleteNode(BiNode *&p)
    {
    	BiNode *q;
    	//从二叉排序树中删除结点p,并重接它的的左或右子树
    	if (p == NULL)	return 0;
    	if (p->lchild == NULL)	 //左子树空则仅仅需重接右子树
    	{
    		q = p; p = p->rchild; delete q;
    	}
    	else if (p->rchild == NULL)	  //右子树空则仅仅需重接左子树
    	{
    		q = p; 
    		p = p->lchild; 
    		delete q;
    	}
    	else	//左右子树均不空
    	{
    		BiNode *s;
    #if 0	
    		//用p的直接前驱取代p,然后删除p的直接前驱
    		q = p; s = p->lchild;//转左,然后向右到尽头
    		while (s->rchild)
    		{
    			q = s; s = s->rchild;
    		}
    		p->data = s->data;	//s指向被删除结点,q指向被删除结点的前驱
    		if (q != p)
    			q->rchild = s->lchild;	//重接q的右子树
    		else
    			q->lchild = s->lchild;	//重接q的左子树
    #else
    		//用p的直接后继取代p,然后删除p的直接后继
    		q = p; s = p->rchild;
    		while (s->lchild)
    		{
    			q = s; s = s->lchild;
    		}
    		p->data = s->data;
    		if (p != p)
    			q->lchild = s->rchild;
    		else
    			q->rchild = s->rchild;
    #endif
    		delete s;
    	}
    	return 1;
    }
    
    int DeleteBST(BiTree &T, int key)
    {
    	if (T == NULL)
    		return 0;
    	else
    	{
    		if (key == T->data)
    			return DeleteNode(T);
    		else if (key < T->data)
    			return DeleteBST(T->lchild, key);
    		else
    			return DeleteBST(T->rchild, key);
    	}
    }
    
    void CreateBST(BiTree &T, int a[], int n)
    {
    	T = NULL;
    	for (int i = 0; i < n; i++)
    	{
    		InsertBST_(T, a[i]);
    	}
    }
    
    void DestoryBST(BiTree &T)
    {
    	if (T == NULL)
    		return;
    	DestoryBST(T->lchild);
    	DestoryBST(T->rchild);
    	delete T; T = NULL;
    }
    
    void InOrderTraverse(BiTree T)//=O(n)时间复杂度
    {
    	if (T == NULL)
    		return;
    	InOrderTraverse(T->lchild);
    	cout << T->data << " ";
    	InOrderTraverse(T->rchild);
    }
    測试代码:

    int main()
    {
    	const int n = 10;
    	int a[n] = {3, 2, 8, 6, 1, 4, 5, 7, 1, 3};
    	BiTree T;
    	CreateBST(T, a, n);
    	InOrderTraverse(T);
    	cout << endl;
    
    	BiNode *p;
    	for (int i = 1; i < 10; i++)
    	{
    		p = SearchBST_(T, i);
    		if (p != NULL)
    			cout << p->data << endl;
    	}
    
    	int b[5]={0, 2, 6, 1, 7};
    	int ret;
    	for (int i = 0; i < 5; i++)
    	{
    		ret = DeleteBST(T, b[i]);
    		if (ret == 0)
    			cout << "删除 " << b[i] << " 失败" << endl;
    		else
    		{
    			cout << "删除 " << b[i] << " 后: " ;
    			InOrderTraverse(T);
    			cout << endl;
    		}
    	}
    
    	DestoryBST(T);
    	getchar();
    	return 0;
    }

    參考:数据结构C语言版、算法导论(关于删除结点操作,该书p173页有注记)


  • 相关阅读:
    测试sql 查询时间
    C# 数组 ArrayList Array 在C#里把ArrayList转换为Array 或 把Array转换为ArrayList
    DotNet软件开发框架
    C# Socket多线程编程实例
    Yahoo!网站性能最佳体验的34条黄金守则
    最基本的Socket编程(C#)
    完全解决VS2008通过Internet连接VSS2005
    追MM与设计模式的有趣见解
    一个GridView的PagerTemplate
    线程
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4173662.html
Copyright © 2011-2022 走看看