SplayTree高分测试用例

news2025/1/16 17:45:38

测试用例结果展示

覆盖率

 变异得分

测试注意点

  1. 从SplayTree测起,然后再测SubSplayTree,因为前者调用后者。
  2. SplaySubTree的remove方法大部分内容需要通过反射才能测到。
  3. value和index在SplayTree当中都不是唯一的。一个index可能对应多个value。

不足之处

  1. 没考虑到异常怎么接住。
  2. 对SplayTree这个数据结构的理解还很浅显。

测试文件MyTest.java

package net.mooctest;

import static org.junit.Assert.*;

import java.lang.reflect.Field;
import java.util.Arrays;

import org.junit.Before;
import org.junit.Test;

public class MyTest {
	
	private Integer valArr[];
	private Integer remArr[];
	private Integer conArr[];
	private SplayTree<Integer> splayTree;
	private int howmanynumbers;
	private int removeCnt;
	private int containsCnt;
	
	@Before
	public void initializeValArr() {
		
		this.howmanynumbers = 100;
		this.removeCnt = 0;
		this.containsCnt = 0;
		
		valArr = new Integer[howmanynumbers];  
		remArr = new Integer[howmanynumbers/7+1];  
		conArr = new Integer[howmanynumbers/9+1];
		
		for(int i=0;i<this.howmanynumbers;i++) {
			int val = (int)(Math.random()*100);
//			System.out.println(val);
			valArr[i] = val;
			if(i%7==0) {
				remArr[this.removeCnt++] = val;
			}
			if(i%9==0) {
				conArr[this.containsCnt++] = val;
			}
		}
		
	}

	@Test
	public void testMain() {
		SplayTree.main(null);
	}
	
	// 测试remove和contains
	@Test
	public void test001() {
		splayTree = new SplayTree<Integer>();
		for(int i=0;i<this.howmanynumbers;i++) {
			splayTree.add(valArr[i]);
			assertNull(splayTree.root.join(splayTree.root));
		}
		assertNotNull(splayTree.root.add(null));
		assertEquals(howmanynumbers, splayTree.size());
		
		for(int i=0;i<this.removeCnt;i++) {
			int valToRemove = remArr[i];
			assertTrue(splayTree.contains(valToRemove));
			splayTree.remove(valToRemove);
		}
		assertEquals(howmanynumbers-removeCnt, splayTree.size());
		
		for(int i=0;i<this.containsCnt;i++) {
			int valToVarify = conArr[i];
			assertTrue(splayTree.contains(valToVarify));
		}
	}
	
	// 测试remove和contains
	@Test
	public void test002() {
		splayTree = new SplayTree<Integer>();
		for(int i=0;i<this.howmanynumbers;i++) {
			splayTree.add(valArr[i]);
			assertNull(splayTree.root.split(splayTree.root.getData()));
		}
		assertEquals(howmanynumbers, splayTree.size());
		
		for(int i=0;i<this.removeCnt;i++) {
			int valToRemove = remArr[i];
			assertTrue(splayTree.contains(valToRemove));
			splayTree.remove(valToRemove);
		}
		assertEquals(howmanynumbers-removeCnt, splayTree.size());
		
		for(int i=0;i<this.containsCnt;i++) {
			int valToVarify = conArr[i];
			assertTrue(splayTree.contains(valToVarify));
		}
	}
	
