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)
上一篇 2021年11月24日 上午7:00
下一篇 2021年11月24日 上午8:00


相关推荐

  • 罗技键盘+android风格,罗技这款好看轻便的蓝牙键盘,让你在电脑手机间无缝切换…

    罗技键盘+android风格,罗技这款好看轻便的蓝牙键盘,让你在电脑手机间无缝切换…来源:极客之选摘要对便携性和颜值有要求的用户,这款键盘很适合。罗技K380蓝牙键盘是罗技比较经典的一款外设产品,最近,罗技新推出了k380芍药白和茱萸粉两种新配色,让我们来一起看一下。其中粉色介于粉色和裸色之间,相比粉色增加了一丝灰色。极客之选本次拿到的是白色版本,颜色也非亮白,而是与粉色类似较柔和,两种颜色整体都非常素雅,因此也适合在各种场合使用。外观上,罗技K380延续了一贯的设计…

    2022年10月15日
    6
  • Pycharm撤销操作和代码跳转后退回操作以及消除波浪线操作快捷键

    Pycharm撤销操作和代码跳转后退回操作以及消除波浪线操作快捷键不小心进行了错误的操作 想要回到前一步操作的时候 撤销与反撤销操作 Ctrl z Ctrl Shift z 代码跳转后退回操作 把 View 中的 Toolbar 勾上这两个箭头就是分别回到前后的代码跳转的位置处 3 在写自己代码的时候 经常代码下面会出现波浪线 表示自己的代码格式不符合规范 不过也不是错误 比如 红色这块区域的波浪线是由于定义的两个

    2026年3月27日
    2
  • 银河麒麟v10 centos_银河麒麟创建root用户

    银河麒麟v10 centos_银河麒麟创建root用户由于现在很多软件安装时都需要安装一系列的依赖,出于安全考虑服务器又不一定都能够连接外网。故需要本地配置yum源,当前也可以配置外网yum源(前提是要能够访问外网)

    2022年8月12日
    8
  • VS 2013 所有产品密钥

    VS 2013 所有产品密钥转载自:https://blog.csdn.net/my1989night/article/details/44916079VS2013产品密钥–所有版本VisualStudioUltimate2013KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9VisualStudioPremium2013KEY(密钥):FBJVC-3CMTX-D8DVP…

    2022年5月12日
    58
  • 图解汉诺塔问题(递归求解)

    图解汉诺塔问题(递归求解)汉诺塔 汉诺塔 TowerofHanoi 源于印度传说中 大梵天创造世界时造了三根金钢石柱子 其中一根柱子自底向上叠着 64 片黄金圆盘 大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上 并且规定 在小圆盘上不能放大圆盘 在三根柱子之间一次只能移动一个圆盘 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 引用维基百科单看这个问题描述有点让人抓瞎 这是当然 无论多么简单的问题描述

    2026年3月19日
    2
  • IntelliJ IDEA报错:Error:(1, 1) java: 非法字符: ‘\ufeff'[通俗易懂]

    IntelliJ IDEA报错:Error:(1, 1) java: 非法字符: ‘\ufeff'[通俗易懂]当我把Eclipse中的类拷贝到idea项目中,就出现了这个错误。查找资料得知:Eclipse可以智能的把UTF-8+BOM文件转为普通的UTF-8文件,但使用IDEA编译UTF-8+BOM编码的文件时会出现这个错误:Error:(1, 1) java: 非法字符: ‘\ufeff’。关于UTF-8+BOM 参考 https://www.zhihu.com/question/20167122/an…

    2022年6月13日
    119

发表回复

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

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