面试--二叉搜索树的常见添加删除前继后继

#include<iostream>
#include<vector>
#include<queue>
#include<string>
#include<stack>
using namespace std;

/*
    二叉搜索树比二叉树多一个性质,左节点的值小于父节点的值,右节点的值大于等于父节点的值
	二叉搜索树右可以排序,平衡二叉搜索树有红黑树,AVL树,此处仅是一般二叉搜索树。
	二叉搜索树通常设计比一般二叉树多一个父节点域,否则要反复找出某个节点的父节点
*/


struct Node
{
	int key;
	Node* left;
	Node* right;
	Node* parent;
	Node(int a)
	{
		key = a;
	   left = right=parent=nullptr;
	}

	///为了代码简洁,此处二叉树节点比较仅仅比较值是否相等
	bool operator==(Node * other)
	{
		return key == other->key;
	}

	bool operator!=(Node* other)
	{
		return key != other->key;
	}

};

///返回以p为树根的树中最大节点
Node* maxNode(Node* p)
{
	if (p->right != nullptr)
	{
		while (p->right)
		{
			p = p->right;
		}
	}
	return p;
}

///返回以p为树根的树中最小节点
Node* minNode(Node* p)
{
	if (p->left != nullptr)
	{
		while (p->left)
		{
			p = p->left;
		}
	}
	return p;
}

/*
返回节点p的后继若不存在返回nullptr
*/
Node* successor(Node* root, Node* p)
{
	Node* result = nullptr;
	if (p->right != nullptr)
	{
		result = minNode(p->right);
	}
	else
	{
		while (p->parent!=nullptr&&p->parent->right == p)
		{
			p = p->parent;
		}
		if (p->parent != nullptr)
		{
			result = p->parent;
		}
	}
	return result;
}

Node* pressor(Node* root, Node* p)
{
	Node* result = nullptr;
	if (p->left != nullptr)
	{
		result = maxNode(p->left);
	}
	else
	{
		while (p->parent != nullptr&&p->parent->left == p)
		{
			p = p->parent;
		}
		if (p->parent != nullptr)
		{
			result = p->parent;
		}
	}
	return result;
}


Node* insertNode(Node* root, int k)
{
	if (root == nullptr)
	{
		root = new Node(k);
		return root;
	}
	else
	{
		Node* p=root,*q = root;
		Node*temp = new Node(k);
		while (p)
		{
			if (k < p->key)
			{
				q = p;
				p = p->left;
			}
			else
			{
				q = p;
				p = p->right;
			}
		}
		if (k < q->key)
		{
			q->left = temp;
			temp->parent = q;
		}
		else
		{
			q->right = temp;
			temp->parent = q;
		}
	}
	return root;
}

/*
找出一个节点的值等于k
*/
Node* searchNode(Node* root, int k)
{
	Node* p = root;
	while (p)
	{
		if (p->key == k)
		{
			return p;
		}
		else if (k < p->key)
		{
			p = p->left;
		}
		else
		{
			p = p->right;
		}
	}
	return p;
}

Node* deleteNode(Node* root, Node* p)
{
	if (root == nullptr||p==nullptr)return root;
	if (p->left == nullptr || p->right == nullptr)
	{
		if (p->left != nullptr)
		{
			Node* temp = p->left;
			temp->parent = p->parent;
			if (p->parent != nullptr) ///p不是根节点
			{
				if (p->parent->left == p)
					p->parent->left = temp;
				else
					p->parent->right = temp;
			}
			else    ///p是根节点
			{
				root = temp;
			}
			delete p;
			p = nullptr;
		}
		else if (p->right != nullptr)
		{
			Node* temp = p->right;
			temp->parent = p->parent;
			if (p->parent != nullptr)
			{
				if (p->parent->left == p)
					p->parent->left = temp;
				else
					p->parent->right = temp;
			}
			else
			{
				root = temp;
			}
			delete p;
			p = nullptr;
		}
		else
		{
			if (p ->parent== nullptr)
				root = nullptr;
			else
			{
				if (p->parent->left == p)
					p->parent->left = nullptr;
				else
					p->parent->right = nullptr;
			}
			delete p;
			p = nullptr;
		}
	}
	else   ///p的两个孩子都不为空
	{
		Node* temp = minNode(p->right);
		p->key = temp->key;
		///此时temp的左孩子肯定为nullptr,
		if (temp->right != nullptr)
		{
			temp->right->parent = temp->parent;
			if (temp->parent->left == temp)
				temp->parent->left = temp->right;
			else
				temp->parent->right = temp->right;
		}
		else
		{
			if (temp->parent->right == temp)
				temp->parent->right = nullptr;
			else 
				temp->parent->left = nullptr;
		}
		delete temp;
	}
	return root;
}

/*
删除所有值为k的节点
*/
Node* deleteNode(Node* root, int k)
{
	Node* p = searchNode(root, k);
	
	while (p!=nullptr&&p->key==k)
	{
		root=deleteNode(root, p);
		////这里犯了一个错误,查找了半天还一直以为删除节点出了问题,指针果然nb
		///经过上一步指针p指向的空间已经被删除了,所以下一步寻找p的后继会出错。
		p = searchNode(root,k);
	}
	
	return root;
}



Node* buildTree(int a[], int n)
{
	Node* root = nullptr;
	for (int i = 0; i < n; i++)
	{
		root = insertNode(root, a[i]);
	}
	return root;
}

void tree_sort(Node* root)
{
	if (root == nullptr)return;
	Node* p = minNode(root);
	while (p != nullptr)
	{
		cout << p->key << " ";
		p = successor(root, p);
	}
	cout << endl;
	
	p = maxNode(root);
	while (p != nullptr)
	{
		cout << p->key << " ";
		p = pressor(root, p);
	}
	cout << endl;
	
}


void levelOrder3(Node* p)
{
	if (p == nullptr)return;
	queue<Node*>qu;
	qu.push(p);
	while (!qu.empty())
	{
		p = qu.front();
		cout << p->key << " ";
		qu.pop();
		if (p->left != nullptr)
		{
			qu.push(p->left);
		}
		if (p->right != nullptr)
		{
			qu.push(p->right);
		}
	}
}

/*
int main()
{
	const int len = 30;
	int a[len];
	srand(1);
	for (int i = 0; i < len; i++)
	{
		a[i] = rand() % 30;
		if (a[i] == 0)a[i] += 1;
	}
	a[0] = 15;
	cout << endl << "=======数组a=====" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;

	Node* root=buildTree(a, len);
	cout << endl << "=======逐层遍历=====" << endl;
	levelOrder3(root);
	cout << endl<<"=======排序====="<<endl;
	tree_sort(root);
	cout << endl;
	while (true)
	{
		int m;
		cin >> m;
		root = deleteNode(root, m);
		cout << endl << "=======逐层=====" << endl;
		levelOrder3(root);
		cout << endl;
		cout << endl << "=======排序=====" << endl;
		tree_sort(root);
	}
}
*/

  

posted on 2016-04-09 22:45  徒步者_金伟  阅读(311)  评论(0编辑  收藏  举报