	// 测试get和indexOf
	// 不能再用随机生成的数据,因为随机数据很可能重复
	@Test
	public void test003() {
		splayTree = new SplayTree<Integer>();
		for(int i=0;i<this.howmanynumbers;i++) {
			splayTree.add(i*17);
		}
		assertEquals(howmanynumbers, splayTree.size());
		
		long idxArr[] = new long[howmanynumbers];
		
		for(int i=0;i<splayTree.size();i++) {
			idxArr[i] = splayTree.indexOf(i*17);
		}
		
		for(int i=0;i<splayTree.size();i++) {
			assertEquals(i*17, (int)splayTree.get(idxArr[i]));
		}
		assertNull(splayTree.get(-1));
		assertNull(splayTree.get(splayTree.size()+1));
	}
	
	
	//测试toString()
	@Test
	public void test004() {
		int primeArr[] = {
			2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 	
		};
		
		splayTree = new SplayTree<Integer>();
		
		for(int i=0;i<primeArr.length;i++) {
			splayTree.add(primeArr[i]);
		}
		
//		System.out.println(splayTree.toString());
//		String expectedStr = " data=2 left= null right null sz=1 cnt=1\n";
//		assertEquals(expectedStr, splayTree.toString());
		
		String expectedStr = " data=71 left=67 right null sz=20 cnt=1\n" + 
				" data=67 left=61 right null sz=19 cnt=1\n" + 
				" data=61 left=59 right null sz=18 cnt=1\n" + 
				" data=59 left=53 right null sz=17 cnt=1\n" + 
				" data=53 left=47 right null sz=16 cnt=1\n" + 
				" data=47 left=43 right null sz=15 cnt=1\n" + 
				" data=43 left=41 right null sz=14 cnt=1\n" + 
				" data=41 left=37 right null sz=13 cnt=1\n" + 
				" data=37 left=31 right null sz=12 cnt=1\n" + 
				" data=31 left=29 right null sz=11 cnt=1\n" + 
				" data=29 left=23 right null sz=10 cnt=1\n" + 
				" data=23 left=19 right null sz=9 cnt=1\n" + 
				" data=19 left=17 right null sz=8 cnt=1\n" + 
				" data=17 left=13 right null sz=7 cnt=1\n" + 
				" data=13 left=11 right null sz=6 cnt=1\n" + 
				" data=11 left=7 right null sz=5 cnt=1\n" + 
				" data=7 left=5 right null sz=4 cnt=1\n" + 
				" data=5 left=3 right null sz=3 cnt=1\n" + 
				" data=3 left=2 right null sz=2 cnt=1\n" + 
				" data=2 left= null right null sz=1 cnt=1\n";
		
		assertEquals(expectedStr, splayTree.toString());
	}
	
	//测试SplaySubTree--find
	@Test(timeout=4000)
	public void test005() {
		SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(null);
		assertNull(splaySubTree.find(1));
		int primeArr[] = {
			2, 41, 5, 7, 67, 23, 11,  17, 19
		};
		for(int i=0;i<primeArr.length;i++) {
			splaySubTree = splaySubTree.add(primeArr[i]);
		}
//		System.out.println(splaySubTree.toString());
		assertNull(splaySubTree.find(20));
	}
	
	//测试SplaySubTree--remove
	@Test(timeout=4000)
	public void test006() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(0);
		
		int primeArr[] = {
			2, 41, 5, 7, 23, 11, 67, 17, 19
		};
		
		System.out.println(primeArr.length);
		
		for(int i=0;i<primeArr.length;i++) {
			splaySubTree = splaySubTree.add(primeArr[i]);
		}
		
		assertNotNull(splaySubTree.remove(20));
		
		assertEquals(primeArr.length+1,splaySubTree.remove(null).size());

  
        // 获取 SplaySubTree<Integer> 的 Class 对象  
        Class<?> splaySubTreeClass = splaySubTree.getClass();  
  
        // 获取私有属性 count 的 Field 对象  
        Field countField = splaySubTreeClass.getDeclaredField("count");  
  
        // 设置私有属性 count 的可访问性  
        countField.setAccessible(true); 
		
