当前位置:网站首页>Extended tree (I) - concept and C implementation
Extended tree (I) - concept and C implementation
2022-07-01 11:31:00 【Life needs depth】
Summary
This chapter introduces extended trees . It and " Binary search tree " and "AVL Trees " equally , Are special binary trees . In understanding " Binary search tree " and "AVL Trees " after , Learning to stretch trees is quite easy . As usual , This article will first give a brief introduction to the theoretical knowledge of extended trees , Then give C The realization of language . The following sequence will be given separately C++ and Java Implementation of version ; this 3 The principle of each implementation method is the same , Choose one of them to learn . If there are mistakes or deficiencies in the article , I hope you can point out !
Catalog
1. Introduction to the stretch tree
2. Stretching the tree C Realization
3. Stretching the tree C The test program
Reprint please indicate the source : Stretch the tree ( One ) And Graphic analysis and C The realization of language - If the sky doesn't die - Blog Garden
More : Data structure and algorithm series Catalog
(01) Stretch the tree ( One ) And Graphic analysis and C The realization of language
(02) Stretch the tree ( Two ) And C++ The implementation of the
(03) Stretch the tree ( 3、 ... and ) And Java The implementation of the
Introduction to the stretch tree
Stretch the tree (Splay Tree) It's a binary sort tree , It can be in O(log n) Insert inside complete 、 Search and delete operations . It consists of Daniel Sleator and Robert Tarjan create .
(01) Stretch tree belongs to binary search tree , That is, it has the same properties as binary search tree : hypothesis x Is any node in the tree ,x Nodes contain keywords key, node x Of key Value to key[x]. If y yes x A node in the left subtree of , be key[y] <= key[x]; If y yes x A node of the right subtree of , be key[y] >= key[x].
(02) In addition to the properties of binary search tree , Another feature of stretch trees is : When a node is accessed , Stretching the tree will make the node become the root of the tree by rotation . The advantage of this is , The next time you want to access this node , Can quickly access the node .
Suppose you want to perform a series of lookup operations on a binary lookup tree . In order to make the whole search time smaller , The items that are checked frequently should always be near the root of the tree . So I thought of designing a simple method , Refactoring the tree after each lookup , Move the searched items closer to the root of the tree . Stretch tree came into being , It is a self-adjusting binary search tree , It follows the path from a node to the root of the tree , Move this node to the root of the tree through a series of rotations .
Compared with " Binary search tree " and "AVL Trees ", When learning to stretch a tree, you need to focus on " Rotation algorithm of extended tree ".
Stretching the tree C Realization
1. Node definition

typedef int Type;
typedef struct SplayTreeNode {
Type key; // keyword ( Key value )
struct SplayTreeNode *left; // Left the child
struct SplayTreeNode *right; // The right child
} Node, *SplayTree; 
The nodes of the extension tree include several constituent elements :
(01) key -- Is the key word , It is used to sort the nodes of the extended tree .
(02) left -- The left child. .
(03) right -- It's the right child .
External interface

// The former sequence traversal " Stretch the tree " void preorder_splaytree(SplayTree tree); // In the sequence traversal " Stretch the tree " void inorder_splaytree(SplayTree tree); // After the sequence traversal " Stretch the tree " void postorder_splaytree(SplayTree tree); // ( Recursive implementation ) lookup " Stretch the tree x" The middle key value is key The node of Node* splaytree_search(SplayTree x, Type key); // ( Non recursive implementation ) lookup " Stretch the tree x" The middle key value is key The node of Node* iterative_splaytree_search(SplayTree x, Type key); // Find the smallest node : return tree The smallest node of an extended tree that is the root node . Node* splaytree_minimum(SplayTree tree); // Find the largest node : return tree The largest node of the extended tree that is the root node . Node* splaytree_maximum(SplayTree tree); // rotate key The corresponding node is the root node . Node* splaytree_splay(SplayTree tree, Type key); // Insert the node into the extended tree , And return the root node Node* insert_splaytree(SplayTree tree, Type key); // Delete node (key Is the value of the node ), And return the root node Node* delete_splaytree(SplayTree tree, Type key); // Destroy the stretch tree void destroy_splaytree(SplayTree tree); // Print stretch tree void print_splaytree(SplayTree tree, Type key, int direction);

2. rotate
Rotating code

