0
点赞
收藏
分享

微信扫一扫

树论相关(Java)

i奇异 2022-06-28 阅读 58

本专栏目录

​​蓝桥杯算法竞赛大纲​​​​​​

​​数论相关(Java)​​

​​​枚举相关(Java)​​​​​​

​​对象排序(Java)​​​​​​

​​字符串相关(Java)​​​​​​

​​排序相关算法(Java)​​

​​​记忆化搜索(Java)​​

​​ 树论相关(Java)
​​​图论相关(Java)​​

​​​堆(Java)​​

​​​贪心(Java)​​


文章目录

  • ​​二叉搜索树​​
  • ​​二叉搜索树的结构AC1​​
  • ​​二叉搜索树的结构AC2​​
  • ​​前中后层序遍历​​
  • ​​是否完全二叉搜索树​​
  • ​​完全二叉树的层序遍历​​
  • ​​玩转二叉树​​
  • ​​线段树​​
  • ​​线段树LazyTag​​
  • ​​AVLTree​​
  • ​​ST表​​
  • ​​公共祖先问题​​
  • ​​构建BST的两种方式和构建AVL的一种方式​​

二叉搜索树

package 树论;

import java.util.Scanner;

public class _二叉搜索树 {

static int n;
static int[] arr;
static int c1=0,c2=0;
static boolean flag1=false,flag2=false;

public static void main(String[] args) {

// 给定一个整数键值序列,现请你编写程序,
// 判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果

Scanner scan = new Scanner(System.in);

n = scan.nextInt();
arr = new int[n];

Node root = null;

for (int i = 0; i < n; i++) {
int x = scan.nextInt();
arr[i] = x;
root = insert(root, x);
}

preOrder(root);

if (!flag1){
System.out.println("YES");
postOrder(root);
return;
}

preMirrOrder(root);

if (!flag2){
System.out.println("YES");
postMirrOrder(root);
return;
}

System.out.println("NO");
}

// 后序镜像遍历
static boolean f2 = false;
public static void postMirrOrder(Node root) {

if (root.r!=null) postMirrOrder(root.r);
if (root.l!=null) postMirrOrder(root.l);

if (!f2){
System.out.print(root.data);
f2 = true;
}else {
System.out.print(" " + root.data);
}

}

// 前序镜像遍历 + 验证
public static void preMirrOrder(Node root) {

if (flag2 || arr[c2++]!=root.data){
flag2 = true;
return;
}

if (root.r!=null) preMirrOrder(root.r);
if (root.l!=null) preMirrOrder(root.l);

}

// 后序遍历
static boolean f1 = false;
public static void postOrder(Node root) {

if (root.l!=null) postOrder(root.l);

if (root.r!=null) postOrder(root.r);

if (!f1){
System.out.print(root.data);
f1 = true;
}else {
System.out.print(" " + root.data);
}
}


// 前序遍历 + 验证
public static void preOrder(Node root) {

if (flag1 || arr[c1++]!=root.data){

flag1 = true;
return;
}

if (root.l!=null){
preOrder(root.l);
}

if (root.r!=null){
preOrder(root.r);
}
}


// 构建二叉搜索树(BST)
public static Node insert(Node root, int x) {

if (root == null){

root = new Node();
root.data = x;

return root;
}

if (x < root.data){

root.l = insert(root.l, x);

}else {

root.r = insert(root.r, x);
}

return root;
}

static class Node{
Node l,r;
int data;
}
}

二叉搜索树的结构AC1

package 树论;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class _二叉搜索树的结构AC1 {

static int n,m;
static Map<Integer, Integer> layers = new HashMap<>(); // 层数
static Map<Integer, Integer> par = new HashMap<>(); // 父节点
static Map<Integer, Integer> lor = new HashMap<>(); // 左0还是右1子树


public static void main(String[] args) {

Scanner scan = new Scanner(System.in);

n = scan.nextInt();

Node root = new Node();

for (int i = 0; i < n; i++) {
int x = scan.nextInt();
insert(root, x, 0);
}

m = scan.nextInt();
scan.nextLine();

for (int i = 0; i < m; i++) {

String line = scan.nextLine();
String[] strArr = line.split(" ");

if (line.contains("root")){
int x = Integer.parseInt(strArr[0]);
if (isExit(x) && x == root.data){
System.out.println("Yes");
}else {
System.out.println("No");
}
}else if (line.contains("siblings")){

int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[2]);

if (par.get(a)!=null&&par.get(b)!=null&&par.get(a)-par.get(b)==0){
System.out.println("Yes");
}else {
System.out.println("No");
}
}else if (line.contains("level")){

int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[2]);

if (isExit(a)&&isExit(b)&&layers.get(a)-layers.get(b)==0){
System.out.println("Yes");
}else {
System.out.println("No");
}

}else if (line.contains("parent")){
int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[5]);

if (isExit(a)&&par.get(b)!=null&&par.get(b)-a==0){
System.out.println("Yes");
}else {
System.out.println("No");
}
}else if (line.contains("left")){

int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[6]);

