数据结构----索引方法(2)树形索引

为什么在实际的数据库应用中不适用BST树这种结构呢?

因为BST树的插入容易导致树不平衡,树的深度太大将导致从根节点到叶节点的路径经过的磁盘块太多。基于解决这两个问题的基础上,提出了2-3树结构

1.2-3树

1.形状的定义:

1)一个结点包含一个或者两个关键码
2)每个内部结点假如有一个关键码,则有两个子女;假如有两个关键码,则有三个子女。
3)所有的叶结点都在树结构的同一层,因此树的高度总是平衡的。(这和2-3树的插入方式有关)

2.检索树特征:

对于每个结点:
一个关键码:左子树的后继结点的值都小于第一个关键码的值,右子树的所有后继结点都大于等于第一个关键码的值
两个关键码:左子树的后继结点的值都小于第一个关键码的值,中间子树的所有后继结点都大于等于第一个关键码的值且小于等于第二个关键码的值,右边子树的所有后继结点的值都大于等于第二个关键码的值

3.树节点的定义:

#include 
template 
class TTNode {
public:
	Key lKey;
	Key rKey;
	TTNode* left;
	TTNode* center;
	TTNode* right;

	TTNode() {
		left = center = right = NULL;
	}
	~TTNode() {}
	bool isleafNode() {
		return left == NULL;
	}
	
};
代码如上所示

4.2-3树的插入操作


数据结构----索引方法(2)树形索引_第1张图片


如图为依次插入C  S D T A M P的2-3树的结构
插入步骤详解:当前插入的关键码为key,当前结点为rt
判断是否是空树,若为空树,建立空结点并插入左关键码值
不为空树:
当前结点为叶子结点
(1)右键值为空:
a)rt->lKey
b)rt->lKey>key,将当前结点的左键值调节为右键值,将当前插入的键值作为当前结点的左键值
(2)右键部位不为空:
a)键值比左键值小
b)键值介于左右键值之间
c)键值比右键值大
以上这三种情况都需要“提升”操作
数据结构----索引方法(2)树形索引_第2张图片

当前结点不为叶子结点:用到递归操作
a)key小于当前结点的左键值:对左子树操作
b)右键值为空或者右键值存在但是key介于左右键值之间:对中间子树进行操作
c)key大于右键值:对右子树进行操作

插入操作的代码如下:
#pragma once
#include 
template 
class TTNode {
public:
	Key lKey;
	Key rKey;
	TTNode* left;
	TTNode* center;
	TTNode* right;

	TTNode() {
		lKey = 0;
		rKey = 0;
		left = center = right = NULL;
	}
	TTNode(Key l,Key r,TTNode* ln=NULL,TTNode* cn=NULL,TTNode rn=NULL) {
		lKey = l;
		rKey = r;
		left = ln; right = rn; center = cn;
	}
	~TTNode() {}
	bool isleafNode() {
		return left == NULL;
	}
	TTNode* add(TTNode* it) {
		if (rKey == 0) {
			if (lKey < it->lKey) {
				rKey = it->lKey;
				right = center; center = it->center;
			}
			else {
				rKey = lKey;
				lKey = it->lKey;
				right = center; center = it->center;
			}
		}
		else if (lKey >= it->lKey) {
			center = new TTNode(rKey, 0, NULL, NULL, NULL);
			rKey = 0; right = NULL;
			it->left = left; left = it;
			return this;
		}
		else if (rKey < it->lKey) {
			it->center = new TTNode(rKey, 0, NULL, it->center, right, NULL);
			it->left = this;
			rKey = 0; right = NULL;
			return it;
		}
		else {
			TTNode N1 = new TTNode(rKey, 0, this, it, NULL);
			it->left = right;
			right = NULL; rKey = 0;
			return N1;
		}
	}
	
};
template 
class TTTNode {
private:
	TTNode* subroot;
	bool findhelp(TTNode* node,const Key key) {
		if (node == NULL)  return false;
		if (node->lKey==key) return true;
		if (node->rKey!=NULL&&node->rKey == key) return true;
		if (node->lKey > key)
			return findhelp(node->left, key);
		else if (node->rKey == NULL&& node->lKey <= key)
			return findhelp(node->center, key);
		else if (node->rKey > key)
			return findhelp(node->center, key);
		else
			return findhelp(node->right, key);
	}
	TTNode* inserthelp(TTNode* rt, const Key k) {
		TTNode* retval;
		if (rt == NULL)
			return new TTNode(k,0, NULL, NULL, NULL);
		if (rt->isleafNode())
			return rt->add(new TTNode(k, 0, NULL, NULL, NULL));
		if (k < rt->lKey) {
			retval = inserthelp(rt->left, k);
			if (retval == rt->left) return rt;
			else return rt->add(retval);
		}
		else if (rt->rKey == 0 || rt->rKey > k) {
			retval = inserthelp(rt->center, k);
			if (retval == rt->center) return rt;
			else return rt->add(retval);
		}
		else {
			retval = inserthelp(rt->right, k);
			if (retval == rt->right) return rt;
			else return rt->add(retval);
		}
	}
public:
	TTTNode() {
		subroot = NULL;
	}
	bool findNode(const Key key) {
		return findhelp(subroot, key);
	}
	void insert(Key k) {
		inserthelp(subroot, k);
	}

	
};


你可能感兴趣的:(数据结构,结构,索引,数据结构)