		splaySubTree = splaySubTree.remove(7);
		// 访问私有属性 count 的值  
        int countValue = (int) countField.get(splaySubTree);  
//        System.out.println("countValue: " + countValue);
        assertEquals(0, countValue);
//		System.out.println(splaySubTree.toString());
		splaySubTree = splaySubTree.remove(7);
		countValue = (int) countField.get(splaySubTree);  
//        System.out.println("countValue: " + countValue); 
        assertEquals(-1, countValue);

	}
	
		//测试SplaySubTree--remove
		@Test(timeout=4000)
		public void test007() {
			SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(1);
			splaySubTree.remove(1);
		}
		
		//测试SplaySubTree--remove
		@Test(timeout=4000)
		public void test008() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NullPointerException {
			SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(1);
			// 获取 SplaySubTree<Integer> 的 Class 对象  
	        Class<?> splaySubTreeClass = splaySubTree.getClass();  
	        // 获取私有属性 count 的 Field 对象  
	        Field leftField = splaySubTreeClass.getDeclaredField("left");  
	        // 设置私有属性 count 的可访问性  
	        leftField.setAccessible(true);         
			SplaySubTree<Integer> splaySubTree2 = new SplaySubTree<Integer>(2);
			
			leftField.set(splaySubTree,splaySubTree2);
			
			
			
			splaySubTree.remove(1);
		}
		
		//测试SplaySubTree--remove
		@Test(timeout=4000)
		public void test009() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NullPointerException {
			SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(1);
			// 获取 SplaySubTree<Integer> 的 Class 对象  
	        Class<?> splaySubTreeClass = splaySubTree.getClass();  
	        // 获取私有属性 count 的 Field 对象  
	        Field rightField = splaySubTreeClass.getDeclaredField("right");  
	        // 设置私有属性 count 的可访问性  
	        rightField.setAccessible(true);         
			SplaySubTree<Integer> splaySubTree2 = new SplaySubTree<Integer>(2);
			
			rightField.set(splaySubTree,splaySubTree2);
		
			splaySubTree.remove(1);
		}
				
		
		//测试SplaySubTree--remove
		@Test(timeout=4000)
		public void test0010() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NullPointerException {
			SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(1);
			// 获取 SplaySubTree<Integer> 的 Class 对象  
	        Class<?> splaySubTreeClass = splaySubTree.getClass();  
	        // 获取私有属性 count 的 Field 对象  
	        Field leftField = splaySubTreeClass.getDeclaredField("left");
	        Field parentField = splaySubTreeClass.getDeclaredField("parent");  
	        // 设置私有属性 count 的可访问性  
	        leftField.setAccessible(true);   
	        parentField.setAccessible(true);   
	        
			SplaySubTree<Integer> splaySubTree2 = new SplaySubTree<Integer>(2);
			leftField.set(splaySubTree,splaySubTree2);
			SplaySubTree<Integer> splaySubTree3 = new SplaySubTree<Integer>(3);
			parentField.set(splaySubTree,splaySubTree3);
		
			splaySubTree.remove(1);
		}
		
		//测试SplaySubTree--remove
		@Test(timeout=4000)
		public void test0011() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NullPointerException {
			SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(1);
			// 获取 SplaySubTree<Integer> 的 Class 对象  
	        Class<?> splaySubTreeClass = splaySubTree.getClass();  
	        // 获取私有属性 count 的 Field 对象  
	        Field rightField = splaySubTreeClass.getDeclaredField("right");  
	        Field parentField = splaySubTreeClass.getDeclaredField("parent"); 
	        // 设置私有属性 count 的可访问性  
	        rightField.setAccessible(true);   
	        parentField.setAccessible(true); 
	        
			SplaySubTree<Integer> splaySubTree2 = new SplaySubTree<Integer>(2);
			rightField.set(splaySubTree,splaySubTree2);
			SplaySubTree<Integer> splaySubTree3 = new SplaySubTree<Integer>(3);
			parentField.set(splaySubTree,splaySubTree3);
		
			splaySubTree.remove(1);
		}
		
		//测试SplaySubTree--remove
		@Test(timeout=4000)
		public void test0012() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NullPointerException {
			SplaySubTree<Integer> splaySubTree = new SplaySubTree<Integer>(1);
			// 获取 SplaySubTree<Integer> 的 Class 对象  
	        Class<?> splaySubTreeClass = splaySubTree.getClass();  
	        // 获取私有属性 count 的 Field 对象  
	        Field rightField = splaySubTreeClass.getDeclaredField("right");  
	        Field leftField = splaySubTreeClass.getDeclaredField("left"); 
	        // 设置私有属性 count 的可访问性  
	        rightField.setAccessible(true);   
	        leftField.setAccessible(true); 
	        
			SplaySubTree<Integer> splaySubTree2 = new SplaySubTree<Integer>(2);
			rightField.set(splaySubTree,splaySubTree2);
			SplaySubTree<Integer> splaySubTree3 = new SplaySubTree<Integer>(3);
			leftField.set(splaySubTree,splaySubTree3);

			String expectedStr = " data=1 left=3 right=2 sz=1 cnt=1\n" + 
					" data=3 left= null right null sz=1 cnt=1\n" + 
					" data=2 left= null right null sz=1 cnt=1\n";
			
			assertEquals(expectedStr, splaySubTree.toString());
		}

}

被测文件(1/2)SplayTree.java

package net.mooctest;

