Geeks Splay Tree Insert 树的插入操作

Splay树的插入操作,只需要处理好插入节点的孩子节点就可以了,最重要的是不要破坏了BST的基本规则。

因为高度并不是Splay树的首要因素,所以插入的时候也是使用splay操作,然后在根节点插入。

参考:http://www.geeksforgeeks.org/splay-tree-set-2-insert-delete/

对比一下使用插入创建的树和手工创建数的区别,先序遍历的结果:

#pragma once
#include<stdio.h>
#include <stdlib.h>

class SplayTree_Insertion
{
	struct Node
	{
		int key;
		Node *left, *right;
		Node(int k) : key(k), left(NULL), right(NULL) {}
		~Node()
		{
			if (left) delete left, left = NULL;
			if (right) delete right, right = NULL;
		}
	};

	Node *rightRotate(Node *x)
	{
		Node *y = x->left;
		x->left = y->right;
		y->right = x;

		return y;
	}

	Node *leftRotate(Node *x)
	{
		Node *y = x->right;
		x->right = y->left;
		y->left = x;

		return y;
	}

	Node *splay(Node *root, const int key)
	{
		if (!root || key == root->key) return root;

		if (key < root->key)
		{
			if (!root->left) return root;

			if (key < root->left->key)
			{
				root->left->left = splay(root->left->left, key);
				root = rightRotate(root);//不应root->left
			}
			else if (root->left->key < key)
			{
				root->left->right = splay(root->left->right, key);
				if (root->left->right) root->left = leftRotate(root->left);
			}
			return root->left? rightRotate(root) : root;
		}
		if (!root->right) return root;
		if (root->right->key < key)
		{
			root->right->right = splay(root->right->right, key);
			root = leftRotate(root);
		}
		else if (key < root->right->key)
		{
			root->right->left = splay(root->right->left, key);
			if (root->right->left) root->right = rightRotate(root->right);
		}
		return root->right? leftRotate(root) : root;
	}

	Node *insert(Node *root, int k)
	{
		if (!root) return new Node(k);

		root = splay(root, k);

		if (root->key == k) return root;

		Node *newNode = new Node(k);

		//learn how to handle the insertion is the best way.
		if (k < root->key)
		{
			newNode->right = root;
			newNode->left = root->left;
			root->left = NULL;
		}
		else
		{
			newNode->left = root;
			newNode->right = root->right;
			root->right = NULL;
		}
		return newNode;
	}

	void preOrder(Node *root)
	{
		if (root != NULL)
		{
			printf("%d ", root->key);
			preOrder(root->left);
			preOrder(root->right);
		}
	}
public:
	SplayTree_Insertion()
	{
		Node *root = new Node(100);
		root->left = new Node(50);
		root->right = new Node(200);
		root->left->left = new Node(40);
		root->left->left->left = new Node(30);
		root->left->left->left->left = new Node(20);
		root = insert(root, 25);
		printf("Preorder traversal of the modified Splay tree is \n");
		preOrder(root);
		putchar('\n');

		delete root;

		runInsert();
	}

	void runInsert()
	{
		Node *root = NULL;
		int keys[] = {100, 50, 200, 40, 30, 20, 25};
		int n = sizeof(keys) / sizeof(keys[0]);
		for (int i = 0; i < n; i++)
		{
			root = insert(root, keys[i]);
		}

		printf("Inser create Preorder traversal Splay tree is \n");
		preOrder(root);
		putchar('\n');

		delete root;
	}
};

Geeks Splay Tree Insert 树的插入操作,布布扣,bubuko.com

时间: 2024-12-26 06:07:24

Geeks Splay Tree Insert 树的插入操作的相关文章

[转] Splay Tree(伸展树)

好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集合操作.因此,在信息学竞赛中,二叉排序树起着非常重要的作用,它可以被用来表示有序集合.建立索引或优先队列等. 作用于二叉查找树上的基本操作的时间是与树的高度成正比的.对一个含n各节点的完全二叉树,这些操作的最坏情况运行时间为O(log n).但如果树是含n个节点的线性链,则这些操作的最坏情况运行时间

hdu 1754 splay tree伸展树 初战(单点更新,区间属性查询)