if (par.get(a)!=null&&isExit(b)&&par.get(a)-b==0&&lor.get(a)==0){
System.out.println("Yes");
}else {
System.out.println("No");
}

}else if (line.contains("right")){
int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[6]);

if (par.get(a)!=null&&isExit(b)&&par.get(a)-b==0&&lor.get(a)==1){
System.out.println("Yes");
}else {
System.out.println("No");
}
}
}
}

public static boolean isExit(int x){

if (layers.get(x)==null){
return false;
}

return true;
}

static boolean flag = false;
public static void insert(Node root, int x, int layer){

if (!flag){
flag = true;
root.data = x;
layers.put(root.data,1);
return;
}

if (x<root.data){

if (root.l==null){
root.l = new Node();
root.l.data = x;
par.put(x, root.data);
layers.put(x, layer);
lor.put(x, 0);
return;
}

insert(root.l, x, layer+1);

}else {

if (root.r==null){
root.r = new Node();
root.r.data = x;
par.put(x, root.data);
layers.put(x, layer);
lor.put(x, 1);
return;
}

insert(root.r, x, layer+1);
}
}

static class Node{
Node r,l;
int data=-1;
}
}

二叉搜索树的结构AC2

package 树论;

import java.util.Scanner;

public class _二叉搜索树的结构AC2 {

static int n,m;


public static void main(String[] args) {

Scanner scan = new Scanner(System.in);

n = scan.nextInt();

Node root = new Node();

for (int i = 0; i < n; i++) {
int x = scan.nextInt();
insert(root, x, 1);
}

m = scan.nextInt();
scan.nextLine();

for (int i = 0; i < m; i++) {

String line = scan.nextLine();
String[] strArr = line.split(" ");

if (line.contains("root")){
int x = Integer.parseInt(strArr[0]);

if (x == root.data){
System.out.println("Yes");
}else {
System.out.println("No");
}
}else if (line.contains("siblings")){

int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[2]);

Node na = find(root,a);
Node nb = find(root,b);

if (na!=null&&nb!=null&&na.parent!=null&&nb.parent!=null&&nb.parent==na.parent){
System.out.println("Yes");
}else {
System.out.println("No");
}
}else if (line.contains("level")){

int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[2]);

Node na = find(root,a);
Node nb = find(root,b);

if (na!=null&&nb!=null&&na.depth==nb.depth){
System.out.println("Yes");
}else {
System.out.println("No");
}

}else if (line.contains("parent")){
int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[5]);

Node na = find(root,a);
Node nb = find(root,b);

if (na!=null&&nb!=null&&nb.parent==na){
System.out.println("Yes");
}else {
System.out.println("No");
}
}else if (line.contains("left")){

int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[6]);

Node na = find(root,a);
Node nb = find(root,b);

if (na!=null&&nb!=null&&nb.l==na){
System.out.println("Yes");
}else {
System.out.println("No");
}

}else if (line.contains("right")){
int a = Integer.parseInt(strArr[0]);
int b = Integer.parseInt(strArr[6]);

Node na = find(root,a);
Node nb = find(root,b);

if (na!=null&&nb!=null&&nb.r==na){
System.out.println("Yes");
}else {
System.out.println("No");
}
}
}
}

public static Node find(Node root, int x){

if (root==null) return null;

if (x == root.data) return root;

if (x < root.data){
return find(root.l,x);
}else {
return find(root.r, x);
}
}

static boolean flag = false;
public static void insert(Node root, int x, int layer){

if (!flag){
flag = true;
root.data = x;
root.depth = 0;
root.parent = null;
return;
}

if (x<root.data){

if (root.l==null){
root.l = new Node();
root.l.data = x;
root.l.parent = root;
root.l.depth = layer;
return;
}

insert(root.l, x, layer+1);

}else {

if (root.r==null){
root.r = new Node();
root.r.data = x;
root.r.parent = root;
root.r.depth = layer;
return;
}

insert(root.r, x, layer+1);
}
}

