算法导论第十二章-二叉搜索树的插入(递归与非递归),中序输出(递归,用栈,既不用栈也不递归)以及节点的删除

算法导论第十二章-二叉搜索树的插入(递归与非递归),中序输出(递归,用栈,既不用栈也不递归)以及节点的删除

本文章中建立的树结构如下:


#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
#include <time.h>

using namespace std;
typedef struct Node
{
	int key;
	Node* parent;
	Node* leftChild;
	Node* rightChild;
};
typedef struct Tree
{
	Node* root;
};
struct NodeStack
{
	Node** node;//最大容量大于搜索树的高度即可
	int top;
	void push(Node* n);
	Node* pop(void);
};

void NodeStack::push(Node* n)
{
	node[top++] = n;
}

Node* NodeStack::pop(void)
{
	return node[--top];
}

//循环方式实现树结点的插入,中序输出
//输入的tree都可以为NULL

//插入   
void TREE_INSERT(Tree *tree,Node* z)
{
	Node* x = tree->root;
	Node* y = NULL;
	while(x != NULL)
	{
		y = x;
		if(z->key<x->key)
			x = x->leftChild;
		else
			x = x->rightChild;
	}
	if(y == NULL)//树为空树
	{
		tree->root = z;
		z->parent = NULL;
	}
	else if(z->key < y->key)
	{
		y->leftChild = z;
		z->parent = y;
	}
	else
	{
		y->rightChild = z;
		z->parent = y;
	}
}
//用一个栈中序输出二叉树
void printTreeByStack(Node* root)
{
	if(root == NULL)
	{
		cout<<"NULL tree.";
		return ;
	}
	NodeStack* nodeStack = new NodeStack;
	nodeStack->node = new Node*[10];
	nodeStack->top = 0;
	while(nodeStack->top != 0 || root != NULL)//输出根结点的时候,会出现栈为空的情况,所以再加上对root是否为空的判断
	{
		while(root != NULL)
		{
			nodeStack->push(root);
			root = root->leftChild;
		}
		root = nodeStack->pop();
		cout<<root->key<<"  ";
		root = root->rightChild;
	}
}

//不递归  也不用栈中序输出
void print(Node* root)
{
	if(root == NULL)
	{
		cout<<"NULL tree.";
		return ;
	}
	Node* y = NULL;
	while(root != NULL  )
	{
		//if(root->leftChild != NULL && root->parent == y)//root->parent == y表明是在沿着树向下搜索
		//					                // 左子树不为空
		//{
		//	y = root;
		//	root = root->leftChild;
		//}
		//else if(root->rightChild != NULL && root->parent == y)//向下搜索  左子树为空 右子树不为空
		//{
		//	cout<<root->key<<"  ";
		//	y = root;
		//	root = root->rightChild;
		//}
		//else if(root->leftChild == NULL && root->rightChild == NULL )//左右子树都为空 也就说明一定是在向下搜索  
		//{
		//	cout<<root->key<<"  ";
		//	y = root;
		//	root = root->parent;
		//}
		if(root->parent == y)//这是对上面三种情况的一个综合  精简代码
		{
			y = root;
			//如果 左子树不为空取左子树
			//如果左子树为空  右子树不为空  取右子树
			//如果左右子树都为空   取父结点 
			root = root->leftChild?root->leftChild:
				   root->rightChild?root->rightChild:root->parent;
			if(y->leftChild != root)//除了左子树不为空的情况  都需要输出
				cout<<y->key<<"  ";
		}


		else if(root->leftChild == y )//左子树向上回退的情况
		{
			cout<<root->key<<"  ";
			if(root->rightChild != NULL)
			{
				y = root;
				root= root->rightChild;
			}
			else//root->rightChild为空  继续回退
			{
				y = root;
				root = root->parent;
			}
		}
		else  //右子树向上回退  就直接回退
		{
			y = root;
			root = root->parent;
		}
	}
}



//递归实现二叉搜索树的插入,中序输出,输入可以为空
// 插入
void TREE_INSERT_recursive(Node* node,Node* z,Node* p)
{
	if(node == NULL)
	{
		if(z->key<p->key)
		{
			p->leftChild = z;
			z->parent = p;
		}
		else
		{
			p->rightChild = z;
			z->parent = p;
		}
	}
	else
	{
		if(z->key<node->key)
			TREE_INSERT_recursive(node->leftChild,z,node);
		else
			TREE_INSERT_recursive(node->rightChild,z,node);
	}
}
void TREE_INSERT_recursivePrehandle(Tree *tree,Node* z)
{
	if(tree->root == NULL)
	{
		tree->root = z;
		z->parent = NULL;
	}
	else
	{
		TREE_INSERT_recursive(tree->root,z,NULL);
	}
}
//中序输出
void printTreeRecursive(Node* node)
{
	if(node == NULL)
		return;
	printTreeRecursive(node->leftChild);
	cout<<node->key<<"  ";
	printTreeRecursive(node->rightChild);
}