import java.util.Arrays;

public class SplayTree <T extends Comparable<T>> {
	SplaySubTree<T> root;
	
	public SplayTree(){
		root = new SplaySubTree<T>(null);
	}
	
	/**
	 * @param index - of the node to search for.
	 * @return  - null if index<=0 or index>=size otherwise SubTree at index. 
	 */
	public T get(long index) {
		SplaySubTree<T> cT = root.get(index);
		if(cT==null)return null;
		cT.splay();
		root = cT;
		return cT.getData();
	}
	
	/**
	 * @return - the number of nodes in the tree.
	 */
	public long size() { return root.size();}

	/**
	 * @param node - to search for.
	 * @return - the index of node. All nodes are ordered according to the compareTo(T) method.
	 *         
	 */
	public long indexOf(T node) {
		long index = root.indexOf(node);
		get(index);
		return index;
	}
	
	/**
	 * @param node - is added to the tree.
	 *             If node is null tree is unchanged.
	 */
	public void add(T node) {
		root = root.add(node);
	}
	
	/**
	 * @param node - is removed from the tree.
	 *             If node is null tree is unchanged.
	 */
	public void remove(T node) {
		root = root.remove(node);
	}
	
	/**
	 * @param node
	 * @return
	 */
	public boolean contains(T node) {
		SplaySubTree<T> temp = root.find(node);
		if(temp!=null){
			temp.splay();
			root = temp;
		}
		return temp != null;
	}
	
	@Override
	public String toString(){
		return root.toString();
	}

	public static void main(String[] args) {
		SplayTree<Integer> test = new SplayTree<Integer>();
		int howmanynumbers = 10000;
		for (int i = 0; i < howmanynumbers; i++) {
			int val = (int)(Math.random()*100);
			test.add(val);
		}
		

		System.out.println(test);
	}
}

被测文件(2/2)SubSplayTree.java

package net.mooctest;

public class SplaySubTree<T extends Comparable<T>> {

	private T data;
	private SplaySubTree<T> left, right, parent;
	private long size; // number of nodes in tree
	private int count;

	/**
	 * @param node
	 *            - If node==null then size will be 0 otherwise node will be in the
	 *            tree and size will be 1
	 */
	public SplaySubTree(T node) {
		data = node;
		if (node != null) {
			size = count = 1;
		}
	}
	
	

	public String toString() {
		String lft = "";
		String rght = "";
		String myData = " data=" + data;
		if (left != null) {
			myData += " left=" + left.data;
			lft = left.toString();
		} else {
			myData += " left= null";
		}
		if (right != null) {
			myData += " right=" + right.data;
			rght = right.toString();
		} else {
			myData += " right null";
		}
		myData += " sz="+size + " cnt="+count;
		return myData + "\n" + lft + rght;
	}

	public T getData() {
		return data;
	}

	/**
	 * @param index
	 *            - of the node to search for.
	 * @return - null if index<=0 or index>=size otherwise SubTree at index.
	 */
	public SplaySubTree<T> get(long index) {
		if (index > size || index < 0)
			return null;
		long cS = 1;
		SplaySubTree<T> cT = this;
		if (cT.left != null)
			cS += cT.left.size;
		while (cS != index) {
			if (cS > index) {
				cS--;
				cT = cT.left;
				if (cT != null && cT.right != null)
					cS -= cT.right.size;
			} else {
				cS++;
				cT = cT.right;
				if (cT != null && cT.left != null)
					cS += cT.left.size;
			}
		}
		return cT;
	}

	/**
	 * @return - the number of nodes in the tree.
	 */
	public long size() {
		return size;
	}

	/**
	 * @param node
	 *            - to search for.
	 * @return - the index of node. All nodes are ordered according to the
	 *         compareTo(T) method.
	 * 
	 */
	public long indexOf(T node) {
		if (node == null)
			return -1;
		long cI = 1;
		SplaySubTree<T> cT = this;
		if (cT.left != null)
			cI += cT.left.size;
		while (!cT.data.equals(node)) {
			if (cT.data.compareTo(node) > 0) {
				cI--;
				cT = cT.left;
				if (cT != null && cT.right != null)
					cI -= cT.right.size;
			} else {
				cI++;
				cT = cT.right;
				if (cT != null && cT.left != null)
					cI += cT.left.size;
			}
			if (cT == null)
				return -1;
		}

		return cI;
	}