static class Node{
Node r,l,parent;
int data,depth;
}
}

前中后层序遍历

package 树论;

import java.util.Scanner;

public class _前中后层序遍历 {

static int n;
static int[] postArr;
static int[] midArr;

public static void main(String[] args) {

// 给定一棵二叉树的后序遍历和中序遍历,输出其层序遍历的序列
Scanner scan = new Scanner(System.in);

n = scan.nextInt();
postArr = new int[n+1];
midArr = new int[n+1];

for (int i = 1; i <= n; i++) {
postArr[i] = scan.nextInt();
}

for (int i = 1; i <= n; i++) {
midArr[i] = scan.nextInt();
}

Node root = buildTree(1,n,1,n);

levelOrder(root);

}

// 树的层序遍历
private static void levelOrder(Node root) {

Node[] Q = new Node[n];

int front = -1;
int rear = -1;

Q[++rear] = root;

while (front!=rear){

Node node = Q[++front];

if (node==root) System.out.print(node.data);
else System.out.print(" " + node.data);

if (node.l != null) Q[++rear] = node.l;
if (node.r != null) Q[++rear] = node.r;

}
}

public static Node buildTree(int m1, int e1, int m2, int e2){

if (m1 > e1 || m2 > e2){
return null;
}

// 后序遍历的最后一个元素是根
int x = postArr[e1];

Node root = new Node();
root.data = x;

// 在中序遍历中查找root
for (int i = m2; i <= e2; i++) {
if (midArr[i]==x){
//左子树长度
int k = i - m2;

root.l = buildTree(m1,m1+k-1,m2,i-1);
root.r = buildTree(m1+k,e1-1,i+1,e2);

break;
}
}

return root;
}

static class Node{
Node r,l;
int data;
}
}

是否完全二叉搜索树

package 树论;

import java.util.Scanner;

public class _是否完全二叉搜索树 {

static int n;
static int max = 0;

public static void main(String[] args) {

// 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),
// 你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。

Scanner scan = new Scanner(System.in);

n = scan.nextInt();

Node root = null;

for (int i = 0; i < n; i++) {
int x = scan.nextInt();
root = insert(root, x);
}

levelOrder(root);
System.out.println();

dfs(root, 1);

if (max == n) System.out.println("YES");
else System.out.println("NO");
}

public static void dfs(Node root, int v){

if (v>max) max = v;

if (root.l!=null) dfs(root.l, v*2);
if (root.r!=null) dfs(root.r, v*2+1);

}

public static void levelOrder(Node root) {

Node[] Q = new Node[n];
int front = -1;
int rear = -1;

Q[++rear] = root;

boolean flag = true;

while (front!=rear){

Node node = Q[++front];
if (flag){

System.out.print(node.data);
flag = false;
}else {
System.out.print(" " + node.data);
}

if (node.l!=null) Q[++rear] = node.l;
if (node.r!=null) Q[++rear] = node.r;
}

}

public static Node insert(Node root, int x) {

if (root == null){

root = new Node();
root.data = x;

return root;
}

if (x > root.data){

root.l = insert(root.l, x);

}else {

root.r = insert(root.r, x);
}

return root;
}

static class Node{
Node r,l;
int data;
}
}

完全二叉树的层序遍历

package 树论;

import java.util.Scanner;

public class _完全二叉树的层序遍历 {

static int n;
static int[] arr;
static int[] brr;
static int c = 1;

public static void main(String[] args) {

// 给定一棵完全二叉树的后序遍历,请你给出这棵树的层序遍历结果。

Scanner scan = new Scanner(System.in);

n = scan.nextInt();

arr = new int[n+1];
brr = new int[n+1];

for (int i = 1; i <= n; i++) {
arr[i] = scan.nextInt();
}

postOrder(1);

System.out.print(brr[1]);
for (int i = 2; i <= n; i++) {
System.out.print(" " + brr[i]);
}
}

public static void postOrder(int v) {
if (v>n){
return;
}

postOrder(v*2);
postOrder(v*2 + 1);

brr[v] = arr[c++];
}
}

玩转二叉树

