树形结构 二叉查找树

对于任意结点,左子树的所有结点值小于自身的值,右子树的所有结点值大于自身的值;

左右子树也是二叉查找树;

#include<stdio.h>

#include<stdlib.h>

typedef struct BSTreeNode {

	int key;//关键值

	BSTreeNode *left;//左孩子

	BSTreeNode *right;//右孩子

	BSTreeNode *parent;//父结点

}Node,BSTree;*

//创建一个结点

static Node create_bstree_node(int key, Node *parent, Node *left, Node right)

{

	Node p=(Node)malloc(sizeof(Node));

	if (p == NULL)

		return NULL;

	p->key = key;

	p->left = left;

	p->right = right;

	p->parent = parent;

	return p;

}

//三种遍历重点在于对于当前节点的操作在先、中还是后

//先序遍历

void preoder_bstree(BSTree tree)

{

	if (tree != NULL)

	{

		printf("%d ", tree->key);

		preoder_bstree(tree->left);

		preoder_bstree(tree->right);

	}

}

//中序遍历

void inorder_bstrss(BSTree tree)

{

	if (tree != NULL)

	{

		inorder_bstrss(tree->left);

		printf("%d ", tree->key);

		inorder_bstrss(tree->right);

	}

}

//后序遍历

void postorder_bstree(BSTree tree)

{

	if (tree != NULL)

	{

		postorder_bstree(tree->left);

		postorder_bstree(tree->right);

		printf("%d ", tree->key);

	}

}

//查找

//递归版

*Node bstree_search(BSTree x, int key)

{

	if (x == NULL || x->key == key)

		return x;

	if (key < x->key)//根据bstrss的性质

		return bstree_search(x->left, key);

	else

		return bstree_search(x->right, key);

}

//非递归版

Node iterative_bstree_search(BSTree x, int key)*

{

	while ((x != NULL) && (x->key != key))

	{

		if (key < x->key)

			x = x->left;

		else

			x = x->right;

	}

return x;

}

//查找最值

Node bstree_maximum(BSTree tree)*

{

	if (tree == NULL)

		return NULL;

while (tree->right != NULL)

	tree = tree->right;

return tree;

}

Node bstree_minimum(BSTree tree)*

{

	if (tree == NULL)

		return NULL;

while (tree->left != NULL)

	tree = tree->left;

return tree;

}

//查找前驱和后继

Node bstree_predecessor(Node x)

{

	//如果x存在左孩子,则x的前驱结点为以其左孩子为跟的子树的最大根节点

	if (x->left != NULL)

		return bstree_maximum(x->left);

	//如果x没有左孩子,那么有两种情况

	//(1)x是一个右孩子,则x的前驱就是它的父结点

	//(2)x是一个左孩子,则查找x的最低父结点,且父结点要有右孩子

	Node* y = x->parent;

	while (y != NULL && x == y->left)//画图可知在找一个可能比x小的结点

	{

		x = y;

		y = y->parent;

	}

	return y;

}

Node bstree_successor(Node x)

{

	// 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。

	if (x->right != NULL)

		return bstree_minimum(x->right);

// 如果x没有右孩子。则x有以下两种可能:

// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。

// (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。

Node y = x->parent;*

while ((y != NULL) && (x == y->right))

{

	x = y;

	y = y->parent;

}

return y;

}

//插入节点(建树),每次插入的都是叶子结点

static Node bstree_insert(BSTree tree, Node z)

{

	Node *y = NULL;

	Node *x = tree;

// 查找z的插入位置

while (x != NULL)

{

	y = x;

	if (z->key < x->key)

		x = x->left;

	else  if (z->key > x->key)

		x = x->right;

	else

	{

		free(z); // 释放之前分配的系统,有相同的值

		return tree;

	}

}

z->parent = y;

if (y == NULL)

	tree = z;

else if (z->key < y->key)

	y->left = z;

else

	y->right = z;

return tree;

}

Node insert_bstree(BSTree tree, int key)*

{

	Node *z;    // 新建结点

			// 如果新建结点失败,则返回。

if ((z = create_bstree_node(key, NULL, NULL, NULL)) == NULL)

	return tree;

return bstree_insert(tree, z);

}

static Node* bstree_delete(BSTree tree, Node z)

{

    Node *x=NULL;

    Node *y=NULL;

if ((z->left == NULL) || (z->right == NULL) )

    y = z;//z左右子树不都有,直接在z上操作,接上去就好了

else

    y = bstree_successor(z);//否则需要找到直接后继	

if (y->left != NULL)

    x = y->left;

else

    x = y->right;

if (x != NULL)

    x->parent = y->parent;

if (y->parent == NULL)

    tree = x;

else if (y == y->parent->left)

    y->parent->left = x;

else

    y->parent->right = x;

if (y != z) 

    z->key = y->key;

if (y!=NULL)

    free(y);

return tree;

}

Node delete_bstree(BSTree tree, Type key)*

{

    Node *z, *node; 

if ((z = bstree_search(tree, key)) != NULL)

    tree = bstree_delete(tree, z);

return tree;

}

猜你喜欢

转载自blog.csdn.net/qq_40061421/article/details/81350032