	/**
	 * @param node
	 *            - is added to the tree. If node is null tree is unchanged.
	 * @return - New root of the tree.
	 */
	public SplaySubTree<T> add(T node) {
		if (node == null)
			return this;
		if (this.data == null)
			return new SplaySubTree<T>(node);
		SplaySubTree<T> current = this;
		SplaySubTree<T> child = null;

		if (this.data.compareTo(node) < 0)
			child = this.right;
		else if(this.data.compareTo(node)>0)
			child = this.left;
		while (child != null && current.data.compareTo(node)!=0) {
			current = child;
			if (current.data.compareTo(node) < 0)
				child = current.right;
			else if(current.data.compareTo(node)>0)
				child = current.left;
		}
		
		SplaySubTree<T> newNode = new SplaySubTree<T>(node);
		if (current.data.compareTo(node) < 0) {
			current.right = newNode;
		} else if(current.data.compareTo(node)>0){
			current.left = newNode;
		}else {
			current.size++;
			current.count++;
			newNode = current;
			current = newNode.parent;
		}
		newNode.parent = current;
		if (newNode.splay())
			return newNode;
		return this;
	}

	/**
	 * @param node
	 *            - is removed from the tree. If node is null tree is unchanged.
	 * @return - New root of the tree.
	 */
	public SplaySubTree<T> remove(T node) {
		if (node == null)
			return this;
		SplaySubTree<T> x = find(node);
		if (x == null)
			return this;
		if(x.data.equals(node)) {
			x.count--;
			x.size--;
			if(size>0) {
				x.splay();
				return x;
			}
		}
		// To delete a node x:
		// if x has no children remove it.

		if (x.left == null && x.right == null) {
			if (x.parent != null) {
				if (x.parent.left == x) {
					parent.left = null;
				} else
					parent.right = null;
			} else
				return new SplaySubTree(null);

		}
		// if x has one child remove x, and put the child in place of x
		if (x.left == null) {
			if (x.parent != null) {
				if (x.parent.left == x) {
					parent.left = x.right;
					x.right.parent = parent;
					x = x.right;
				} else {
					parent.right = x.right;
					x.right.parent = parent;
					x = x.right;
				}
			} else {
				x.right.parent = null;
				return x.right;
			}
		} else if (x.right == null) {
			if (x.parent != null) {
				if (x.parent.left == x) {
					parent.left = x.left;
					x.left.parent = parent;
					x = x.left;
				} else {
					parent.right = x.left;
					x.left.parent = parent;
					x = x.left;
				}
			} else {
				x.left.parent = null;
				return x.left;
			}
		} else {
			// if x has two children, swap its value with that of
			// the rightmost node of its left sub tree
			SplaySubTree<T> rmc = x.left;
			while (rmc.right != null)
				rmc = rmc.right;
			x.data = rmc.data;
			// Then remove that node instead.
			rmc.left.parent = rmc.parent;
			if (rmc.parent == x) {
				x.left = rmc.left;
			} else {
				rmc.parent.right = rmc.left;
			}
			x = rmc;
		}

		// After deletion, splay the parent of the removed node to the top of
		// the tree.
		x.splay();
		return x;
	}

	/**
	 * @param other
	 * @return
	 */
	public SplaySubTree<T> join(SplaySubTree<T> other) {
		return null;

	}

	/**
	 * @param node
	 * @return
	 */
	public SplaySubTree<T> split(T node) {
		return null;
	}

	/**
	 * @param node
	 * @return
	 */
	public SplaySubTree<T> find(T node) {
		SplaySubTree<T> current = this;
		if (this.data == null)
			return null;
		while (current != null) {
			if (node.equals(current.data))
				return current;
			if (node.compareTo(current.data) < 0)
				current = current.left;
			else
				current = current.right;
		}
		return current;
	}

	/**
	 * Assuming this node is an interior or leaf node of a larger tree this method
	 * moves this node up to the root balancing the tree in the process
	 */
	public boolean splay() {
		
		while (this.parent != null) {
			SplaySubTree<T> p = this.parent;
			SplaySubTree<T> g = p.parent;
			if (g == null && this == p.left) {
				zig();
			} else if (g == null && this == p.right) {
				zag();
			} else if (p.left == this && g.left == p) {
				zigzig();
			} else if (p.right == this && g.right == p) {
				zagzag();
			} else if (p.right == this && g.left == p) {
				zigzag();
			} else {
				zagzig();
			}
		}
		return true;
	}