/*
* rotate key The corresponding node is the root node , And return the root node .
*
* Be careful :
* (a): There are in the stretching tree " The key value is key The node of ".
* take " The key value is key The node of " Rotate to root node .
* (b): It doesn't exist in the stretched tree " The key value is key The node of ", also key < tree->key.
* b-1 " The key value is key The node of " If the precursor node of exists , take " The key value is key The node of " The precursor node of is rotated to the root node .
* b-2 " The key value is key The node of " If the precursor node of exists , Means that the ,key Smaller than any key value in the tree , So at this time , Rotate the smallest node to the root node .
* (c): It doesn't exist in the stretched tree " The key value is key The node of ", also key > tree->key.
* c-1 " The key value is key The node of " If the successor node of exists , take " The key value is key The node of " The subsequent node of is rotated to the root node .
* c-2 " The key value is key The node of " If the successor node of does not exist , Means that the ,key Larger than any key value in the tree , So at this time , Rotate the largest node to the root node .
*/
Node* splaytree_splay(SplayTree tree, Type key)
{
Node N, *l, *r, *c;
if (tree == NULL)
return tree;
N.left = N.right = NULL;
l = r = &N;
for (;;)
{
if (key < tree->key)
{
if (tree->left == NULL)
break;
if (key < tree->left->key)
{
c = tree->left; /* 01, rotate right */
tree->left = c->right;
c->right = tree;
tree = c;
if (tree->left == NULL)
break;
}
r->left = tree; /* 02, link right */
r = tree;
tree = tree->left;
}
else if (key > tree->key)
{
if (tree->right == NULL)
break;
if (key > tree->right->key)
{
c = tree->right; /* 03, rotate left */
tree->right = c->left;
c->left = tree;
tree = c;
if (tree->right == NULL)
break;
}
l->right = tree; /* 04, link left */
l = tree;
tree = tree->right;
}
else
{
break;
}
}
l->right = tree->left; /* 05, assemble */
r->left = tree->right;
tree->left = N.right;
tree->right = N.left;
return tree;
}
The function of the above code : take " The key value is key The node of " Rotate to root node , And return the root node . Its handling includes :
(a): There are in the stretching tree " The key value is key The node of ".
take " The key value is key The node of " Rotate to root node .
(b): It doesn't exist in the stretched tree " The key value is key The node of ", also key < tree->key.
b-1) " The key value is key The node of " If the precursor node of exists , take " The key value is key The node of " The precursor node of is rotated to the root node .
b-2) " The key value is key The node of " If the precursor node of exists , Means that the ,key Smaller than any key value in the tree , So at this time , Rotate the smallest node to the root node .
(c): It doesn't exist in the stretched tree " The key value is key The node of ", also key > tree->key.
c-1) " The key value is key The node of " If the successor node of exists , take " The key value is key The node of " The subsequent node of is rotated to the root node .
c-2) " The key value is key The node of " If the successor node of does not exist , Means that the ,key Larger than any key value in the tree , So at this time , Rotate the largest node to the root node .
The following are examples of a To illustrate .
Look in the stretched tree below 10, Including " Right hand " --> " Right link " --> " Combine " this 3 Step .
First step : Right hand
Corresponding to "rotate right" part
The second step : Right link
Corresponding to "link right" part
The third step : Combine
Corresponding to "assemble" part
Tips : If you look in the stretched tree above "70", Is exactly the same as " Example 1" symmetry , The corresponding operations are "rotate left", "link left" and "assemble".
Other things , for example " lookup 15 yes b-1 The situation of , lookup 5 yes b-2 The situation of " wait , These are relatively simple , You can analyze by yourself .
3. Insert

/*
* Insert the node into the extended tree ( No rotation )
*
* Parameter description :
* tree Extend the root node of the tree
* z Inserted node
* Return value :
* The root node
*/
static Node* splaytree_insert(SplayTree tree, Node *z)
{
Node *y = NULL;
Node *x = tree;
// lookup z Where to insert
while (x != NULL)
{
y = x;
if (z->key < x->key)
x = x->left;
else if (z->key > x->key)
x = x->right;
else
{
printf(" Inserting the same node is not allowed (%d)!\n", z->key);
// Release the requested node , And back to tree.
free(z);
return tree;
}
}
if (y==NULL)
tree = z;
else if (z->key < y->key)
y->left = z;
else
y->right = z;
return tree;
}
/*
* Create and return the extended tree node .
*
* Parameter description :
* key Is the key value .
* parent Is the parent node .
* left The left child. .
* right It's the right child .
*/
static Node* create_splaytree_node(Type key, Node *left, Node* right)
{
Node* p;
if ((p = (Node *)malloc(sizeof(Node))) == NULL)
return NULL;
p->key = key;
p->left = left;
p->right = right;
return p;
}
/*
* New node (key), Then insert it into the extended tree , And rotate the inserted node into the root node
*
* Parameter description :
* tree Extend the root node of the tree
* key Insert the key value of the node
* Return value :
* The root node
*/
Node* insert_splaytree(SplayTree tree, Type key)
{
Node *z; // New node
// If the new node fails , Then return to .
if ((z=create_splaytree_node(key, NULL, NULL)) == NULL)
return tree;
// Insert node
tree = splaytree_insert(tree, z);
// The nodes (key) Rotate to root node
tree = splaytree_splay(tree, key);
}
External interface : insert_splaytree(tree, key) It is an interface provided to the outside , Its function is to create new nodes ( The key value of the node is key), And insert the node into the extended tree ; then , Rotate this node to the root node .
Internal interface : splaytree_insert(tree, z) It's the internal interface , Its function is to connect nodes z Insert into tree in .splaytree_insert(tree, z) Will be z Insert into tree In the middle of the day , Only will tree Think of it as a binary search tree , And it is not allowed to insert the same node .
4. Delete
Delete interface

