zoukankan      html  css  js  c++  java
  • 数据结构--二叉查找树

    二叉查找树(Binary Search Tree),又被称为二叉搜索树。
    它是特殊的二叉树:对于二叉树,假设x为二叉树中的任意一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]。那么,这棵树就是二叉查找树。如下图所示:

    在二叉查找树中:
    (01) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    (02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    (03) 任意节点的左、右子树也分别为二叉查找树。
    (04) 没有键值相等的节点(no duplicate nodes)。

    查找节点:

    若二叉查找树为空,则查找失败
    若该树非空且查找数据x等于根节点的值,则查找成功,返回根节点
    若该树非空且查找数据x小于根节点的值,则查找左子树,直到值相等,并返回节点
    若该树非空且查找数据x大于根节点的值,则查找右子树,直到值相等,并返回节点
    插入节点:

    若二叉查找树为空,则将结点作为根节点插入
    若所插入节点关键字值等于根节点的值,则插入失败,并返回
    若所插入节点关键字值小于根节点的值,则把节点插入到左子树中
    若所插入节点关键字值大于根节点的值,则把节点插入到右子树中
    删除节点:


    若p结点为叶子结点,则删去该叶子结点,修改其双亲结点的指针即可。
    若p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点的左子树(当p是左子树)或右子树(当p是右子树)。
    若p结点的左子树和右子树均不空。找出节点p的后继节点y(一定在节点p的右子树中),以右子树中的最小数作为后继节点。

    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    #define LENGTH 11
    struct BinSearNode
    {
    	int key;
    	struct BinSearNode *left_child;
    	struct BinSearNode *right_child;
    	struct BinSearNode *parent;
    }Node;
    typedef struct BinSearNode *PNode;
    /*Search the node of the tree*/
    PNode Search_Tree(PNode root, int key)
    {
    	PNode x = root;
    	//the tree is not empty and the key is not equal
    	while (NULL != x && x->key != key)
    	{
    		if (x->key<key)
    			x = x->right_child;//along the right child of tree,until it is empty
    		else
    			x = x->left_child;//along the left child of tree,until it is empty
    	}
    	return x;//return the node
    }
    /*the minimum key of node in the tree*/
    PNode Minimum_Tree(PNode root)
    {
    	PNode x = root;
    	while (NULL != x->left_child)
    	{
    		x = x->left_child;
    	}
    	return x;
    }
    /*the maxmum key of node in the tree*/
    PNode Maxmum_Tree(PNode root)
    {
    	PNode x = root;
    	while (NULL != x->right_child)
    	{
    		x = x->right_child;
    	}
    	return x;
    }
    /*the successor node of the x,后继节点可以这么理解,将查找树从小到大排序,比他大的值
    如果有右孩子,那么应该是右子树当中的最小值
    如果没有右孩子,那么应该向上追溯,直至一个分支节点是其父节点的左孩子,返回父节点
    可以用于operate++*/
    PNode Successor_Tree(PNode x)
    {
    	PNode y = NULL;
    	//case 1:the right subtree of node x is not empty
    	if (NULL != x->right_child)
    	{
    		y = Minimum_Tree(x->right_child);
    	}
    	//case 2:the right subtree of node x is empty
    	//and the node of x has a successor node y
    	else
    	{
    		y = x->parent;
    		while (NULL != y && x == y->right_child)
    		{
    			x = y;
    			y = y->parent;
    		}
    	}
    	return y;
    }
    /*the predecessor node of the x,前任节点
    如果节点有左孩子,那么找到左孩子的最大值
    如果没有左孩子,那么向上追溯直至一个分支当前节点是对应父节点的右孩子,返回父节点的值
    */
    PNode Predecessor_Tree(PNode x)
    {
    	PNode y = NULL;
    	//case 1:the left subtree of node x is not empty
    	if (NULL != x->left_child)
    	{
    		y = Maxmum_Tree(x->left_child);
    	}
    	//case 2:the left subtree of node x is empty
    	//and the node of x has a predecessor node y
    	else
    	{
    		y = x->parent;
    		while (NULL != y && x == y->left_child)
    		{
    			x = y;
    			y = y->parent;
    		}
    	}
    	return y;
    }
    
    /*insert a new node into the BST*/
    void Insert_Tree(PNode *root, int key)
    {
    	PNode x = *root;
    	PNode y = NULL;
    	PNode z = (PNode)malloc(sizeof(Node));//<开辟一个节点的空间
    	if (NULL == z)
    	{
    		printf("malloc the z is failed.");
    		exit(1);
    	}
    	//initial the node of z
    	z->key = key;
    	z->left_child = z->right_child = z->parent = NULL;
    	//Find the location node of y to insert the node of z
    	while (NULL != x)
    	{
    		y = x; //<找到当前树满足条件的叶子节点了,表示为y,之后在y节点后面进行插入操作
    		if (z->key<x->key)
    			x = x->left_child;
    		else
    			x = x->right_child;
    	}
    	//insert the node of z
    	z->parent = y;
    	if (NULL == y)
    		*root = z;//tree was empty
    	else
    	{
    		if (z->key<y->key)
    			y->left_child = z;
    		else
    			y->right_child = z;
    	}
    }
    void Transplant(PNode *root, PNode u, PNode v)
    {
    	if (NULL == u->parent)
    		*root = v;
    	else
    	{
    		if (u == u->parent->left_child)
    			u->parent->left_child = v;
    		else
    			u->parent->right_child = v;
    	}
    	if (NULL != v)
    		v->parent = u->parent;
    }
    /*delete a node in the binary search tree*/
    void Delete_Tree(PNode *root, int key) //<删除节点
    {
    	//Find the node you want to delete
    	PNode p = Search_Tree(*root, key);
    	if (NULL == p->left_child)
    		Transplant(root, p, p->right_child);
    	else
    	{
    		if (NULL == p->right_child)
    			Transplant(root, p, p->left_child);
    		else
    		{
    			PNode y = Successor_Tree(*root);
    			if (y->parent != p)
    			{
    				Transplant(root, y, y->right_child);
    				y->right_child = p->right_child;
    				y->right_child->parent = y;
    			}
    			Transplant(root, p, y);
    			y->left_child = p->left_child;
    			y->left_child->parent = y;
    		}
    	}
    }
    /*print the key of binary search tree*/
    void ioder_Tree(PNode root)
    {
    	if (NULL != root)
    	{
    		ioder_Tree(root->left_child);
    		printf("  %d", root->key);
    		ioder_Tree(root->right_child);
    	}
    }
    int main()
    {
    	int i;
    	int Arr[LENGTH] = { 16, 6, 20, 2, 7, 19, 22, 1, 4, 11, 8 };
    	PNode root = NULL;
    	PNode p = NULL;
    	for (i = 0; i<LENGTH; i++)
    	{
    		Insert_Tree(&root, Arr[i]);
    	}
    	ioder_Tree(root);
    	printf("
    ");
    	//printf("Hello world!
    ");  
    	Delete_Tree(&root, 11);
    	ioder_Tree(root);
    	printf("
    ");
    	p = Maxmum_Tree(root);
    	printf("The Maxmum of node is:%d
    ", p->key);
    	p = Minimum_Tree(root);
    	printf("The Minimum of node is:%d
    ", p->key);
    	getchar();
    	return 0;
    }
    

      

    #include <iostream>
    #include <cstdio>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
    	///声明(int为键 , const char* 为值)
    	map <int, const char*> m;
    	///插入元素
    	m.insert(make_pair(1, "ONE"));
    	m.insert(make_pair(10, "TEN"));
    	m[100] = "HUNDRED";///其他写法
    	///查找元素
    	map<int, const char*>::iterator ite;
    	ite = m.find(1);
    	puts(ite->second);
    	ite = m.find(2);
    	if (ite == m.end())
    		puts("no found");
    	else
    		puts(ite->second);
    
    	puts(m[10]);///其他写法
    	///删除元素
    	m.erase(10);
    	for (ite = m.begin(); ite != m.end(); ++ite)
    	{
    		printf("%d: %s
    ", ite->first, ite->second);
    	}
    	system("pause");
    	return 0;
    }
    

      

  • 相关阅读:
    内置函数filter()和匿名函数lambda解析
    time&datetime模块详解
    python学习笔记:*args和**kwargs使用原理?
    python学习笔记:深浅拷贝的使用和原理
    python传参是传值还是传引用
    第215天:Angular---指令
    第214天:Angular 基础概念
    第213天:12个HTML和CSS必须知道的重点难点问题
    第212天:15种CSS居中的方式,最全了
    第211天:git和github的区别和使用详解
  • 原文地址:https://www.cnblogs.com/277223178dudu/p/11424700.html
Copyright © 2011-2022 走看看