小说网 找小说 无限小说 烟雨红尘 幻想小说 酷文学 深夜书屋

基于visual Studio2013解决算法导论之029二叉搜索树




题目

二叉搜索树


解决代码及点评

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

typedef struct BSTree
{
	int nValue;
	struct BSTree *pLChild;
	struct BSTree *pRChild;
}BSTree, *PBSTree;

PBSTree InsertBSTree(PBSTree pRoot, int nValue)
{
	if (pRoot == NULL)
	{
		pRoot = (PBSTree)malloc(sizeof(BSTree));
		if (!pRoot)
		{
			printf("分配内存失败!\n");
			return NULL;
		}
		pRoot->nValue = nValue;
		pRoot->pLChild = NULL;
		pRoot->pRChild = NULL;
	}
	else
	{
		if (pRoot->nValue > nValue)
		{
			pRoot->pLChild = InsertBSTree(pRoot->pLChild, nValue);
		}
		else if (pRoot->nValue < nValue)
		{
			pRoot->pRChild = InsertBSTree(pRoot->pRChild, nValue);
		}
	}

	return pRoot;
}

PBSTree SearchBSTree(PBSTree pRoot, int nValue)
{
	if (pRoot == NULL)
	{
		return NULL;
	}
	if (pRoot->nValue == nValue)
	{
		return pRoot;
	}
	else if (pRoot->nValue > nValue)
	{
		return SearchBSTree(pRoot->pLChild, nValue);
	}
	else
	{
		return SearchBSTree(pRoot->pRChild, nValue);
	}
}

//删除BST中一个结点
void DeleteNode(PBSTree *pDel)
{
	PBSTree pTmp,pLChildMax;
	if ((*pDel)->pLChild && (*pDel)->pRChild)
	{//左右子树都不为空 则将左子树中最大值的右指针指向要删除结点的右子树
		//然后将要删除结点的左子树根结点放到要删除结点的位置
		pTmp = pLChildMax = (*pDel)->pLChild;
		while (pLChildMax->pRChild)
		{
			pLChildMax = pLChildMax->pRChild;
		}
		pLChildMax->pRChild = (*pDel)->pRChild;
		free((*pDel));
		(*pDel) = pTmp;
	}
	else if (!(*pDel)->pLChild)
	{//左子树为空
		pTmp = *pDel;
		(*pDel) = (*pDel)->pRChild;
		free(pTmp);
	}
	else if (!(*pDel)->pRChild)
	{//右子树为空
		pTmp = *pDel;
		(*pDel) = (*pDel)->pLChild;
		free(pTmp);
	}

}

//删除操作
//设p,p1,r是指针变量,p↑表示s要删除的结点,
//p1↑表示p↑的父母结点,则删除可以按如下规定进行:

//1 若结点p↑没有左子树,则用右子树的根代替被删除的结点p↑

//2 若结点p↑有左子树,则在左子树里找按中序周游的最后
//一个结点r↑,将r↑的右指针置成指向p↑的右子树的根,
//然后用结点p↑的左子树的根去代替被删除的结点p↑

void DeleteBSTree(PBSTree *pRoot, int nValue)
{
	if (!SearchBSTree((*pRoot), nValue))
	{
		printf("没有该元素,无法删除!\n");
		return;
	};
	if (nValue == (*pRoot)->nValue)
	{
		DeleteNode(pRoot);
	}
	else if ((*pRoot)->nValue > nValue)
	{
		DeleteBSTree(&(*pRoot)->pLChild, nValue);
	}
	else
	{
		DeleteBSTree(&(*pRoot)->pRChild, nValue);
	}
}

PBSTree DeleteBSTree1(PBSTree pRoot, int nValue)
{
	if (pRoot == NULL)
	{
		printf("树为空!\n");
		return NULL;
	}

	if (pRoot->nValue > nValue)
	{
		pRoot->pLChild = DeleteBSTree1(pRoot->pLChild, nValue);
	}
	else if (pRoot->nValue < nValue)
	{
		pRoot->pRChild = DeleteBSTree1(pRoot->pRChild, nValue);
	}
	else
	{//pRoot即为要删除的结点
		if(pRoot->pLChild && pRoot->pRChild)
		{//左右子树都不为空
			//将左子树的最大值赋值给要删除的结点,再删除左子树的最大值结点(叶子结点)    
			PBSTree pLChildMax = pRoot->pLChild;
			while (pLChildMax->pRChild)
			{
				pLChildMax = pLChildMax->pRChild;
			}
			pRoot->nValue = pLChildMax->nValue;

			pRoot->pLChild = DeleteBSTree1(pRoot->pLChild, pRoot->nValue);
		}
		else
		{
			PBSTree pTmp = pRoot;
			if (pRoot->pLChild == NULL)
			{//右子树为空
				pRoot = pRoot->pLChild;
			}
			else if (pRoot->pRChild == NULL)
			{//左子树为空
				pRoot = pRoot->pLChild;
			}

			delete pTmp;
		}   
	}
	return pRoot;
}

void InOrder(PBSTree pRoot)
{
	if (!pRoot)
	{
		return;
	}
	InOrder(pRoot->pLChild);
	printf("%d ", pRoot->nValue);
	InOrder(pRoot->pRChild);
}

PBSTree GetParent(PBSTree pRoot, int nValue)
{
	if (pRoot == NULL)
	{//BST树为空
		return NULL;
	}

	if (pRoot->pLChild && pRoot->pLChild->nValue == nValue)
	{
		return pRoot;
	}
	if (pRoot->pRChild && pRoot->pRChild->nValue == nValue)
	{
		return pRoot;
	}

	PBSTree ptemp = NULL;
	ptemp = GetParent(pRoot->pLChild, nValue);
	if(ptemp != NULL)
		return ptemp;

	ptemp = GetParent(pRoot->pRChild, nValue);
	if(ptemp != NULL)
		return ptemp;
}
int main()
{
	PBSTree pRoot = NULL;
	int data[] = {12,3,2,34,1,23,44,667,23,3};
	for (int i = 0; i < sizeof(data) / sizeof(int); i++)
	{
		pRoot = InsertBSTree(pRoot, data[i]);
	}

	InOrder(pRoot);
	PBSTree p = SearchBSTree(pRoot, 311);
	if (p)
	{
		printf("有该元素%d\n", p->nValue);
	}
	else
	{
		printf("没有该元素!\n");
	}

	//DeleteBSTree1(pRoot, 12);
	printf("\n");
	InOrder(pRoot);

	p = GetParent(pRoot, 23);
	if (p)
	{
		printf("父结点为%d\n", p->nValue);
	}
	else
	{
		printf("无父结点!\n");
	}

	system("pause");

	return 0;
}


代码下载及其运行

代码下载地址:http://download.csdn.net/detail/yincheng01/6858815

解压密码:c.itcast.cn


下载代码并解压后,用VC2013打开interview.sln,并设置对应的启动项目后,点击运行即可,具体步骤如下:

1)设置启动项目:右键点击解决方案,在弹出菜单中选择“设置启动项目”


2)在下拉框中选择相应项目,项目名和博客编号一致

3)点击“本地Windows调试器”运行


程序运行结果









posted on 2014-01-17 20:57  牛栏山1  阅读(94)  评论(0编辑  收藏  举报

导航