/*
* Delete node (key Is the key value of the node ), And return the root node .
*
* Parameter description :
* tree Extend the root node of the tree
* z Deleted nodes
* Return value :
* The root node ( The root node is the precursor node of the deleted node )
*
*/
Node* delete_splaytree(SplayTree tree, Type key)
{
Node *x;
if (tree == NULL)
return NULL;
// The search key value is key The node of , If it cannot be found, return directly .
if (splaytree_search(tree, key) == NULL)
return tree;
// take key The corresponding node is rotated to the root node .
tree = splaytree_splay(tree, key);
if (tree->left != NULL)
{
// take "tree The precursor node of " Rotate to root node
x = splaytree_splay(tree->left, key);
// remove tree node
x->right = tree->right;
}
else
x = tree->right;
free(tree);
return x;
}
delete_splaytree(tree, key) The role of is : Delete the key value of key The node of .
It will first find the key value of key The node of . If not found , Then return directly . If found , Then rotate the node to the root node , Then delete the node .
Be careful : About stretching trees " The former sequence traversal "、" In the sequence traversal "、" After the sequence traversal "、" Maximum "、" minimum value "、" lookup "、" Print "、" The destruction " Equal interface and " Binary search tree " Is essentially the same , These operations are in " Binary search tree " Has been introduced in , Here is no longer a separate introduction . Of course , The complete source code of the extended tree given later , Have given these API Implementation code . These interfaces are simple ,Please RTFSC(Read The Fucking Source Code)!
Stretching the tree C Realization ( Complete source code )
Stretch the header file of the tree (splay_tree.h)

View Code
Implementation file of extension tree (splay_tree.c)

View Code
Test program of stretching tree (splaytree_test.c)

View Code
Stretching the tree C The test program
The test program running results of the extended tree are as follows :

== Add... In turn : 10 50 40 30 20 60 == The former sequence traversal : 60 30 20 10 50 40 == In the sequence traversal : 10 20 30 40 50 60 == After the sequence traversal : 10 20 40 50 30 60 == minimum value : 10 == Maximum : 60 == Tree details : 60 is root 30 is 60's left child 20 is 30's left child 10 is 20's left child 50 is 30's right child 40 is 50's left child == Rotate nodes (30) Root node == Tree details : 30 is root 20 is 30's left child 10 is 20's left child 60 is 30's right child 50 is 60's left child 40 is 50's left child

The main flow of the test program is : Create a new stretch tree , Then insert into the extended tree one by one 10,50,40,30,20,60. After inserting these data , The nodes of the extended tree are 60; here , Then rotate the node , bring 30 Become the root node .
Insert... In turn 10,50,40,30,20,60 The schematic diagram is as follows :
take 30 The schematic diagram of rotating to root node is as follows :
边栏推荐
- [buuctf.reverse] 144_[XMAN2018排位赛]easyvm
- kubernetes之ingress探索实践
- Ultra detailed black apple installation graphic tutorial sent to EFI configuration collection and system
- Mingchuang plans to be listed on July 13: the highest issue price is HK $22.1, and the net profit in a single quarter decreases by 19%
- Skip the test cases to be executed in the unittest framework
- 编译调试Net6源码
- Redis configuration environment variables
- Nordic nrf52832 flash 下载M4错误
- Is it safe for Huatai Securities to open an account online?
- Harbor webhook从原理到构建
猜你喜欢

京东与腾讯续签合作:向腾讯发行A类股 价值最高达2.2亿美元

Exploration and practice of inress in kubernetes

CVPR 2022 | self enhanced unpaired image defogging based on density and depth decomposition

Tianrunyun, invested by Tian Suning, was listed: its market value was 2.2 billion Hong Kong, and its first year profit decreased by 75%

Technology sharing | introduction to linkis parameters

用实际例子详细探究OpenCV的轮廓检测函数findContours(),彻底搞清每个参数、每种模式的真正作用与含义

node版本管理器nvm安装及切换

软件项目管理 9.2.软件项目配置管理过程

Cvpr22 | CMT: efficient combination of CNN and transformer (open source)

Exposure:A White-Box Photo Post-Processing Framework阅读札记
随机推荐
Cann operator: using iterators to efficiently realize tensor data cutting and blocking processing
TEMPEST HDMI泄漏接收 5
Redis configuration environment variables
Mysql的四个隔离级别是如何实现的 (简要)
Give up high paying jobs in Shenzhen and go back home
Unittest 框架介绍及第一个demo
Test case writing specification in unittest framework and how to run test cases
2022/6/29学习总结
华泰证券网上开户安全吗?
博途V15添加GSD文件
CVPR 2022 | self enhanced unpaired image defogging based on density and depth decomposition
Value/sortedset in redis
Question: what professional qualities should test engineers have?
JS date format conversion method
流动性质押挖矿系统开发如何制作,dapp丨defi丨nft丨lp流动性质押挖矿系统开发案例分析及源码
Can I open a securities account anywhere? Is it safe to open an account
ES6 promise Usage Summary
"Target detection" + "visual understanding" to realize the understanding and translation of the input image (with source code)
达梦数据冲刺科创板:拟募资24亿 冯裕才曾为华科教授
CAD如何设置标注小数位