Splay Tree的删除操作

Splay Tree的删除操作

Splay Tree的插入操作,搜索操作,和删除操作都实现了,那么就能够使用来解题了。

指针的删除操作的处理还是那么难的,非常多坎须要避开.

同一个坎还是坑了我好多次,就是指针传递的问题,什么时候须要改动指针本身的值,就必须返回指针或者传递指针的指针,或者传递指针的的实參。

这里的删除操作就是须要改变传递到函数的指针本身的,所以我这里使用了返回指针操作。

还有删除树的问题,之前的代码没做删除操作,所以没问题,如今须要逐个节点删除,所以要小心不能把整个树都删除了。

至此, splay 树的功能差点儿相同完好了。


代码中凝视标明了几个坑都被我碰到了。


#pragma once
#include <stdio.h>

class SplayTreeComplete
{
	struct Node
	{
		int key;
		Node *left, *right;
		explicit Node(int k):key(k),left(NULL),right(NULL){}
		/*~Node()
		{教训:这种话整颗树都删除了,不能这么删除,要逐个节点删除
			if (left) delete left, left = NULL;
			if (right) delete right, right = NULL;
		}*/
	};

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

	Node *rightRotate(Node *x)
	{
		Node *y = x->left;
		x->left = y->right;
		y->right = 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);
			}
			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, const int key)
	{
		if (!root) return new Node((int)key);//别忘了创建新的节点

		root = splay(root, key);//别忘了 root = 
		
		if (key == root->key) return root;

		Node *newNode = new Node((int)key);
		if (key < 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;
	}

	Node *deleteNode(Node *root, const int key)
	{
		if (!root) return root;

		root = splay(root, key);

		if (key == root->key)
		{
			if (!root->left)
			{
				Node *x = root;
				root = root->right;
				delete x, x = NULL;
			}
			else
			{
				Node *x = root->right;
				Node *y = root->left;
				delete root;
				root = splay(y, key);
				root->right = x;
			}
		}
		return root;
	}

	void preOrder(Node *root)
	{
		if (root != NULL)
		{
			printf("%d ", root->key);
			preOrder(root->left);
			preOrder(root->right);
		}
	}
public:
	SplayTreeComplete()
	{
		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("\nInser create Preorder traversal Splay tree is \n");
		preOrder(root);
		putchar('\n');

		root = splay(root, 50);
		bool found = root->key == 50;

		printf("\n50 is %s the tree\n", found? "in" : "not in");

		root = deleteNode(root, 50);//root 发生改变了,所以必须返回新的指针值

		root = splay(root, 50);
		found = root->key == 50;

		printf("\n50 is %s the tree\n", found? "in" : "not in");

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

		deleteTree(root);
	}

	void deleteTree(Node *root)
	{
		if (root)
		{
			deleteTree(root->left);
			deleteTree(root->right);
			delete root, root = NULL;
		}
	}
};


<span>Splay Tree的删除操作</span>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119014.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么是Deeplink?以及Deeplink的原理

    什么是Deeplink?以及Deeplink的原理先说一个日常场景帮大家理解。最近双十一、双十二,不知道大家有没有被亲友们发的某宝、某东、或拼夕夕的各类信息轮番轰炸?小编的亲友群、闺蜜群里常年有这类链接挂着,小红薯的笔记分享,某宝的化妆品、衣服链接分享等等,这一个个的分享链接织成一张张网,真可谓是增加亲友亲密度,快速获取优质好物的利器。这背后有个特别容易忽视却又极其重要的知识点。比如你在社交媒体上分享给翠花一个某App上的精选好店,翠花想要查看有几种操作方式:l如果翠花已经安装了该App,那她只要点开链接就可以跳转到App;l如果…

    2022年6月16日
    105
  • github开发人员在七夕搞事情:remote: Support for password authentication was removed on August 13, 2021.

    github开发人员在七夕搞事情:remote: Support for password authentication was removed on August 13, 2021.1问题描述如果你在七夕(没错就是2020年8月14日)的这一天刚好加班,又刚好去访问了全球最大的同性交友网站,又刚好去更新提交代码,又或你创建了一个新的仓库送给自己,又刚好想把这个仓库送给(push)github,你就刚好会遇到这个问题:remote:SupportforpasswordauthenticationwasremovedonAugust13,2021.Pleaseuseapersonalaccesstokeninstead.具体如下:(yolov4)

    2022年7月20日
    27
  • linux系统移植的一般过程_内核移植的基本步骤

    linux系统移植的一般过程_内核移植的基本步骤在众多嵌入式操作系统中,Linux目前发展最快、应用最为广泛。性能优良、源码开放的Linux具有体积小、内核可裁减、网络功能完善、可移植性强等诸多优点,非常适合作为嵌入式操作系统。一个最基本的Linux操作系统应该包括:引导程序、内核与根文件系统三部分。  嵌入式Linux系统移植主要由四大部分组成:  一、搭建交叉开发环境  二、bootloader的选择和移植  三、kernel的配置、编译、…

    2022年9月25日
    0
  • FPGA的图像处理算法

    FPGA的图像处理算法下面简要分析了FPGA技术,包括FPGA技术原理和技术特点等,随后介绍一下FPGA的图像处理系统算法的实现,包括存储模块、运算单元、控制模块以及数据传输模块等内容。智能机器人、多媒体已经计算机的诞生都离不开数字图象处理技术,随着计算机智能化图像处理技术的不断发展,几乎所有领域当中都有数字图象技术的身影。例如军事、公共安全、工业、航天航空、卫星遥感以及生命科学等各种领域。因此对图象处理…

    2022年5月17日
    38
  • 五分钟JAVA代码教会你:FFmpeg实现视频试看(window版本)「建议收藏」

    当领导要你开发视频试看功能,怎么破??我用JAVA代码教会你,花5分钟就能学会,赶紧来看看吧。

    2022年4月6日
    65
  • Linux vim退出_怎么关闭vim

    Linux vim退出_怎么关闭vim有些终端在vim退出后可以恢复到打开vim前终端的状态,类似这样:$vim/etc/sysconfig/####这里表示打开vim#####sdskk,一些文件内容:q$vim/etc/sysconfig/##终端恢复到先前状态但是有些不行,解决这个问题需要以下两步:1、设置TERM环境变量为xterm或者xterm-color,可以在.ba…

    2022年8月24日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号