package 树论;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class _玩转二叉树 {

static int[] midArr;
static int[] preArr;
static int n;
static boolean flag = false;

static class Node{
Node l;
Node r;
int data;
}

public static void main(String[] args) {

// 给定一棵二叉树的中序遍历和前序遍历,
// 请你先将树做个镜面反转,再输出反转后的层序遍历的序列。

Scanner scan = new Scanner(System.in);

n = scan.nextInt();

midArr = new int[n+1];
preArr = new int[n+1];

for (int i = 1; i <= n; i++) {
midArr[i] = scan.nextInt();
}

for (int i = 1; i <= n; i++) {
preArr[i] = scan.nextInt();
}


Node root = fn(1,n,1,n);

levelOrder(root);
}

private static void levelOrder(Node root) {

List<Node> ls = new ArrayList<>();
ls.add(root);

while (!ls.isEmpty()){
Node node = ls.remove(0);
if (!flag){
flag = true;
System.out.print(node.data);
}else {
System.out.print(" " + node.data);
}

if (node.l!=null) ls.add(node.l);
if (node.r!=null) ls.add(node.r);
}

}

private static Node fn(int preS, int preE, int midS, int midE) {

if (preS>preE || midS>midE){
return null;
}

int x = preArr[preS];
Node root = new Node();
root.data = x;

for (int i = midS; i <= midE; i++) {

if (midArr[i]==x){
int k = i - midS; // 左子树长度
// 镜像构造
root.r = fn(preS+1,preS+k, midS, i-1);
root.l = fn(preS+k+1,preE, i+1, midE);
}
}

return root;
}
}

线段树

树论相关(Java)_i++
树论相关(Java)_i++_02
树论相关(Java)_java_03
树论相关(Java)_avl_04
树论相关(Java)_i++_05
树论相关(Java)_树_06
树论相关(Java)_二叉树_07
树论相关(Java)_二叉树_08

package 树论;

public class _线段树 {

static int[] arr = {1, 3, 5, 7, 9, 11};
static int[] tree = new int[1000005];
static int n = 6;

public static void main(String[] args) {

buildTree(0, 0, n-1);

for (int i = 0; i <= 14; i++) {
System.out.print(tree[i] + " ");
}

System.out.println();

updateTree(0, 0, n-1, 4, 6);

for (int i = 0; i <= 14; i++) {
System.out.print(tree[i] + " ");
}

System.out.println();

// 查找原数组中索引为[2, 5] 区间的和
int sum = queryTree(0, 0, n-1, 2, 5);

System.out.println(sum);
}

/**
* 区间查询合
* @param node tree中的下标
* @param start arr数组中的下标
* @param end
* @param L 带查询的区间是[L, R]
* @param R
* @return
*/
private static int queryTree(int node, int start, int end, int L, int R) {

if (end < L || start > R){ // 如果[L, R] 和 [start, end] 没有交集
return 0;
}else if (L<=start && R >= end){ // 如果 [L, R] 区间包含 [start, end]
return tree[node];
}else if (start==end){ // 如果查找单点则直接返回值
return tree[node];
}

int mid = (start + end) / 2;

int left_node = node * 2 + 1;
int right_node = node * 2 + 2;

int sum_left = queryTree(left_node, start, mid, L, R);
int sum_right = queryTree(right_node, mid+1, end, L, R);

return sum_left + sum_right;
}

// 单点更新 arr[idx] = val
public static void updateTree(int node, int start, int end, int idx, int val){

if (start==end){
// 当查找到单点时,更新
tree[node] = val;
arr[idx] = val;

return;
}

int mid = (start + end) / 2;

int left_node = node * 2 + 1;
int right_node = left_node + 1;

if (idx <= mid){ // 如果idx在arr的左边,则在tree的左子树查找更新

updateTree(left_node, start, mid, idx, val);
}else {

updateTree(right_node, mid+1, end, idx, val);
}

// 更新父节点
tree[node] = tree[left_node] + tree[right_node];
}

/**
*
* @param node tree中的下标
* @param start arr中的下标 表示区间 [start, end]
* @param end
*/
public static void buildTree(int node, int start, int end){

if (start==end){

tree[node] = arr[start];
return;
}

int mid = (start + end) / 2;

// tree中子树下标
int left_node = 2 * node + 1;
int right_node = left_node + 1;

// 分别建左右子树
buildTree(left_node, start, mid);
buildTree(right_node, mid+1, end);

tree[node] = tree[left_node] + tree[right_node];
}
}

线段树LazyTag

package 树论;

import java.util.Scanner;

// http://poj.org/problem?id=3468