题意:与区间查询点更新,点有20W个,询问区间的最大值.曾经用线段树,1000+ms,今天的伸展树,890没ms,差不多. 第一次学习伸展树,一共花了2个单位时间,感觉伸展树真很有用,也很好玩.现在只学了一点点.切个点更新试试. 大致思路:用编号(数组)作为树的键值建树,每插一个数,沿路节点更新最大值(每个结点有一个附加信息标记以之为子树的树所有点的最大值).所以,查询时[i,j],只要把i-1伸展到树根,把j+1伸展到I-1下面,那么j+1的左子树就是要的区间了!查该子树根值信息即可(特判端点

AVL树的插入操作(旋转)图解

=================================================================== AVL树的概念 在说AVL树的概念之前,我们需要清楚二茬搜索树的概念.对于二叉搜索树,我们知道它可以降低查找速率,但是如果一个二叉搜索树退化成一棵只剩单支的搜索树,此时的查找速率就相当于顺序表中查找元素,效率变低,时间复杂度由原来的O(logN)变为O(N). 此时就有了AVL(高度平衡二叉搜索树),从它的名字就能知道它也是一棵二叉搜索树,只是它在插入元素的时候

CodeForces 620E New Year Tree(线段树的骚操作第二弹)

The New Year holidays are over, but Resha doesn't want to throw away the New Year tree. He invited his best friends Kerim and Gural to help him to redecorate the New Year tree. The New Year tree is an undirected tree with n vertices and root in the v

Splay Tree

伸展树 和AVL树不一样,伸展树并不保证每次操作的时间复杂度为O(logn),而保证任何一个m个操作的序列总时间为O(mlogn).伸展树的基本思想是:每个结点被访问时,使用AVL树的旋转操作把它移动到根.由于旋转是自底向上的,所以需要设置父亲指针,而不像AVL树那样以儿子为轴旋转.伸展操作(splaying) 伸展树的核心是伸展操作Splay(x,S).它是在保持伸展树有序性的前提下,通过一系列旋转将伸展树S中的元素x调整到树的根部.在调整的过程中,要根据x的位置分以下三种情况分别处理.情况一

AVL树的插入和删除

一.AVL 树 在计算机科学中,AVL树是最早被发明的自平衡二叉查找树.在AVL树中,任一节点对应的两棵子树的最大高度差为 1,因此它也被称为高度平衡树.查找.插入和删除在平均和最坏情况下的时间复杂度都是 O(log(n)).插入和删除元素的操作则可能需要借由一次或多次树旋转,以实现树的重新平衡. 节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反).带有平衡因子 1.0 或 -1 的节点被认为是平衡的.带有平衡因子 -2 或 2 的节点被认为是不平衡的,并需要重新平衡这个树.平衡因

B树和B+树的插入、删除图文详解

简介:本文主要介绍了B树和B+树的插入.删除操作.写这篇博客的目的是发现没有相关博客以举例的方式详细介绍B+树的相关操作,由于自身对某些细节也感到很迷惑,通过查阅相关资料,对B+树的操作有所顿悟,写下这篇博客以做记录.由于是自身对B+树的理解,肯定有考虑不周的情况,或者理解错误的地方,请留言指出. 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. B树 1. B树的定义 B树也称B-树,它是一颗多路平衡查找树.我们描述一颗B树时

splay tree旋转操作 hdu 1890

很神奇的旋转操作. 目前没看到其他数据结构能实现这个功能.平衡树不好处理区间操作,线段树很难旋转.splay tree搞这个就很简单了. 下面用的这个模板跑了700ms,好慢,估计是删除操作太费时了,是时候去找找其他更快的模板了. #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; #define MAXN 1

Splay Tree的删除操作

Splay Tree的插入操作,搜索操作,和删除操作都实现了,那么就可以使用来解题了. 指针的删除操作的处理还是那么难的,很多坎需要避开. 同一个坎还是坑了我好多次,就是指针传递的问题,什么时候需要修改指针本身的值,就必须返回指针或者传递指针的指针,或者传递指针的的实参. 这里的删除操作就是需要改变传递到函数的指针本身的,所以我这里使用了返回指针操作. 还有删除树的问题,之前的代码没做删除操作,所以没问题,现在需要逐个节点删除,所以要小心不能把整个树都删除了. 至此, splay 树的功能差不多