	/**
	 * This is a helper method used in the splay() operation
	 */
	private void zig() {
		SplaySubTree<T> b = this.right;
		SplaySubTree<T> p = this.parent;

		this.right = p;
		p.parent = this;
		p.left = b;
		if (b != null)
			b.parent = p;
		this.parent = null;
		p.size = p.count;
		if (p.right != null)
			p.size += p.right.size;
		if (b != null)
			p.size += b.size;
		this.size = p.size + this.count;
		if (this.left != null)
			this.size += this.left.size;
	}

	/**
	 * This is a helper method used in the splay() operation
	 */
	private void zag() {
		SplaySubTree<T> b = this.left;
		SplaySubTree<T> p = this.parent;

		this.left = p;
		p.parent = this;
		p.right = b;
		if (b != null)
			b.parent = p;
		this.parent = null;
		p.size = p.count;
		if (b != null)
			p.size += b.size;
		if (p.left != null)
			p.size += p.left.size;
		this.size = p.size + this.count;
		if (this.right != null)
			this.size += this.right.size;
	}

	/**
	 * This is a helper method used by zigzig, zagzag, zigzag, zagzig This "fixes"
	 * the great grandparent
	 */
	private void fixGG(SplaySubTree<T> g) {
		SplaySubTree<T> gg = g.parent;
		if (gg != null) {
			if (g == gg.left)
				gg.left = this;
			if (g == gg.right)
				gg.right = this;
		}
		this.parent = gg;
		// might need to update size
	}

	/**
	 * This is a helper method used in the splay() operation
	 */
	private void zigzig() {
		SplaySubTree<T> g = parent.parent;
		SplaySubTree<T> b = this.right;
		SplaySubTree<T> p = this.parent;
		SplaySubTree<T> c = p.right;
		fixGG(g);

		if (b != null)
			b.parent = p;
		p.left = b;
		if (c != null)
			c.parent = g;
		g.left = c;
		g.parent = p;
		p.right = g;
		p.parent = this;
		this.right = p;

		g.size = g.count;
		if (c != null)
			g.size += c.size;
		if (g.right != null)
			g.size += g.right.size;
		p.size = p.count;
		if (g != null)
			p.size += g.size;
		if (b != null)
			p.size += b.size;
		this.size = p.size + this.count;
		if (this.left != null)
			this.size += this.left.size;
	}

	/**
	 * This is a helper method used in the splay() operation
	 */
	private void zagzag() {
		SplaySubTree<T> g = parent.parent;
		SplaySubTree<T> b = this.left;
		SplaySubTree<T> p = this.parent;
		SplaySubTree<T> c = p.left;

		fixGG(g);
		if (b != null)
			b.parent = p;
		// above line throws java.lang.NullPointerException

		p.right = b;
		if (c != null)
			c.parent = g;
		g.right = c;
		g.parent = p;
		p.left = g;
		p.parent = this;
		this.left = p;
		g.size = g.count;
		if (g.left != null)
			g.size += g.left.size;
		if (c != null)
			g.size += c.size;
		p.size = g.size + p.count;
		if (b != null)
			p.size += b.size;
		this.size = p.size + this.count;
		if (this.right != null)
			this.size += this.right.size;
	}

	/**
	 * This is a helper method used in the splay() operation
	 */
	private void zigzag() {
		SplaySubTree<T> g = parent.parent;
		SplaySubTree<T> b = this.left;
		SplaySubTree<T> p = this.parent;
		SplaySubTree<T> c = this.right;

		fixGG(g);
		if (b != null)
			b.parent = p;
		p.right = b;
		if (c != null)
			c.parent = g;
		g.left = c;
		p.parent = this;
		this.left = p;
		g.parent = this;
		this.right = g;
		g.size = g.count;
		if (g.right != null)
			g.size += g.right.size;
		if (c != null)
			g.size += c.size;
		p.size = p.count;
		if (p.left != null)
			p.size += p.left.size;
		if (b != null)
			p.size += b.size;
		this.size = g.size + p.size + this.count;
	}

