当前位置: 首页 > news >正文

怎么给网站做链接屏蔽怎么做seo网站关键词优化

怎么给网站做链接屏蔽,怎么做seo网站关键词优化,免费企业,什么网站可以做护士三基试题目录 一、基本介绍 二、伸展操作 1. 左右情况的伸展 2. 左左情况的伸展 3. 右左情况的伸展 4. 右右情况的伸展 三、其它操作 1. 插入 2. 删除 四、代码实现 一、基本介绍 伸展树是一种二叉搜索树,伸展树也是一种平衡树,不过伸展树并不像AVL树那…

目录

一、基本介绍

二、伸展操作

1. 左右情况的伸展

2. 左左情况的伸展

3. 右左情况的伸展

4. 右右情况的伸展

三、其它操作

1. 插入

2. 删除

四、代码实现


一、基本介绍

伸展树是一种二叉搜索树,伸展树也是一种平衡树,不过伸展树并不像AVL树那样对树的平衡有很

严格的要求(左右孩子高度之差不能超过1),伸展树通过一系列的伸展操作,可以保证对伸展树

的任意连续M次操作,其时间复杂度不会超过MlogN级别,并且伸展树的实现相较于AVL树也简单

了很多,不论是插入还是删除算法

二、伸展操作

伸展树之所以能够保证MlogN的界,就是因为伸展树的伸展操作,每一次调用伸展树的search方法

查找一个结点的时候,如果存在,那么就需要对该结点进行一系列的伸展操作,经过一系列的伸展

操作之后,该结点最终会变成根节点

1. 左右情况的伸展

本质上就是AVL树的右双旋转

2. 左左情况的伸展

这种情况和AVL树的单右旋转不同,需要先将A进行单向左旋,然后再将B进行单向左旋

3. 右左情况的伸展

略,情况同1

4. 右右情况的伸展

略,情况同2

三、其它操作

1. 插入

伸展树的插入就是普通BST的插入算法,无差别

2. 删除

伸展树的删除步骤如下

(1)找到被删除的结点D的左子树DL的最大结点M,然后将M结点伸展到DL的根节点处

(2)然后将D删除,因为M一定没有右孩子,即使被伸展到DL的根节点也不会有右孩子,此时只

需要将D的右子树DR挂到M的右孩子上即可

四、代码实现