public class _线段树LazyTag {

static long[] tree;
static long[] tags;
static long[] nums;
static int n, m;

public static void main(String[] args) {

Scanner scan = new Scanner(System.in);

n = scan.nextInt();
m = scan.nextInt();

nums = new long[n+1];
tree = new long[4*n+1];
tags = new long[4*n+1];

for (int i = 1; i <= n; i++) {
nums[i] = scan.nextInt();
}

buildTree(0, 1, n);

for (int i = 0; i < m; i++) {
String s = scan.next();

if (s.equals("Q")){

int L = scan.nextInt();
int R = scan.nextInt();

long sum = query(0, 1, n, L, R);
System.out.println(sum);

}else {
int L = scan.nextInt();
int R = scan.nextInt();
int val = scan.nextInt();
updateTree(0, 1, n, L, R, val);
}
}
}

public static void buildTree(int node, int start, int end){

if (start==end){

tree[node] = nums[start];
return;
}

int mid = (start + end) / 2;
int left_node = node * 2 + 1;
int right_node = node * 2 + 2;

buildTree(left_node, start, mid);
buildTree(right_node, mid+1, end);

pushUP(node);
}

public static long query(int node, int start, int end, int L, int R) {


if (L<=start && end <= R){
return tree[node];
}else if (L>end || R < start){
return 0;
}else if (start==end){
return tree[node];
}

// 下放后才能查询
if (tags[node]!=0){
pushDown(node, start, end);
}

int mid = (start + end) / 2;
int left_node = 2 * node + 1;
int right_node = 2 * node + 2;

long sum_left = query(left_node, start, mid, L, R);
long sum_right = query(right_node, mid+1, end, L, R);

return sum_left + sum_right;
}

public static void updateTree(int node, int start, int end, int L, int R, int val) {

if (L <= start && end <= R){
// 如果[start,end] 在待查询的区间 [L, R] 内, 则进行LazyTag标记后返回
tree[node] += (end - start + 1) * val;
tags[node] += val;
return;
}

// 更新前如果当前节点有LazyTag标记,则先下放
if (tags[node]!=0){
pushDown(node, start, end);
}

int mid = (start + end) / 2;
int left_node = node * 2 + 1;
int right_node = node * 2 + 2;

// [L, R] 和 [start, mid] 有交集, 则去左边更新
if (L <= mid){

updateTree(left_node, start, mid, L, R, val);
}

// [L, R] 和 [mid + 1, end] 有交集, 则去右边更新
if (mid + 1 <=R){

updateTree(right_node, mid+1, end, L, R, val);
}

// 更新节点的值
pushUP(node);
}

// 根据父节点的LazyTag标记,更新子节点的值,并且给子节点打标记
public static void pushDown(int idx, int start, int end){

long val = tags[idx];
int mid = (start + end) / 2;
int left_node = idx * 2 + 1;
int right_node = idx * 2 + 2;

tree[left_node] += (mid - start + 1) * val;
tree[right_node] += (end - (mid + 1) + 1) * val;

tags[left_node] += val;
tags[right_node] += val;

tags[idx] = 0;
}

// 根据子节点的值更新父节点的值
public static void pushUP(int idx){
tree[idx] = tree[idx*2+1] + tree[idx*2+2];
}
}

AVLTree

package 树论;

import java.util.Scanner;

public class _AVLTree {

static class Node{
int data;
Node left,right;
}

static int n;

public static void main(String[] args) {

Scanner scan = new Scanner(System.in);

n = scan.nextInt();

Node root = null;

for (int i = 0; i < n; i++) {

int x = scan.nextInt();
root = insert(root, x);

}

levelOrder(root);

}

public static void levelOrder(Node root){

Node[] Q = new Node[n];

int rear = -1;
int front = -1;

Q[++rear] = root;

while (rear!=front){

Node node = Q[++front];

System.out.print(node.data + " ");

if (node.left!=null) {
Q[++rear] = node.left;
}
if (node.right!=null) {
Q[++rear] = node.right;
}

}

}

public static Node rotateRightLeft(Node root){

root.right = rotateRight(root.right);
root = rotateLeft(root);

return root;
}

public static Node rotateLeftRight(Node root){

root.left = rotateLeft(root.left);
root = rotateRight(root);

return root;
}

public static Node rotateLeft(Node root){ // 左旋

Node right = root.right;
root.right = right.left;
right.left = root;

return right;
}


public static Node rotateRight(Node root){ // 右旋

Node left = root.left;
root.left = left.right;
left.right = root;

return left;
}


public static int getHeight(Node root){

if (root==null) return 0;

return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
}

// 构建AVL
public static Node insert(Node root, int x){

if (root == null){

root = new Node();
root.data = x;

return root;
}

if (x < root.data){

root.left = insert(root.left, x);

if (getHeight(root.left)-getHeight(root.right)>=2){

// 如果高度差是因为x插入了左子树的右子树造成的,则左右旋
if (x > root.left.data){
root = rotateLeftRight(root);
}else { // 否则只右旋
root = rotateRight(root);
}
}

}else {

root.right = insert(root.right, x);

if (getHeight(root.right)-getHeight(root.left)>=2){

// 如果高度差是因为x插入了右子树的左子树造成的,则右左旋
if (x<root.right.data){
root = rotateRightLeft(root);
}else { // 否则只左旋
root = rotateLeft(root);
}
}
}

return root;
}
}

