1. 程式人生 > >二叉查詢樹後繼節點和前驅節點查詢

二叉查詢樹後繼節點和前驅節點查詢

二叉查詢樹按照二叉樹進行組織。二叉查詢樹關鍵字的儲存方式總是瞞住二叉查詢樹性質:

設x為二查查詢樹種一個節點。如果y是x的左子樹中的一個節點,那麼key[x] >= key[y]。如果y是x的右子樹的一個節點,那麼key[x] <= key[y]。

這樣對二叉查詢樹進行中序遍歷就可得到書中所有元素的一個非降序排列。

查詢某一個存在節點的前驅和後繼。某一個節點x的後繼就是大於key[x]的關鍵字中最小的那個節點,前驅就是小於key[x]的關鍵字中最大的那個節點。查詢二叉前驅和後繼節點的演算法如下所示:

typedef struct _node
{
	struct _node* lchild;
	struct _node* rchild;
	struct _node* parent;
	int data;
}node;		//二叉樹結構體定義,是帶父節點的哦。

typedef node* Tree;

//查詢二叉樹中關鍵字最小的節點,返回指向該指標的節點。
Tree iterative_searchTree(Tree root, int k)
{
	Tree p = root;
	while (p != NULL && k != p->data)
	{
		if (k < p->data)
		{
			p = p->lchild;
		}
		else
			p = p->rchild;
	}
	return p;
}

Tree Tree_Minmum(Tree root)
{
	Tree p = root;
	while (p->lchild != NULL)
	{
		p=p->lchild;
	}
	return p;
}

Tree Tree_Maximum(Tree root)
{
	Tree p = root;
	while (p->rchild != NULL)
	{
		p=p->rchild;
	}
	return p;
}

Tree Tree_Successor(Tree p)
{
	while(p->rchild != NULL)
	{
		return Tree_Minmum(p->rchild);	//一種情況,找該節點右子樹中關鍵字最小的節點。
	}
	
	Tree q = p->parent;
	while (q != NULL && p == q->rchild)	//另一種情況,該節點不存在右子樹,則尋找該節點最低的公共祖先。
	{
		p = q;
		q = q->parent;
	}
	return q;
}

Tree Tree_Presuccessor(Tree p)
{
	while (p->lchild != NULL)
	{
		return Tree_Maximum(p->lchild);	//一種情況,找該節點左子樹中關鍵字最大的節點。
	}

	Tree q = p->parent;
	while (q != NULL && p == q->lchild)	//另一種情況,該節點不存在左子樹,則尋找該節點最低的公共祖先。
	{
		p = q;
		q = q->parent;
	}
	return q;
}