翻转字符串(HDU1062)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class StackX {
private int maxSize;//栈容量
private char[] stackArray;//字符数组
private int top;//栈顶指针
public StackX(int max) {
maxSize = max;
stackArray = new char[maxSize];
top = -1;//初始化栈顶指针
}
public void push(char j) {
stackArray[++top] = j;
}//入栈操作
public char pop() {
return stackArray[top--];
}//出栈
public char peek() {
return stackArray[top];
}//取栈顶元素
public boolean isEmpty() {
return (top == -1);
}//判断栈是否为空
}// 用类构建栈
class Reverser {
private String input;
private String output;
public Reverser(String in) {
this.input = in;
}
public String doRev() {
int stackSize = input.length();
StackX theStack = new StackX(stackSize);
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);//提取字符串中的每个字符
theStack.push(ch);//利用栈的后进先出实现翻转
}
output = "";
while (!theStack.isEmpty()) {
char ch = theStack.pop();
output = output + ch;
}
return output;
}
}
class Main {
public static void main(String[] args) throws IOException {
String input, output;
while (true) {
input = getString();// 字符串的输入
if (input.equals(""))
break;
Reverser theReverser = new Reverser(input);
output = theReverser.doRev();
System.out.println(output);
}
}
public static String getString() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
}
已知先序和中序,输出后序跟层次遍历的结果
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int pre[], in[];
static int n;
static int num = 0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
n = input.nextInt();
pre = new int[n];
in = new int[n];
for (int i = 0; i < n; i++)
pre[i] = input.nextInt();
for (int j = 0; j < n; j++)
in[j] = input.nextInt();
Node root = create(0, n - 1, 0, n - 1);
BFS(root);
System.out.println();
Postorder(root);
}
private static void Postorder(Node root) {
if (root == null)
return;
Postorder(root.lchild);
Postorder(root.rchild);
System.out.printf("%d ", root.data);
}
private static Node create(int preL, int preR, int inL, int inR) {
if (preL > preR)
return null;
Node root = new Node(pre[preL]);
int k;
for (k = inL; k <= inR; k++) {
if (in[k] == pre[preL]) {
break;
}
}
int numLeft = k - inL;
root.lchild = create(preL + 1, preL + numLeft, inL, k - 1);
root.rchild = create(preL + numLeft + 1, preR, k + 1, inR);
return root;
}
static void BFS(Node root) {
Queue<Node> Q = new LinkedList();
Q.offer(root);
while (!Q.isEmpty()) {
Node cur = Q.peek();
Q.poll();
System.out.printf("%d", cur.data);
num++;
if (num < n)
System.out.printf(" ");
if (cur.lchild != null)
Q.offer(cur.lchild);
if (cur.rchild != null)
Q.offer(cur.rchild);
}
}
}
class Node {
public int data;
Node lchild;
Node rchild;
public Node(int data) {
this.data = data;
}
}
import java.util.ArrayList;
class Main {
// 最开始的最大容量
private static final int MAX_SIZE = 20;
/*
* 扩容因子 当达到最大容量*0.75时扩容一倍
*/
private static final float LOAD_FACTOR = 0.75f;
/*
* 链表节点
*/
class Entry {
private int key;
private int value;
private Entry next;
public Entry(int key, int value, Entry next) {
super();
this.key = key;
this.value = value;
this.next = next;
}
}
private Entry table[] = new Entry[MAX_SIZE];
private long size = 0;
private long use = 0;
private ArrayList<Integer> keyset = new ArrayList<Integer>();
/*
* 通过除留取余法计算key在表中的hash位置
*/
private int hash(int key) {
return key % this.table.length;
}
/*
* 将数据以key,value方式插入
*/
public void put(int key, int value) {
int index = hash(key);
// 首先判断数组在index位置是否已有数据
if (table[index] == null) {
table[index] = new Entry(-1, -1, null);
}
Entry e = table[index];
if (e.next == null) {
table[index].next = new Entry(key, value, null);
size++;
use++;
addKey(key);
// 扩容
if (use >= table.length * LOAD_FACTOR) {
resize();
}
} else {
for (e = e.next; e != null; e = e.next) {
int k = e.key;
if (k == key) {// 如果已经有该key则改变value值
e.value = value;
return;
}
}
Entry temp = table[index].next;
Entry newEntry = new Entry(key, value, temp);// 头插法
table[index].next = newEntry;
size++;
addKey(key);
}
}
/*
* 删除
*/
public void remove(int key) {
int index = hash(key);
Entry e = table[index];
Entry pre = table[index];
if (e != null && e.next != null) {
for (e = e.next; e != null; pre = e, e = e.next) {
int k = e.key;
if (k == key) {
removeSetKey(key);
pre.next = e.next;
size--;
return;
}
}
}
}
/*
* 通过key获取value
*
*/
public int get(int key) {
int index = hash(key);
Entry e = table[index];
if (e != null && e.next != null) {
for (e = e.next; e != null; e = e.next) {
int k = e.key;
if (key == k) {
return e.value;
}
}
}
return -1;
}
/*
* 获取元素个数
*/
public long size() {
return this.size;
}
/* 扩容 */
private void resize() {
int newlength = table.length * 2;
Entry[] oldTable = table;
table = new Entry[newlength];
use = 0;
for (int i = 0; i < oldTable.length; i++) {
if (oldTable[i] != null && oldTable[i].next != null) {
Entry e = oldTable[i];
while (null != e.next) {
Entry next = e.next;
int index = hash(next.key);
if (table[index] == null) {
use++;
table[index] = new Entry(-1, -1, null);
}
Entry temp = table[index].next;
Entry newEntry = new Entry(next.key, next.value, temp);// 头插法
table[index].next = newEntry;
e = next;
}
}
}
}
public ArrayList<Integer> Keyset() {
return keyset;
}
private void addKey(Integer key) {
this.keyset.add(key);
}
private void removeSetKey(Integer key) {
this.keyset.remove(key);
}
public static void main(String[] args) {
Main test = new Main();
test.put(1, 2);
test.put(3, 5);
test.put(2, 5);
test.put(9, 3);
for (int x : test.Keyset()) {
System.out.println(x);
}
System.out.println("===============================");
test.remove(3);
for (int x : test.Keyset()) {
System.out.println(x);
}
}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
class BinarySearchTree<E extends Comparable> {
private Node root;
public BinarySearchTree() {
}
public BinarySearchTree(E e) {
this.root = new Node(e, null, null, null);
}
public void add(E e) {
// 根节点为空
if (root == null) {
root = new Node(e, null, null, null);
} else {
Node current = root;
Node parent;
boolean lessThanLeft;
do {
parent = current;
lessThanLeft = e.compareTo(current.data) < 0 ? true : false;
// 如果新增节点小于当前节点,则以当前节点的左子节点作为当前节点继续搜索
if (lessThanLeft) {
current = parent.left;
} else {
// 如果新增节点不小于当前节点,则以当前节点的右子节点作为当前节点继续搜索
current = parent.right;
}
} while (current != null);
Node newNode = new Node(e, parent, null, null);
if (lessThanLeft) {
parent.left = newNode;
} else {
parent.right = newNode;
}
}
}
public void remove(E e) {
// 获取要删除的节点
Node delNode = getNode(e);
while (delNode != null) {
// 如果删除的节点为叶子节点,直接移除即可
if (delNode.left == null && delNode.right == null) {
if (delNode == root) {
root = null;
} else {
// 如果被删除节点是左子节点,移除其父节点的左子节点,否则移除父节点的右子节点
if (delNode == delNode.parent.left) {
delNode.parent.left = null;
} else {
delNode.parent.right = null;
}
delNode.parent = null;
}
delNode = null;
} else if (delNode.left != null && delNode.right == null) {
// 被删除节点只有左子节点
if (delNode == root) {
// 如果是根节点,让左子节点作为根节点
root = delNode.left;
root.parent = null;
delNode = null;
} else {
delNode.left.parent = delNode.parent;
delNode.parent.left = delNode.left;
delNode = null;
}
} else if (delNode.left == null && delNode.right != null) {
// 被删除节点只有右子节点
if (delNode == root) {
// 如果是根节点,让右子节点作为根节点
root = delNode.right;
root.parent = null;
delNode.right = null;
delNode = null;
} else {
delNode.right.parent = delNode.parent;
delNode.parent.right = delNode.right;
delNode = null;
}
} else {
// 被删除节点的左、右子节点都存在
// 找到被删除节点的左子树的最大节点,也就是左子树中最右边的节点,即该节点的前驱节点。
Node leftMaxNode = delNode.left;
while (leftMaxNode.right != null) {
leftMaxNode = leftMaxNode.right;
}
delNode.data = leftMaxNode.data;
delNode = leftMaxNode;
}
}
}
public Node getNode(E e) {
Node p = root;
int cmp;
while (p != null) {
cmp = e.compareTo(p.data);
if (cmp < 0) {
p = p.left;
} else if (cmp > 0) {
p = p.right;
} else {
return p;
}
}
return null;
}
// 以先中后序遍历的方式输出树的每个节点的值
public void print() {
List<Node> nodes = new ArrayList<Node>();
if (root != null) {
inorderTraversal(root, nodes);
}
System.out.println(nodes);
}
public void println() {
List<Node> nodes = new ArrayList<Node>();
if (root != null) {
preorderTraversal(root, nodes);
}
System.out.println(nodes);
List<Node> nodes1 = new ArrayList<Node>();
if (root != null) {
postorderTraversal(root, nodes1);
}
System.out.println(nodes1);
List<Node> nodes2 = new ArrayList<Node>();
if (root != null) {
levelorderTraversal(root, nodes2);
}
System.out.println(nodes2);
}
// 中序遍历
private List<Node> inorderTraversal(Node node, List<Node> nodes) {
if (node.left != null) {
inorderTraversal(node.left, nodes);
}
nodes.add(node);
if (node.right != null) {
inorderTraversal(node.right, nodes);
}
return nodes;
}
// 先序遍历
private List<Node> preorderTraversal(Node node, List<Node> nodes) {
nodes.add(node);
if (node.left != null) {
preorderTraversal(node.left, nodes);
}
if (node.right != null) {
preorderTraversal(node.right, nodes);
}
return nodes;
}
// 后序遍历
private List<Node> postorderTraversal(Node node, List<Node> nodes) {
if (node.left != null) {
postorderTraversal(node.left, nodes);
}
if (node.right != null) {
postorderTraversal(node.right, nodes);
}
nodes.add(node);
return nodes;
}
//层次遍历
private List<Node> levelorderTraversal(Node node, List<Node> nodes) {
Queue <Node> q =new LinkedList<Node>();
q.add(root);
while(!q.isEmpty()) {
Node now=q.peek();
nodes.add(now);
q.poll();
if(now.left!=null)
q.add(now.left);
if(now.right!=null)
q.add(now.right);
}
return nodes;
}
private static class Node {
private Object data;
private Node parent;
private Node left;
private Node right;
public Node(Object data) {
this.data = data;
}
public Node(Object data, Node parent, Node left, Node right) {
this.data = data;
this.parent = parent;
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (this.getClass() == obj.getClass()) {
Node target = (Node) obj;
return data.equals(target.data) && parent == target.parent && left == target.left
&& right == target.right;
}
return false;
}
@Override
public String toString() {
return data.toString();
}
}
}
public class Main {
public static void main(String[] args) {
BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>();
Integer[] integers = { 18, 5, 4, 66, 32, 78 };
for (Integer i : integers) {
tree.add(i);
}
tree.print();
tree.println();
for (Integer i : integers) {
tree.remove(i);
tree.print();
}
}
}
import java.util.ArrayList;
import java.util.List;
class RedBlackTree<T extends Comparable> {
private static final boolean RED = false;
private static final boolean BLACK = true;
private Node root;
public RedBlackTree() {
root = null;
}
public RedBlackTree(T t) {
this.root = new Node(t, null, null, null);
}
/**
* 增加一个数据
*/
public void add(T e) {
// 如果根节点为空设置为根节点,默认是黑色
if (root == null) {
this.root = new RedBlackTree.Node(e);
} else {
// 根节点不为空的情况
RedBlackTree.Node current = root;
RedBlackTree.Node parent = null;
int cmp = 0;
do {
// 二叉搜索树的查找方法,找到合适的节点
parent = current;
cmp = e.compareTo(current.data);
if (cmp > 0) {
current = current.right;
} else {
current = current.left;
}
} while (current != null);
RedBlackTree.Node newNode = new RedBlackTree.Node(e, parent, null, null);
if (cmp > 0) {
parent.right = newNode;
} else {
parent.left = newNode;
}
// 新增一个黑色节点,肯定违反了红黑树的黑高一致规则,重新调整树结构
fixAfterInsertion(newNode);
}
}
/**
* 插入后修复红黑树
*
* @param x
* 插入的节点
*/
private void fixAfterInsertion(Node x) {
// 调整考虑如下几种情况:
// 1. x肯定不是根节点了,根节点的话就不需要调整,也就走不到这一步了
// 2. x的父节点是根节点,那么只需要将x设置为红色就行了,不会违反红黑树的规则
// 3. 所以重点调整就不需要考虑1和2了
// 4. x的父节点和叔叔节点都是红色,这个时候,只需要将x叔、父节点设置为黑色,祖父节点设置为红色
// 然后,将祖父节点设置为x递归处理
// 5. x的叔叔节点是黑色,这时候就需要进行旋转处理了
// 新节点设置为红色
x.color = RED;
while (x != null && x != root && x.parent.color == RED) {
// x的父节点是x的祖父节点的左子节点
if (parentOf(x).isLeftChild()) {
// x 的叔叔节点是右子节点
Node uncle = rightOf(grandfatherOf(x));
if (colorOf(uncle) == RED) {
// 叔、父都是红色,按上面注释的情形4处理
setColor(parentOf(x), BLACK);
setColor(uncle, BLACK);
setColor(grandfatherOf(x), RED);
x = grandfatherOf(x);
} else {
// x是父节点的右子节点
if (x.isRightChild()) {
x = parentOf(x);
// x和x的父节点不在一样“直线路径”上,对x的父节点左旋一下弄成看起来是一条直线的路径
rotateLeft(x);
}
setColor(parentOf(x), BLACK);
setColor(grandfatherOf(x), RED);
rotateRight(grandfatherOf(x));
}
} else { // x的父节点是右结点
// x 的叔叔节点
Node uncle = leftOf(grandfatherOf(x));
if (colorOf(uncle) == RED) {
// 叔、父都是红色,按上面注释的情形4处理
setColor(parentOf(x), BLACK);
setColor(uncle, BLACK);
setColor(grandfatherOf(x), RED);
x = grandfatherOf(x);
} else {
// x是左节点
if (x == leftOf(parentOf(x))) {
x = parentOf(x);
// x和x的父节点不在一样“直线路径”上,对x的父节点右旋一下弄成看起来是一条直线的路径
rotateRight(x);
}
setColor(parentOf(x), BLACK);
setColor(grandfatherOf(x), RED);
rotateLeft(grandfatherOf(x));
}
}
}
// 根节点永远为黑
root.color = BLACK;
}
private void rotateLeft(Node p) {
if (p != null) {
Node r = p.right;
Node q = r.left;
p.right = q;
if (q != null) {
q.parent = p;
}
r.parent = p.parent;
if (p.parent == null) {
root = r;
} else if (p == p.parent.left) {
p.parent.left = r;
} else {
p.parent.right = r;
}
r.left = p;
p.parent = r;
}
}
private void rotateRight(Node p) {
if (p != null) {
Node l = p.left;
Node q = l.right;
p.left = q;
if (q != null) {
q.parent = p;
}
l.parent = p.parent;
if (p.parent == null) {
root = l;
} else if (p == p.parent.left) {
p.parent.left = l;
} else {
p.parent.right = l;
}
l.right = p;
p.parent = l;
}
}
private Node parentOf(Node p) {
return p == null ? null : p.parent;
}
private Node grandfatherOf(Node p) {
return parentOf(parentOf(p));
}
private Node leftOf(Node p) {
return p == null ? null : p.left;
}
private Node rightOf(Node p) {
return p == null ? null : p.right;
}
private boolean colorOf(Node p) {
return p != null ? p.color : BLACK;
}
private void setColor(Node p, boolean c) {
if (p != null) {
p.color = c;
}
}
public Node getNode(T e) {
Node p = root;
while (p != null) {
int cmp = e.compareTo(p.data);
if (cmp < 0) {
p = p.left;
} else if (cmp > 0) {
p = p.right;
} else {
return p;
}
}
return null;
}
/**
* 移除一个节点
*/
public void remove(T e) {
Node target = getNode(e);
if (target == null) {
return;
}
// 如果待移除节点的两个子节点都存在,那么找到它的前趋节点代替它
if (target.left != null && target.right != null) {
Node node = target.left;
while (node.right != null) {
node = node.right;
}
// 将前趋节点的数据覆盖待删除节点的数据
target.data = node.data;
// 针对代替节点进行操作
target = node;
}
Node relacement = target.left != null ? target.left : target.right;
// 如果target还有一个子节点,那这里需要调整下,但是如果target是从上面找到的原本待删除节点的前趋节点,
// 那么target至多有一个左子节点
if (relacement != null) {
relacement.parent = target.parent;
if (target.isRoot()) {
root = relacement;
} else if (target.isLeftChild()) {
target.parent.left = relacement;
} else {
target.parent.right = relacement;
}
// 删除target
target.left = target.right = target.parent = null;
if (colorOf(target) == BLACK) {
// 删除了一个黑色节点,需要修复红黑树来满足黑高一致的规则
fixAfterDeletion(relacement);
}
} else if (target.isRoot()) {
root = null;
} else {
// target没有非空子节点了
// 删除了一个黑色节点,需要修复红黑树来满足黑高一致的规则,红色就不用了
if (colorOf(target) == BLACK) {
fixAfterDeletion(target);
}
// 删除target
if (target.isLeftChild()) {
target.parent.left = null;
} else {
target.parent.right = null;
}
target.parent = null;
}
}
public void fixAfterDeletion(Node x) {
// 直到x是根节点或者x 的颜色是红色为止,否则一直处理
while (x != root && colorOf(x) == BLACK) {
if (x.isLeftChild()) {
// s是x的兄弟节点
Node sib = rightOf(parentOf(x));
if (colorOf(sib) == RED) {
// 因为x 路径上将要少一个黑色,所以这时候就需要从它的父母兄弟那里借一个过来帮个忙了
setColor(sib, BLACK);
// sib是红色,则它的父节点原本一定是黑色,否则就违反了红黑树不能两个连续红色节点的规则了
setColor(parentOf(sib), RED);
rotateLeft(parentOf(x));
sib = rightOf(parentOf(x));
}
// sib的两个子节点都是黑色
if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK) {
// 设置sib 是红色是因为,x的子树下将少一个黑色节点,那就让它的兄弟节点的子树下也先少一个黑色节点
setColor(sib, RED);
// 让x指向它的父节点,如果x的父节点是红色,那么结束循环,然后将其设置为黑色,丢失的那个黑色节点也就补回来了
// 如果不是红色,那就继续往下调整
x = parentOf(x);
} else {
// sib的子节点中只有一个是黑色
// 那就把这个红色子节点右旋放到右边子节点上,这是因为,x这边还少一个黑色节点呢,需要借一个黑色
// 最终sib 这边少一个黑色,将这个红色设置为黑色补上
if (colorOf(rightOf(sib)) == BLACK) {
setColor(leftOf(sib), BLACK);
setColor(sib, RED);
rotateRight(sib);
sib = rightOf(parentOf(x));
}
setColor(sib, colorOf(parentOf(x)));
setColor(parentOf(x), BLACK);
setColor(rightOf(x), BLACK);
rotateLeft(parentOf(x));
x = root;
}
} else {
// 如果x 是右子节点,就是上面的情况反过来
Node sib = leftOf(parentOf(x));
if (colorOf(sib) == RED) {
setColor(sib, BLACK);
setColor(parentOf(x), RED);
rotateRight(parentOf(x));
sib = leftOf(parentOf(x));
}
// sib的两个子节点都是黑色
if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK) {
// 设置sib 是红色是因为,x的子树下将少一个黑色节点,那就让它的兄弟节点的子树下也先少一个黑色节点
setColor(sib, RED);
// 让x指向它的父节点,如果x的父节点是红色,那么结束循环,然后将其设置为黑色,丢失的那个黑色节点也就补回来了
// 如果不是红色,那就继续往下调整
x = parentOf(x);
} else {
if (colorOf(leftOf(sib)) == BLACK) {
setColor(rightOf(sib), BLACK);
setColor(sib, RED);
rotateLeft(sib);
sib = leftOf(parentOf(x));
}
setColor(sib, colorOf(parentOf(x)));
setColor(parentOf(x), BLACK);
setColor(leftOf(x), BLACK);
rotateRight(parentOf(x));
x = root;
}
}
}
setColor(x, BLACK);
}
// 中序遍历
public List<Node> inIterator(Node node) {
List<Node> nodes = new ArrayList<Node>();
if (node.left != null) {
nodes.addAll(inIterator(node.left));
}
nodes.add(node);
if (node.right != null) {
nodes.addAll(inIterator(node.right));
}
return nodes;
}
public List<Node> inIterator() {
return root != null ? inIterator(root) : new ArrayList<Node>(0);
}
private static class Node {
Object data;
Node parent;
Node left;
Node right;
boolean color = BLACK;
public Node(Object data) {
this.data = data;
}
public Node(Object data, Node parent, Node left, Node right) {
this.data = data;
this.parent = parent;
this.left = left;
this.right = right;
}
public boolean isLeftChild() {
return this == this.parent.left;
}
public boolean isRightChild() {
return this == this.parent.right;
}
public boolean isRoot() {
return this.parent == null;
}
@Override
public String toString() {
return data.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj.getClass() == Node.class) {
Node target = (Node) obj;
return data.equals(target.data) && left == target.left && right == target.right
&& parent == target.parent && color == target.color;
}
return false;
}
}
}
public class Main {
public static void main(String[] args) {
RedBlackTree<Integer> tree = new RedBlackTree<Integer>();
// 遍历的结果就该是:1,6,8,11,13,15,17,22,25,27
Integer[] integers = { 6, 15, 25, 8, 17, 22, 11, 1, 13, 27 };
for (Integer i : integers) {
tree.add(i);
System.out.println(tree.inIterator());
}
for (Integer i : integers) {
tree.remove(i);
System.out.println(tree.inIterator());
}
}
}