//替换节点  输入:两个节点 u v ,让u的父节点直接指向v,并设v的父节为点u的父节点
void TreeNode_replace(Tree* tree, Node* u, Node* v)
{
	if(u->parent == NULL)//要被替换的是根结点
	{
		tree->root = v;
	}
	else
	{
		if(u == u->parent->leftChild)
			u->parent->leftChild = v;
		else
			u->parent->rightChild = v;
	}
	if(v != NULL)
		v->parent = u->parent;
}

//删除元素  
void Tree_delete(Tree* tree, Node* z)
{
	// if(z->leftChild == NULL && z->rightChild == NULL)
	// {
	// 	if(z==z->parent->leftChild)
	// 		z->parent->leftChild = NULL;
	// 	else
	// 		z->parent->rightChild = NULL;	
	// }
	// else if(z->leftChild == NULL)
	// {
	// 	if(z==z->parent->leftChild)
	// 	{
	// 		z->parent->leftChild = z->rightChild;
	// 		z->rightChild->parent = z->parent;
	// 	}
	// 	else
	// 	{
	// 		z->parent->rightChild = z->rightChild;
	// 		z->rightChild->parent = z->parent;	
	// 	}
	// }
	// else if(z->rightChild == NULL)
	// {
	// 	if(z==z->parent->leftChild)
	// 	{
	// 		z->parent->leftChild = z->leftChild;
	// 		z->leftChild->parent = z->parent;
	// 	}
	// 	else
	// 	{
	// 		z->parent->rightChild = z->leftChild;
	// 		z->leftChild->parent = z->parent;	
	// 	}
	// }
	//下面两种情况是对上面三种情况的合并与精简
	if(z->leftChild == NULL)
	{
		TreeNode_replace(tree,z,z->rightChild);
	}
	else if(z->rightChild == NULL)
	{
		TreeNode_replace(tree,z,z->leftChild);
	}



	else//左右子树都不为空
	{
		Node* y = z->rightChild;
		while(y->leftChild!=NULL)//获得z的后继结点
			y = y->leftChild;
		if(y != z->rightChild)
		{
			TreeNode_replace(tree,y,y->rightChild);
			y->rightChild = z->rightChild;
			y->rightChild->parent = y;
		}
		TreeNode_replace(tree,z,y);
		y->leftChild = z->leftChild;
		z->leftChild->parent = y;
	}
}

int main()
{
	int a[13] = {5,3,2,1,4,6,7,9,8,13,12,10,11};
	//非递归
	Tree* testTree = new Tree;
	testTree->root = NULL;
	for(int i=0;i<13;i++)
	{
		Node* node = new Node;
		node->key = a[i];
		node->parent = NULL;
		node->leftChild = NULL;
		node->rightChild = NULL;
		TREE_INSERT(testTree,node);
	}
	cout<<"用循环的方式插入元素建树:"<<endl<<"Build succeed!"<<endl;
	cout<<"用栈输出:"<<endl;
	printTreeByStack(testTree->root);
	cout<<endl<<"既不用递归,也不用栈输出:"<<endl;
	print(testTree->root);
	cout<<endl<<endl;


	cout<<"用递归的方式插入元素建树:"<<endl<<"Build succeed!"<<endl;
	Tree* RecursiveTestTree = new Tree;
	RecursiveTestTree->root = NULL;
	for(int i=0;i<13;i++)
	{
		Node* node = new Node;
		node->key = a[i];
		node->parent = NULL;
		node->leftChild = NULL;
		node->rightChild = NULL;
		TREE_INSERT_recursivePrehandle(RecursiveTestTree,node);
	}
	cout<<"用递归的方式输出:"<<endl;	
	printTreeRecursive(RecursiveTestTree->root);
	//删除节点
	Node* deleteNode = RecursiveTestTree->root;
	int key = 9;
	while(deleteNode->key!=key  && deleteNode != NULL)
	{
		if(key < deleteNode->key)
			deleteNode = deleteNode->leftChild;
		else
			deleteNode = deleteNode->rightChild;
	}
	Tree_delete(RecursiveTestTree,deleteNode);
	cout<<endl<<"删除节点"<<key<<"后:"<<endl;
	printTreeRecursive(RecursiveTestTree->root);
	cout<<endl;
	return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值