ST表

树论相关(Java)_二叉树_09

树论相关(Java)_i++_10
树论相关(Java)_i++_11

package 树论;

import java.util.Scanner;

public class _ST表 {

static int n,m;
static int[][] dp; // dp[i][j] 表示区间 [i, i+2^j-1], 即下标从i开始,长度为2^j的区间

public static void main(String[] args) {

Scanner scan = new Scanner(System.in);

n = scan.nextInt();
m = scan.nextInt();

dp = new int[n][(int)Math.log(n)+5];

// 预处理
for (int i = 0; i < n; i++) {
dp[i][0] = scan.nextInt();
}

for (int j = 1; j <= Math.log(n); j++) {
for (int i = 0; i + (1 << j) - 1 < n; i++) {
// 长度一半的两个相邻区间的最大/最小值
dp[i][j] = Math.min(dp[i][j-1], dp[i + (1 << (j - 1))][j-1]);
}
}


int l, r;
for (int i = 0; i < m; i++) {
l = scan.nextInt();
r = scan.nextInt();

if (i==m-1){
System.out.print(query(l-1, r-1));
}else {

System.out.print(query(l-1, r-1) + " ");
}
}
}

public static int query(int l, int r) {

// 待求的区间长度
int len = r - l + 1;

int j = (int)Math.log(len);

// max/min([l, l+2^j-1], [r-2^j+1, r])
return Math.min(dp[l][j], dp[r - (1 << j) + 1][j]);
}
}

公共祖先问题

static class Node{
Node r,l,parent;
int data,depth;
}

增加一个parent字段,然后查找到后反搜标记,最后看是否有重复标记的

并查集有可能也可以解决

构建BST的两种方式和构建AVL的一种方式

BST

(一) 一般用于公共父节点问题

static boolean flag = false;
public static void insert(Node root, int x, int layer){

if (!flag){
flag = true;
root.data = x;
root.depth = 0;
root.parent = null;
return;
}

if (x<root.data){

if (root.l==null){
root.l = new Node();
root.l.data = x;
root.l.parent = root;
root.l.depth = layer;
return;
}

insert(root.l, x, layer+1);

}else {

if (root.r==null){
root.r = new Node();
root.r.data = x;
root.r.parent = root;
root.r.depth = layer;
return;
}

insert(root.r, x, layer+1);
}
}

(二)

public static Node insert(Node root, int x) {

if (root == null){

root = new Node();
root.data = x;

return root;
}

if (x < root.data){

root.l = insert(root.l, x);

}else {

root.r = insert(root.r, x);
}

return root;
}



AVL

// 构建AVL
public static Node insert(Node root, int x){

if (root == null){

root = new Node();
root.data = x;

return root;
}

if (x < root.data){

root.left = insert(root.left, x);

if (getHeight(root.left)-getHeight(root.right)>=2){

// 如果高度差是因为x插入了左子树的右子树造成的,则左右旋
if (x > root.left.data){
root = rotateLeftRight(root);
}else { // 否则只右旋
root = rotateRight(root);
}
}

}else {

root.right = insert(root.right, x);

if (getHeight(root.right)-getHeight(root.left)>=2){

// 如果高度差是因为x插入了右子树的左子树造成的,则右左旋
if (x<root.right.data){
root = rotateRightLeft(root);
}else { // 否则只左旋
root = rotateLeft(root);
}
}
}

return root;
}


举报

相关推荐

0 条评论