	/**
	 * This is a helper method used in the splay() operation
	 */
	private void zagzig() {

		SplaySubTree<T> g = parent.parent;
		SplaySubTree<T> b = this.right;
		SplaySubTree<T> p = this.parent;
		SplaySubTree<T> c = this.left;
		fixGG(g);
		if (b != null)
			b.parent = p;
		p.left = b;
		if (c != null)
			c.parent = g;
		g.right = c;
		p.parent = this;
		this.right = p;
		g.parent = this;
		this.left = g;
		g.size = g.count;
		if (g.left != null)
			g.size += g.left.size;
		if (c != null)
			g.size += c.size;
		p.size = p.count;
		if (p.right != null)
			p.size += p.right.size;
		if (b != null)
			p.size += b.size;
		this.size = g.size + p.size + this.count;
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1197485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣100题——子串

560.和为k的子数组 这道题目不是滑动窗口的类型&#xff0c;因为长度并不是固定的。&#xff08;好的&#xff0c;我在说废话&#xff09; 注意题目要求是子数组&#xff0c;且是连贯的。那这里的话&#xff0c;解法有很多&#xff0c;最简单的就是暴力解法&#xff0c;但在这…

ChatGPT 如何改变科研之路

《Nature》全球博士后调查[1]中约有三分之一的受访者正在使用人工智能聊天机器人来帮助完善文本、生成或编辑代码、整理其领域的文献等等。 来自巴西的 Rafael Bretas 在日本生活了十多年&#xff0c;日语说得很好。书面日语的各个方面&#xff0c;例如严格的礼貌等级制度&…

CCNA课程实验-12-NAT

目录 实验条件网络拓朴需求 配置实现基础配置R1PC1ISPR2HTTP_ServerDNS_Server 配置在R2上配置静态NAT&#xff0c;将内网DNS Server关联到公网IP&#xff1a;202.1.1.2测试结果 配置在R2上配置静态NAT&#xff0c;将内网HTTP Server的TCP 80端口关联到公网IP&#xff1a;202.1…

力扣138:随机链表的复制

力扣138&#xff1a;随机链表的复制 题目描述&#xff1a; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff…

TiPro7000 Smart Tool V1.1无法打开解决办法

长江存储官网下载的TiPro7000 Smart Tool V1.1在win10运行时无法打开&#xff0c;转圈圈之后就没有反应了。官网下载的压缩包解压之后内容如下图。 解决办法&#xff1a;将.exe文件名的“致钛”二字删掉即可。文件名不能有中文。 打开后软件界面如下。 吐槽一下这软件做得挺简…

【Python大数据笔记_day06_Hive】

hive内外表操作 建表语法 create [external] table [if not exists] 表名(字段名 字段类型 , 字段名 字段类型 , ... ) [partitioned by (分区字段名 分区字段类型)] # 分区表固定格式 [clustered by (分桶字段名) into 桶个数 buckets] # 分桶表固定格式 注意: 可以排序[so…

Java,多线程,线程安全的懒汉式、死锁、ReentrantLock的使用以及一些知识点补充

关于线程安全地懒汉式有以下几种方式&#xff1a; /*** 实现线程安全的懒汉式*/ public class BankTest {Bank b1 null;Bank b2 null;public static void main(String[] args){BankTest bb new BankTest();Thread t1 new Thread(){Overridepublic void run(){bb.b1 Bank.…

【C++笔记】优先级队列priority_queue的模拟实现

【C笔记】优先级队列priority_queue的模拟实现 一、优先级队列的介绍与使用方式1.1、优先级队列介绍1.2、优先级队列的常见使用 二、优先级队列的模拟实现1.0、仿函数的介绍1.1、构造函数1.2、优先级队列的插入push1.3、优先级队列的删除(删除堆顶元素)1.4、获取堆顶元素1.5、判…

【蓝桥每日一题]-快速幂,倍增,滑动窗口(保姆级教程 篇1) #麦森数 #青蛙跳

之前是考试准备&#xff0c;所以有几天没更新&#xff0c;今天开始继续更新 目录 快速幂模板 题目&#xff1a;麦森数 思路&#xff1a; 题目&#xff1a;青蛙跳 思路&#xff1a; 快速幂模板 #include <bits/stdc.h> #define ll long long using namespa…

人工智能与教育:未来的技术融合

人工智能与教育&#xff1a;未来的技术融合 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;逐渐渗透到我们生活的方方面面&#xff0c;包括教育领域。AI与教育的结合&#xff0c;有望引发一场教育变革&#xff0c;提高教学效果&#xff0c;实现个性化学习&…

ENVI IDL:如何基于气象站点数据进行反距离权重插值?

01 前言 仅仅练习&#xff0c;大可使用ArcGIS或者已经封装好的python模块进行插值&#xff0c;此处仅仅从底层理解如何从公式和代码理解反距离权重插值的过程&#xff0c;从而更深刻的理解IDL的使用和插值的理解。 02 函数说明 2.1 Read_CSV()函数 官方语法如下&#xff1a…

JVM虚拟机:垃圾回收器之Parallel Old(老年代)

本文重点 本文将学习老年代的另外一种垃圾回收器Parallel Old(PO)&#xff0c;这是一种用于老年代的并行化垃圾回收器&#xff0c;它使用标记整理算法进行垃圾回收。 历史 在1.6之前&#xff0c;新生代使用Parallel Scavenge只能搭配老年代的Serial Old收集器&#xff0c;而…

蓝桥杯算法双周赛心得——被替换的身份证(分类讨论)

大家好&#xff0c;我是晴天学长&#xff0c;分类讨论一定要细节啊&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .被替换的身份证 2) .算法思路 假设一方获胜 1.接受数据 2.假设潜梦醒 无非就是&am…

Image透明度点击简述以及Unity2019之后存在无法点击的BUG修复

前言 自Unity2019之后Unity将UGUI模块从内置库修改成了通过PackageManger引入的方式。Image就来源于com.unity.modules.imgui模块。其实代码大体代码跟2018是一致的&#xff0c;但是还是有些细微差别&#xff0c;Image透明度点击不命中就是2019之后才有的问题&#xff0c;2018…

JVM虚拟机:垃圾回收器之CMS(老年代)

本文重点 在前面的课程中我们学习了Serial和PO垃圾回收器,本文将学习一种新的在老年代使用的垃圾回收器CMS。 特点 CMS收集器是一种以获取最短回收停顿时间为目标的收集器(还是会有短暂的STW),适合互联网或者B/S系统的服务器上,这类应用尤其重视服务器的响应速度,希望…

SQL必知会(二)-SQL查询篇(6)-创建计算字段

第7课、创建计算字段 1&#xff09;拼接字段 需求&#xff1a;检索Vendors 表包含供应商的名称和地址的所有信息&#xff0c;返回结果需要把地址括号起来。 SELECT vend_name ( vend_country ) FROM Vendors ORDER BY vend_name;-- 以下例子与上面例子相同工作 SELECT ve…

Rust的崛起:现代必备编程语言,是时候该考虑加入学习了

在不断变化的编程环境中&#xff0c;新的语言和框架如雨后春笋般涌现&#xff0c;需要一个真正强大且设计良好的工具才能脱颖而出。在这些工具中&#xff0c;Rust 已成为效率、安全性和性能的灯塔。从它作为 Mozilla 的一个副项目到它在软件行业中不可否认的增长&#xff0c;Ru…

PHP中传值与引用的区别

在PHP中&#xff0c;变量的传递方式主要分为传值和传引用两种。这两种方式在操作中有一些重要的区别&#xff0c;影响着变量在函数调用或赋值操作中的表现。下面详细解释一下这两种传递方式的区别。 传值&#xff08;By Value&#xff09; 传值是指将变量的值复制一份传递给函…

Python环境安装、Pycharm开发工具安装(IDE)

Python下载 Python官网 Python安装 Python安装成功 Pycharm集成开发工具下载&#xff08;IDE&#xff09; PC集成开发工具 Pycharm集成开发工具安装&#xff08;IDE&#xff09; 安装完成 添加环境变量&#xff08;前面勾选了Path不用配置&#xff09; &#xff08;1&…

个人技术支持

本人目前从事 cnc 自动编程相关职业&#xff0c;主要还是做上位机开发&#xff0c;2021年之前一直从事 Unity3d 开发&#xff0c;本来也是个游戏程序员&#xff0c;后面也是大环境不好&#xff0c;改做了上位机开发&#xff0c;没想到上位机行业现在也是这么不好找工作。 最近…