package splaytree;/*** 实现伸展树** @author CodingW*/
public class SplayTree<K extends Comparable<K>, V> {private TreeNode<K, V> root;/*** 向伸展树中插入一个新的结点** @param key   关键字* @param value 值*/public void insert(K key, V value) {TreeNode<K, V> cur = root;TreeNode<K, V> pre = null;while (cur != null) {int cmp = cur.key.compareTo(key);if (cmp < 0) {pre = cur;cur = cur.right;} else if (cmp > 0) {pre = cur;cur = cur.left;} else {// 如果相等,那么就进行替换cur.value = value;break;}}TreeNode<K, V> node = new TreeNode<>(key, value);node.setParent(pre);if (pre == null) {// 说明当前插入的结点是根节点root = node;return;}// 如果pre不为null,那么说明cur不为null即// root不为null,所以pre一定指向的是bst中// node需要插入位置的前驱结点if (pre.key.compareTo(key) < 0) {pre.right = node;} else {pre.left = node;}}/*** 返回先序遍历** @return 返回先序遍历序列字符串*/public String preOrder() {StringBuilder pre = new StringBuilder();if (root == null) {return pre.toString();}TreeNode<K, V> cur = root;while (cur != null) {if (cur.left != null) {TreeNode<K, V> mostRight = cur.left;while (mostRight.right != null && mostRight.right != cur) {mostRight = mostRight.right;}if (mostRight.right == null) {pre.append("{").append(cur.key).append(",").append(cur.value).append(",").append(cur.parent == null ? "null" : cur.parent.value).append("}\t");mostRight.right = cur;cur = cur.left;continue;} else {mostRight.right = null;}} else {pre.append("{").append(cur.key).append(",").append(cur.value).append(",").append(cur.parent == null ? "null" : cur.parent.value).append("}\t");}cur = cur.right;}return pre.toString();}public String inOrder() {StringBuilder in = new StringBuilder();if (root == null) {return in.toString();}TreeNode<K, V> cur = root;while (cur != null) {if (cur.left != null) {TreeNode<K, V> mostRight = cur.left;while (mostRight.right != null && mostRight.right != cur) {mostRight = mostRight.right;}if (mostRight.right == null) {mostRight.right = cur;cur = cur.left;continue;} else {mostRight.right = null;in.append("{").append(cur.key).append(",").append(cur.value).append(",").append(cur.parent == null ? "null" : cur.parent.value).append("}\t");}} else {in.append("{").append(cur.key).append(",").append(cur.value).append(",").append(cur.parent == null ? "null" : cur.parent.value).append("}\t");}cur = cur.right;}return in.toString();}/*** 删除伸展树指定的关键字,基本的删除算法的思想是* 首先查找这个被删除的元素,然后这个元素就会变成根元素* 然后删除这个根元素,同时查找其左子树的最大值,这个最大值* 也会变成根元素,这个根元素一定右子树为空,那么把这个根元素的** @param key 关键字* @return 返回被删除的关键字对应的值*/public V delete(K key) {TreeNode<K, V> node = searchHelper(key);if (node == null) {return null;}// 找到node的左孩子的最大值TreeNode<K, V> leftMax = findMax(node.left);// 将左孩子的最大值伸展到根节点,leftMax一定是没有右孩子的// 因为leftMax的伸展百分之百是left-left型,伸展之后是right-right型// 后面的伸展只能在这两个型之间跳跃splaying(leftMax);leftMax.right = node.right;node.left = null;node.right = null;return node.value;}private TreeNode<K, V> findMax(TreeNode<K, V> root) {while (root != null && root.right != null) {root = root.right;}return root;}/*** 单向右旋转** @param node 被旋转的结点*/private void singleRightRotate(TreeNode<K, V> node) {// 特别注意在旋转过程中更新结点的父亲指针,否则将会导致回溯// 过程中产生某些意外情况TreeNode<K, V> left = node.left;node.left = left.right;if (left.right != null) {left.right.parent = node;}left.parent = node.parent;if (node.parent == null) {// 如果当前旋转的是根节点root = left;} else if (node == node.parent.left) {node.parent.left = left;} else {node.parent.right = left;}left.right = node;node.parent = left;}/*** 单向左旋转** @param node 被旋转的结点*/private void singleLeftRotate(TreeNode<K, V> node) {TreeNode<K, V> right = node.right;node.right = right.left;if (right.left != null) {right.left.parent = node;}right.parent = node.parent;if (node.parent == null) {root = right;} else if (node == node.parent.left) {node.parent.left = right;} else {node.parent.right = right;}right.left = node;node.parent = right;}/*** 双向右旋转** @param node 被旋转的结点*/private void doubleRightRotate(TreeNode<K, V> node) {singleLeftRotate(node.left);singleRightRotate(node);}/*** 双向左旋转** @param node 被旋转的结点*/private void doubleLeftRotate(TreeNode<K, V> node) {singleRightRotate(node.right);singleLeftRotate(node);}/*** 根据关键字查找指定的值,每一次查找都会导致被查找的结点* 变成根结点,并且其他结点的位置深度基本上下降一半** @param key 关键字* @return 返回key对应的值*/public V search(K key) {TreeNode<K, V> target = searchHelper(key);return target == null ? null : target.value;}/*** 从某个结点开始展开,具体的展开规则是:* (1)node.parent == root && node.parent.left == node,* 那么将node.parent直接右旋,这样node将会成为根节点* (2)node.parent == root && node.parent.right == node,* 那么将node.parent直接左旋,这样node将会成为根节点* (3)node.parent != root,node.parent == node.parent.left* && node == node.parent.right,那么将node.parent.parent双向右旋* (4)node.parent != root,node.parent == node.parent.right* && node == node.parent.left,那么将node.parent.parent双向左旋* (5)node.parent != root,node.parent == node.parent.left* && node == node.parent.left,那么将node.parent.parent单向右旋,* 然后将node.parent单向右旋* (6)node.parent != root,node.parent == node.parent.right* && node == node.parent.right,那么将node.parent.parent单向左旋,* 然后将node.parent单向左旋** @param node 待旋转的结点*/private void splaying(TreeNode<K, V> node) {while (node.parent != null) {if (node.parent == root) {if (node.parent.left == node) {// 情况(1)singleRightRotate(node.parent);} else {// 情况(2)singleLeftRotate(node.parent);}} else if (node.parent == node.parent.parent.left) {if (node == node.parent.right) {// 情况(3)doubleRightRotate(node.parent.parent);} else {// 情况(5)singleRightRotate(node.parent.parent);singleRightRotate(node.parent);}} else {if (node == node.parent.right) {// 情况(6)singleLeftRotate(node.parent.parent);singleLeftRotate(node.parent);} else {// 情况(4)doubleLeftRotate(node.parent.parent);}}}}/*** 搜索SplayTree中具有指定关键字的结点** @param key 关键字* @return 返回关键字和key相等的结点,如果不存在,返回null*/private TreeNode<K, V> searchHelper(K key) {TreeNode<K, V> cur = root;while (cur != null) {int cmp = cur.key.compareTo(key);if (cmp < 0) {cur = cur.right;} else if (cmp > 0) {cur = cur.left;} else {break;}}// 可能从break跳出,也可能完全没进入while循环if (cur != null) {splaying(cur);}return cur;}/*** 伸展树的结点类型** @param <K> 关键字类型* @param <V> 值类型*/private static class TreeNode<K extends Comparable<K>, V> {public K key;public V value;public TreeNode<K, V> left;public TreeNode<K, V> right;public TreeNode<K, V> parent;public TreeNode(K key, V value) {this.key = key;this.value = value;}public void setParent(TreeNode<K, V> parent) {this.parent = parent;}}public static void main(String[] args) {SplayTree<Integer, Integer> splayTree = new SplayTree<>();splayTree.insert(1, 1);splayTree.insert(32, 32);splayTree.insert(30, 30);splayTree.insert(31, 31);splayTree.insert(28, 28);splayTree.insert(29, 29);splayTree.insert(26, 26);splayTree.insert(27, 27);splayTree.insert(24, 24);splayTree.insert(25, 25);splayTree.insert(22, 22);splayTree.insert(23, 23);splayTree.insert(20, 20);splayTree.insert(21, 21);splayTree.insert(18, 18);splayTree.insert(19, 19);splayTree.insert(16, 16);splayTree.insert(17, 17);splayTree.insert(14, 14);splayTree.insert(15, 15);splayTree.insert(12, 12);splayTree.insert(13, 13);splayTree.insert(10, 10);splayTree.insert(11, 11);splayTree.insert(8, 8);splayTree.insert(9, 9);splayTree.insert(6, 6);splayTree.insert(7, 7);splayTree.insert(4, 4);splayTree.insert(5, 5);splayTree.insert(2, 2);splayTree.insert(3, 3);System.out.println(splayTree.preOrder());System.out.println(splayTree.inOrder());System.out.println(splayTree.search(2));System.out.println(splayTree.search(3));System.out.println(splayTree.search(4));System.out.println(splayTree.search(5));System.out.println(splayTree.search(6));System.out.println(splayTree.search(7));System.out.println(splayTree.search(8));System.out.println(splayTree.search(9));System.out.println("访问部分结点后遍历:");System.out.println(splayTree.preOrder());System.out.println(splayTree.inOrder());}
}

http://www.hkea.cn/news/176953/

相关文章:

