初学算法心得-二叉搜索树

初学算法的心得笔记-二叉搜索树

二叉搜索树

二叉搜索树的结点

struct Node{
    
    
	int key;
	Node *parent, *left, *right;
};

插入

insert以根为节点寻找z该插入的位置。设当前节点为x,如果z的键值小于x, 则将当前节点的左子节点作为下一个节点x,反之则以右节点作为下一个节点x。如此不断向叶节点搜索。在此过程中,程序将前一个节点保存在y里,用作z的候选父节点。当x抵达NIL时搜索结束,此时的y就是z的父节点了。

void insert(int k){
    
    
	Node *y = NIL;
	NOde *x = root;
	Node *z;

	z = (Node *)malloc(sizeof(Node));
	z->key = k;
	z->left = NIL;
	z->right = NIL;

	while(x != NIL){
    
    
		y = x;
		if(z->key < x->key){
    
    
			x = x->left;
		}
		else{
    
    
			 x = x->right;
		}
	}

	z->parent = y;
	if(y == NIL){
    
    
		root = z;
	}
	else{
    
    
		if(z->key < y->key){
    
    
			y->left = z;
		}
		else{
    
    
			y->right = z;
		}
	}
}

搜索

find 操作要在二叉搜索树中找出含有键值k的节点x

find(x, k)
{
    
    
	while(x != NIL and k != x.key)
	{
    
    
		if(k < x.key)
			x = x.left;
		else
			x = x.right;
	}
	return x;
}

我们以根节点为起点调用 find 函数,从根向叶搜索节点。如果给定键值小于当前节点x的键值,那么搜索目标移动至左节点继续搜索,反之移动至右节点。键值不存在时返回NIL

删除

deleteNode 函数用于从二叉搜索树T 中删除节点z

deleteNode(T, z){
    
    
	if(z.left == NIL || z.right == NIL){
    
    
		y = z;
	else 
		y = getSuccessor(z);
	
	if(y.left != NIL)
		x = y.left;
	else
		x = y.right;
	if(x != NIl)
		x.parent = y.parent;
	
	if(y.parent == NIL)
		root = x;
	else if (y == y.parent.left)
		y.parent.left = x;
	else
		y.parent.right = x;
	
	if (y != z)
		z.key = y.key;

getSuccessor(x) 用于求x的后一个节点

getSuccessor(x){
    
    
	if(x.right != NIL)
		return getMinimum(x.right)
	y = x.parent;
	while(y != NIl && x == y.right)
	{
    
    
		x = y;
		y = y.parent;
	}
	return y;
}

getMinimum(x) 会在以x 为根的子树中搜索并返回键值最小的节点

getMinimum(x){
    
    
	while(x.left != NIL)
		x = x.left;
	return x;
}

通过标准库管理集合

管理元素的 STL 容器可大致分为两类。一类是有顺序的集合,称为 序列式容器 ;另一类是经过排序的容器,称为关联式容器
序列式容器添加元素的位置与元素本身(值)无关 STL中有 vectorlist 等;
关联式容器 添加元素的位置与元素本身(值)有关STL 为用户提供了 setmapmultisetmultimap 容器
关联式容器 在管理数据的过程中会自动给元素排序。虽然序列式容器也可以进行排序,但关联式容器优点在于可以随时采用二分搜索法,搜索效率极高。

  • set
#include<set> 用来将STL中的set包含在程序中

set<int> s; 用于申明一个set集合s;

set 的成员函数示例:

函数 功能 复杂度
size() 返回set中的元素数 O(1)
clear() 清空set O(n)
begin() 返回指向set开头的迭代器 O(1)
end() 返回指向set末尾的迭代器 O(1)
insert(key) 向set中插入元素key O(logn)
erase(key) 删除含有key的元素 O(logn)
find(key) 搜索与key一致的元素,并返回指向该元素的迭代器。没有与key一致的元素,则返回末尾end() O(logn)
  • map
    map集合以键和值的组合为元素,每个元素拥有1个键和1个值,集合以键作为排序的标准。各元素的键唯一,不存在重复。map可以看做是一种能使用任意类型下标的的关联式容器
#include<map>
用来将STL中的map包含在程序中

map<string, int> T;
这里是声明了一个以string为键的int型元素;

pair为STL提供的结构体模板,其第一个元素可用first访问,第二个元素可用second访问
map的成员函数示例:

函数名 功能 复杂度
size() 返回map中的元素数 O(1)
clear() 清空map O(n)
begin() 返回指向map开头的迭代器 O(n)
end() 返回指向map末尾的迭代器 O(1)
insert((key, val)) 向map中插入元素(key, val) O(logn
erase(key) 删除含有key 的元素 O(logn)
find(key) 搜索与key一致的元素,并返回指向该元素的迭代器。没有与该元素一致的元素,则返回末尾end() O(logn)

おすすめ

転載: blog.csdn.net/weixin_46784800/article/details/109105384