/**
* @Description: 在索引位置添加节点
* @Param: [index, e]
* @return: void
*/
public void add(int index, E e) {
if (index < 0 || index > size)
throw new IllegalArgumentException("add fail , illegal index~");
else {
Node prev = dummyHead;
for (int i = 0; i < index - 1; i++)
prev = prev.next;
Node newNode = new Node(e); //创建一个新节点
newNode.next = prev.next; //将新节点的下一个设置为prev的下一个节点
prev.next = newNode; // 将prev节点的下一个设置为新节点
//上面三句可以替换为__prev.next = new Node(e , prev.next);
size++;
}
}
/**
* @Description: 删除链表中index位置的元素
* @Param: [index]
* @return: E
*/
public E remove(int index) {
if (index < 0 || index >= size)
throw new IllegalArgumentException("remove fail , illegal index~");
Node prev = dummyHead;
for (int i = 0; i < index; i++)
prev = prev.next;
Node retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size--;
return retNode.e;
}
/**
* @Description: 创建线段树
* @Param: [treeIndex, left, right]
*/
private void buildSegmentTree(int treeIndex, int left, int right) {
if (left == right) { //如果到了叶子节点
tree[treeIndex] = data[left];
return;
}
int leftTreeIndex = leftChild(treeIndex); //获得左子树的索引
int rightTreeIndex = rightChild(treeIndex); //获得右子树的索引
int mid = left + (right - left) / 2; //中点
buildSegmentTree(leftTreeIndex, left, mid); //递归创建左右子树
buildSegmentTree(rightTreeIndex, mid + 1, right);
//融合左右子树的值到父节点
tree[treeIndex] = merger.merger(tree[leftTreeIndex], tree[rightTreeIndex]);
}
/**
* @Description: 查询操作递归函数
* @Param: [treeIndex查询的节点, l, r, queryL, queryR]
* @return: E
*/
private E query(int treeIndex, int l, int r, int queryL, int queryR) {
// 左右边界恰好等于查询边界
if (l == queryL && r == queryR)
return tree[treeIndex];
// 计算左右孩子索引和中点
int leftTreeIndex = leftChild(treeIndex);
int rightTreeIndex = rightChild(treeIndex);
int mid = l + (r - l) / 2;
// 如果查询的左边界大于中点,直接去右孩子中查找
if (queryL >= mid + 1)
return query(rightTreeIndex, mid + 1, r, queryL, queryR);
else if (queryR <= mid) // 如果查询的右边界小于中点,直接去左孩子中查找
return query(leftTreeIndex, l, mid, queryL, queryR);
// 如果查询区间在左右孩子中都有
E leftTreeResult = query(leftTreeIndex, l, mid, queryL, mid);
E rightTreeResult = query(rightTreeIndex, mid + 1, r, mid + 1, queryR);
// 融合左右查询的结果并返回
return merger.merger(leftTreeResult, rightTreeResult);
}
public Node add(Node node, E e) {
if (node == null) {
size++;
return new Node(e);
}
if (e.compareTo(node.e) < 0)
node.left = add(node.left, e);
else if (e.compareTo(node.e) > 0)
node.right = add(node.right, e);
return node;
}
private Node remove(Node node, E e) {
if (node == null)
return null;
else if (e.compareTo(node.e) < 0) {// 如果e小于节点
node.left = remove(node.left, e);
return node;
}
// 如果e大于节点
else if (e.compareTo(node.e) > 0) {
node.right = remove(node.right, e);
return node;
}
// e.compareTo(node.e) = 0
else {
// 如果左子树为空时
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
// 如果右子树为空时
else if (node.right == null) {
Node leftNode = node.left;
node.left = null;
size--;
return leftNode;
}
// 如果左右子树均不为空时
//找到比删除节点大的最小节点_右节点的最小值(左节点的最大值亦可)
Node successor = minimum(node.right);
//用找到的节点顶替删除的节点
successor.right = removeMin(node.right);//removeMin中有一次size--操作,需要size++
successor.left = node.left;
node.left = node.right = null;//此操作需要一次size--,与上面操作抵消
return successor;
}
}
///////////////////////////////////////////////////////////////////////
// 0 //
// / \ parent(i) = (i-1)/2 //
// 1 2 leftChild(i) = 2*i+1 //
// / \ / \ rightChild(i) = 2*i+2 //
// 3 4 5 6 //
///////////////////////////////////////////////////////////////////////
/**
* @Description: 添加元素时的操作
* @Param: [i]
*/
private void siftUp(int index) {
while (index > 0 && data.get(index).compareTo(data.get(parent(index))) > 0) {
swap(index, parent(index));
index = parent(index);
}
}
/**
* @Description: 取出堆中的最大值, 下沉操作
* @Param: [index]
*/
private void siftDown(int index) {
//当该节点的左孩子节点比size大时,下浮停止
while (leftChild(index) < data.getSize()) {
int j = leftChild(index);
//j+1则为右孩子索引,如果右孩子存在并且大于左孩子,j就变为右孩子的索引
if (j + 1 < data.getSize() && data.get(j).compareTo(data.get(j + 1)) < 0)
j++;
//如果当前的值大于或等于子节点的值,停止下沉
if (data.get(index).compareTo(data.get(j)) >= 0)
break;//退出循环
swap(index, j);
index = j;
}
}
/**
* @Description: 向Trie中添加新单词word
* @Param: [word]
*/
public void add(String word) {
Node cur = root; //定义root为当前节点
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) == null)
cur.next.put(c, new Node());
cur = cur.next.get(c);
}
if (!cur.isWord) {
cur.isWord = true;
size++;
}
}
/////////////////////////////////////////////////////
// 对节点y进行向右旋转操作,返回旋转后新的根节点x //
// y x //
// / \ / \ //
// x T4 向右旋转 (y) z y //
// / \ - - - - - - - -> / \ / \ //
// z T3 T1 T2 T3 T4 //
// / \ //
// T1 T2 //
/////////////////////////////////////////////////////
private Node rightRotate(Node y) {
// 暂存y的左节点x和x的右节点t3
Node x = y.left;
Node t3 = x.right;
// 让y成为x的右孩子, t3成为y的左孩子
x.right = y;
y.left = t3;
// 更新Height值
y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
return x;
}
//////////////////////////////////////////////////
// 对节点y进行向左旋转操作,返回旋转后新的根节点x //
// y x //
// / \ / \ //
// T1 x 向左旋转 (y) y z //
// / \ - - - - - - - -> / \ / \ //
// T2 z T1 T2 T3 T4 //
// / \ //
// T3 T4 //
/////////////////////////////////////////////////
private Node leftRotate(Node y) {
// 暂存y的左节点x和x的左孩子t2
Node x = y.right;
Node t2 = x.left;
// 让y成为x的左孩子, t2成为y的右孩子
x.left = y;
y.right = t2;
// 更新Height值
y.height = Math.max(getHeight(y.left), getHeight(y.right)) + 1;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
return x;
}
/////////////////////////////////////////////////
// 对节点y进行向左旋转操作,返回旋转后新的根节点x //
// y x //
// / \ / \ //
// T1 x 向左旋转 (y) y T3 //
// / \ - - - - - - - -> / \ //
// T2 T3 T1 T2 //
/////////////////////////////////////////////////
private Node leftRotate(Node y) {
// 暂存y的左节点x
Node x = y.right;
// 让y成为x的左孩子, t2成为y的右孩子
y.right = x.left;
x.left = y;
x.color = y.color;
y.color = RED;
return x;
}
////////////////////////////////////////////////////
// 对节点y进行右旋转操作,返回旋转后新的根节点x //
// y x //
// / \ / \ //
// x T3 向右旋转 (y) T1 y //
// / \ - - - - - - - -> / \ //
// T1 T2 T2 T3 //
////////////////////////////////////////////////////
private Node rightRotate(Node y) {
// 暂存y的左节点x
Node x = y.left;
// t2成为y的左孩子
y.left = x.right;
x.right = y;
x.color = y.color;
x.color = RED;
return x;
}
/**
* @Description: 向以node为根的红黑树中插入元素(key, value),递归算法
* @Param: [node, key, value]
* @return: 返回插入新节点后红黑树的根
*/
public Node add(Node node, K key, V value) {
if (node == null) {
size++;
return new Node(key, value);//默认插入红色节点
}
if (key.compareTo(node.key) < 0)
node.left = add(node.left, key, value);
else if (key.compareTo(node.key) > 0)
node.right = add(node.right, key, value);
else //key.compareTo(node.key) = 0
node.value = value;
if (isRed(node.right) && !isRed(node.left))
node = leftRotate(node);
if (isRed(node.left) && isRed(node.left.left))
node = rightRotate(node);
if (isRed(node.left) && isRed(node.right))
flipColors(node);
return node;
}