  • 做网站接广告赚钱么凡科建站和华为云哪个好
  • 成都网站建设科技公seo营销外包公司
  • 重庆有哪些做网站 小程序的百度搜索引擎的特点
  • 仁怀哪里可以做网站自动秒收录网
  • 重庆市建设局网站推广软件一键发送
  • 合肥网络推广网络运营网站seo诊断分析和优化方案
  • 网站优化公司免费咨询sem优化推广
  • 个人做网站赚钱么宁波seo推荐推广平台
  • 员工支付做网站的费用分录成都营销型网站制作
  • 专业做网站的公司邢台专业做网站关键词搜索优化
  • 电商网站建设方案模板杭州百度首页优化
  • 网站建设服务价格东莞市网站建设
  • 网站开发所需要的的环境佛山网络推广哪里好
  • php网站的优点关键路径
  • 电子政务与网站建设 总结湖南网站推广
  • 境外网站做网站涉黄互联网媒体广告公司
  • 河南做网站公司汉狮怎么做蛋糕
  • 哈 做网站网店代运营收费
  • 制作网页的三大技术是什么郑州seo顾问
  • 网站建设报价流程行业网站网址
  • 提供邯郸做wap网站网页推广方案
  • 网站从域名广告营销公司
  • 网站链接的常见形式免费广告网
  • 微信微网站开发教程百度大数据平台
  • 网站服务设计引流推广是什么意思
  • 学校网站建设管理办法本周新闻热点事件
  • 网站移动版怎么做网站创建公司
  • wordpress 微商城模板下载地址苏州seo推广
  • 珠海网站哪家好百度com百度一下你
  • wordpress wp.net网络优化工程师是做什么的