check if tree if complete binary search tree - algorithm

I'am learning about trees. I just completed problem to check if tree is complete BST or not. I'd like to know if i did it right.
Basically i just have to look for a node which has only one child, for the whole tree.
EDIT: I had definition of both complete and full binary search tree wrong as Mooing Duck pointed out. I finished coding it now, is this the solution?
int heightBST(Node* root)
{
if (root == NULL)
{
return -1;
}
int lHeight = heightBST(root->left);
int rHeight = heightBST(root->right);
return lHeight > rHeight ? 1 + lHeight : 1 + rHeight;
}
int isFullBST(Node* root)
{
if (root == NULL)
{
return 1;
}
int lHeight = heightBST(root->left);
int rHeight = heightBST(root->right);
if (lHeight != rHeight)
{
return -1;
}
if ((root->left == NULL && root->right != NULL) || (root->left != NULL && root->right == NULL))
{
return 0;
}
if (isCompleteBST(root->left) == 0 || isCompleteBST(root->right) == 0)
{
return 0;
}
return 1;
}
int isCompleteBST(Node* root)
{
if (root == NULL)
{
return 1;
}
int lHeight = heightBST(root->left);
int rHeight = heightBST(root->right);
if (lHeight - rHeight != 0 || lHeight - rHeight != 1)
{
return 0;
}
if ((root->left == NULL && root->right != NULL) || (root->left != NULL && root->right == NULL))
{
return 0;
}
if (isCompleteST(root->left) == 0 || isCompleteBST(root->right) == 0)
{
return 0;
}
return 1;
}

Related

minmax algorithm with tictactoe, wrong decision

I have this code written in Dart that implements the minmax algorithm, With a tic-tac-toe, the computer is playing as "O" and trying to maximize the score, but I get some wrong decision like this, it says (look at the top, the first is the move coordinate and the second is the score) that I have to move in (0,2). But this is not the right decision.
This is my code:
class Ai {
play(state) {
return max_Value(state);
}
// the action parameter holds the move that got as to this state
List max_Value(List state, {action}) {
List v = [null, double.negativeInfinity];
if (terminal(state)) {
return [action, utility(state)];
}
for (var action in actions(state)) {
if (v[1] == 1) return v;
v = max(v, min_Value(result(state, action), action: action));
}
return v;
}
List min_Value(List state, {action}) {
List v = [null, double.infinity];
if (terminal(state)) {
return [action, utility(state)];
}
for (var action in actions(state)) {
if (v[1] == -1) return v;
v = min(v, max_Value(result(state, action), action: action));
}
return v;
}
List min(List prv, List curr) {
return prv[1] < curr[1] ? prv : curr;
}
List max(List prv, List curr) {
return prv[1] > curr[1] ? prv : curr;
}
bool terminal(List state) {
if (state[0][0] == state[0][1] &&
state[0][0] == state[0][2] &&
state[0][0] != "") {
return true;
}
if (state[1][0] == state[1][1] &&
state[1][0] == state[1][2] &&
state[1][0] != "") {
return true;
}
if (state[2][0] == state[2][1] &&
state[2][0] == state[2][2] &&
state[2][0] != "") {
return true;
}
// vertical
if (state[0][0] == state[1][0] &&
state[0][0] == state[2][0] &&
state[0][0] != "") {
return true;
}
if (state[0][1] == state[1][1] &&
state[0][1] == state[2][1] &&
state[0][1] != "") {
return true;
}
if (state[0][2] == state[1][2] &&
state[0][2] == state[2][2] &&
state[0][2] != "") {
return true;
}
// diagonal
if (state[0][0] == state[1][1] &&
state[2][2] == state[0][0] &&
state[0][0] != "") {
return true;
}
if (state[2][0] == state[1][1] &&
state[2][0] == state[0][2] &&
state[2][0] != "") {
return true;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "") {
return false;
}
}
}
return true;
}
double utility(List state) {
String winner = "";
// horizontal
if (state[0][0] == state[0][1] && state[0][0] == state[0][2]) {
winner = state[0][0];
}
if (state[1][0] == state[1][1] && state[1][0] == state[1][2]) {
winner = state[1][0];
}
if (state[2][0] == state[2][1] && state[2][0] == state[2][2]) {
winner = state[2][0];
}
// vertical
if (state[0][0] == state[1][0] && state[0][0] == state[2][0]) {
winner = state[0][0];
}
if (state[0][1] == state[1][1] && state[0][1] == state[2][1]) {
winner = state[0][1];
}
if (state[0][2] == state[1][2] && state[0][2] == state[2][2]) {
winner = state[0][2];
}
// diagonal
if (state[0][0] == state[1][1] && state[2][2] == state[0][0]) {
winner = state[0][0];
}
if (state[2][0] == state[1][1] && state[2][0] == state[0][2]) {
winner = state[2][0];
}
if (winner == "O") {
return 1;
} else if (winner == "X") {
return -1;
} else {
return 0;
}
}
List actions(List state) {
List acs = [];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "") {
acs.add([i, j]);
}
}
}
return acs;
}
List result(List state, List action) {
List newState = [
["", "", ""],
["", "", ""],
["", "", ""]
];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
newState[i][j] = state[i][j];
}
}
newState[action[0]][action[1]] = player(state);
return newState;
}
player(List state) {
int xnum = 0;
int onum = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "X") {
xnum++;
} else if (state[i][j] == "O") {
onum++;
}
}
}
if (xnum > onum) {
return "O";
} else {
return "X";
}
}
}
Some mistakes:
This needs to depend on the player to move whether you return max or min:
play(state) {
return max_Value(state);
}
Here (and same for min) v might become an action done later and not the actual action that was performed and lead to the better value.
v = max(v, min_Value(result(state, action), action: action));
Possible improvements:
With a little modification terminal could return the evaluation too and then you don't need the utility function.
You constantly evaluate player with the function. You should have to do that at most once (see first mistake). min and max know whether they are playing X or O. Everything could be simplified a lot and the number of functions reduced without increasing their complexity.

Looking for correct recursive algorithm for Leetcode 112

I am working on Leet Code problem 112. Path Sum:
Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum.
A leaf is a node with no children.
I the code below trying to solve it, but apparently it isn't correct as I keep running into failed test cases.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root.left==null&&root.right==null&&targetSum-root.val ==0)
return true;
else{
if(root.right!= null){
hasPathSum(root.right, targetSum-root.val);
}
if(root.left!=null) {
hasPathSum(root.left, targetSum-root.val);
}
} return false;
}
}
What is wrong with this code?
You are not using the values returned by the recursive calls you make. In a verbose way, you could fix that part of your code as follows:
boolean result = false;
if (root.right != null) {
result = hasPathSum(root.right, targetSum - root.val);
}
if (!result && root.left != null) {
result = hasPathSum(root.left, targetSum - root.val);
}
return result;
It is more compact when you use more logical operators for that:
return root.right != null && hasPathSum(root.right, targetSum - root.val)
|| root.left != null && hasPathSum(root.left, targetSum - root.val);
It is not stated explicitly in the Leet Code challenge, but when calling this function on an empty tree, it should return false. So you should foresee the case where root is null.
The complete solution could look like this:
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
return root != null &&
( root.left == null && root.right == null && targetSum == root.val
|| root.right != null && hasPathSum(root.right, targetSum - root.val)
|| root.left != null && hasPathSum(root.left, targetSum - root.val)
);
}
}
Here is my recursive solution in javascript:
var hasPathSum = function(root, targetSum) {
if (root) {
if (!root.left && !root.right) {
return root.val === targetSum;
}
if (root.left) {
const isTherePath = hasPathSum(root.left, targetSum - root.val);
if (isTherePath) return true;
}
if (root.right) {
const isTherePath = hasPathSum(root.right, targetSum - root.val);
if (isTherePath) return true;
}
}
return false;
};

Red-Black Tree Deletion Partially Working

I implemented a red black tree in c++ with find, insert and delete. The delete only works for right side nodes and for the root node. I can't figure out why it isn't working for any of the left side nodes. Here is my code:
Node* searchNode(Node* root, int value){
Node* temp = root;
while (temp != NULL){
if (temp->val == value){
return temp;
}
else if (temp->val < value){
temp = temp->right;
}
else if (temp->val > value){
temp = temp->left;
}
}
}
Node* sibling(Node* node){
if ((node == NULL) || (node->parent == NULL)){
return NULL;
}
if (node == node->parent->left){
return node->parent->right;
}
else{
return node->parent->left;
}
}
Node* maxNode(Node* node){
while (node->right != NULL){
node = node->left;
}
return node;
}
void replaceNode(Node* old, Node* new_node){
if (old->parent == NULL){
old = new_node;
}
else{
if (old == old->parent->left){
old->parent->left = new_node;
}
else{
old->parent->right = new_node;
}
}
if (new_node != NULL){
new_node->parent = old->parent;
}
}
void deleteNode(Node* root, int value){
Node* child;
Node* temp = searchNode(root, value);
if (temp == NULL){
return;
}
if (temp->left != NULL&&temp->right != NULL){
Node* pred = maxNode(temp->right);
temp->val = pred->val;
temp = pred;
}
if (temp->left == NULL || temp->right == NULL){
if (temp->right == NULL && temp->left == NULL){
child = temp;
}
else if (temp->right == NULL){
child = temp->left;
}
else{
child = temp->right;
}
}
if (temp->color == 1){
temp->color = child->color;
delete_case1(root, child);
}
replaceNode(temp, child);
delete temp;
}
void delete_case6(Node* root, Node* n)
{
Node *s = sibling(n);
s->color = n->parent->color;
n->parent->color = 1;
if (n == n->parent->left) {
s->right->color = 1;
rotate_left(root, n->parent);
}
else {
s->left->color = 1;
rotate_right(root, n->parent);
}
}
void delete_case5(Node* root, Node* n)
{
Node *s = sibling(n);
if (s->color == 1) {
if ((n == n->parent->left) &&(s->right->color == 1) &&(s->left->color == 0)) {
s->color = 0;
s->left->color = 1;
rotate_right(root, s);
}else if ((n == n->parent->right) &&(s->left->color == 1) &&(s->right->color == 0)) {
s->color = 0;
s->right->color = 1;
rotate_left(root, s);
}
}
delete_case6(root, n);
}
void delete_case4(Node* root, Node* n)
{
Node *s = sibling(n);
if ((n->parent->color == 0) && (s->color == 1) && (s->left->color == 1) && (s->right->color == 1)) {
s->color = 0;
n->parent->color = 1;
}
else{
delete_case5(root, n);
}
}
void delete_case3(Node* root, Node* n){
Node* s = sibling(n);
if ((n->parent->color == 1) &&(s->color == 1) &&(s->left->color == 1) &&(s->right->color == 1)) {
s->color = 0;
delete_case1(root, n->parent);
}
else
delete_case4(root, n);
}
void delete_case2(Node* root, Node* n){
Node *s = sibling(n);
if (s->color == 0){
n->parent->color = 0;
s->color = 1;
if (n == n->parent->left){
rotate_left(root, n->parent);
}
else if (n == n->parent->right){
rotate_right(root, n->parent);
}
}
delete_case3(root, n);
}
void delete_case1(Node* root,Node* n){
if (n->parent != NULL){
delete_case2(root,n);
}
}
void main(){
ABTree* ABtree=new ABTree;
ABtree->root = NULL;
insertTree(ABtree->root, 15);
insertTree(ABtree->root, 8);
insertTree(ABtree->root, 2);
insertTree(ABtree->root, 9);
insertTree(ABtree->root, 10);
insertTree(ABtree->root, 12);
insertTree(ABtree->root, 18);
insertTree(ABtree->root, 25);
insertTree(ABtree->root, 20);
printTree(ABtree->root);
Node* search=searchNode(ABtree->root, 18);
cout << endl;
cout << search->val<<endl;
deleteNode(ABtree->root, 8);
printTree(ABtree->root);
}
For example if i want to delete either 8/9/2 the program crashes at delete_case4 at the if statement.
Thanks in advance!

Find Ancestor method for binary search tree is not working

I had written the method for finding a node's parent in C# (c-sharp) but my code is not working correctly. Exceptions: System.NullReferenceException is thrown when I try to delete a node who's parent is null.
public TreeNode FindParent(int value, ref TreeNode parent)
{
TreeNode currentNode = root;
if (currentNode == null)
{
return null;
}
while (currentNode.value != value)
{
if (value < currentNode.value)
{
parent = currentNode;
currentNode = currentNode.leftChild;
}
if (value > currentNode.value)
{
parent = currentNode;
currentNode = currentNode.rightChild;
}
}
return currentNode;
}
public void Delete(int value)
{
TreeNode parent = null;
TreeNode nodeToDelete = FindParent(value, ref parent);
if (nodeToDelete == null)
{
throw new Exception("Unable to delete node: " + value.ToString());
}
//CASE 1: Nod has 0 children.
if (nodeToDelete.leftChild == null && nodeToDelete.rightChild == null)
{
if (parent.leftChild == nodeToDelete)
{
parent.leftChild = null;
}
if (parent.rightChild == nodeToDelete)
{
parent.rightChild = null;
}
count--;
return;
}
//CASE 2: Nod has 1 left || 1 right barn
if (nodeToDelete.leftChild == null && nodeToDelete.rightChild != null)
{
nodeToDelete.rightChild = parent.rightChild;
nodeToDelete = null;
count--;
return;
}
if (nodeToDelete.leftChild != null && nodeToDelete.rightChild == null)
{
nodeToDelete.leftChild = parent.leftChild;
nodeToDelete = null;
count--;
return;
}
//CASE 3: Nod has 2 children
if (nodeToDelete.rightChild != null && nodeToDelete.leftChild != null)
{
TreeNode successor = LeftMostNodeOnRight(nodeToDelete, ref parent);
TreeNode temp = new TreeNode(successor.value);
if (parent.leftChild == successor)
{
parent.leftChild = successor.rightChild;
}
else
{
parent.rightChild = successor.rightChild; nodeToDelete.value = temp.value;
}
count--;
return;
}
}
since you are using recursion , you don't need the parent Node to delete a node in a binary search tree, here is a delete method where you pass in int and the root
private BinaryTreeNode remove (int value, TreeNode t){
if(t==null)
return t; // not found; do nothing
if(value < t.value){
t.left = remove(x,y,t.left);
}
else if (value > t.value){
t.right = remove(x,y,t.right);
}
else if( t.left!=null && t.right != null) // two children
{
t.info = findMin(t.right).info;
remove(t.info.getLastName(),y,t.right);
}
else{ // one child
if (t.left != null) {
t = t.left;
}
else{
t = t.right;
}
}
return t;
}
Edit-----------findMin (find minimum node in a binary search tree)
private BinaryTreeNode findMin ( BinaryTreeNode t){ // recursive
if(t == null)
return null;
else if (t.left == null)
return t;
return findMin(t.left);
}
So you take the min value from the right subtree, and make it the parent of t.info. Follow these diagrams. We are deleting node 25 with two children.

Is there email validator code for Java ME or BlackBerry?

Is there some standard email validator code sample for Java ME or BlackBerry?
public static boolean validateEmailID(String email) {
email = email.trim();
String reverse = new StringBuffer(email).reverse().toString();
if (email == null || email.length() == 0 || email.indexOf("#") == -1) {
return false;
}
int emailLength = email.length();
int atPosition = email.indexOf("#");
int atDot = reverse.indexOf(".");
String beforeAt = email.substring(0, atPosition);
String afterAt = email.substring(atPosition + 1, emailLength);
if (beforeAt.length() == 0 || afterAt.length() == 0) {
return false;
}
for (int i = 0; email.length() - 1 > i; i++) {
char i1 = email.charAt(i);
char i2 = email.charAt(i + 1);
if (i1 == '.' && i2 == '.') {
return false;
}
}
if (email.charAt(atPosition - 1) == '.' || email.charAt(0) == '.' || email.charAt(atPosition + 1) == '.' || afterAt.indexOf("#") != -1 || atDot < 2) {
return false;
}
return true;
}
Use this code for checking the given email id is valid or not,
private static boolean validateEmailID(String email) {
if (email == null || email.length() == 0 || email.indexOf("#") == -1 || email.indexOf(" ") != -1) {
return false;
}
int emailLenght = email.length();
int atPosition = email.indexOf("#");
String beforeAt = email.substring(0, atPosition);
String afterAt = email.substring(atPosition + 1, emailLenght);
if (beforeAt.length() == 0 || afterAt.length() == 0) {
return false;
}
if (email.charAt(atPosition - 1) == '.') {
return false;
}
if (email.charAt(atPosition + 1) == '.') {
return false;
}
if (afterAt.indexOf(".") == -1) {
return false;
}
char dotCh = 0;
for (int i = 0; i < afterAt.length(); i++) {
char ch = afterAt.charAt(i);
if ((ch == 0x2e) && (ch == dotCh)) {
return false;
}
dotCh = ch;
}
if (afterAt.indexOf("#") != -1) {
return false;
}
int ind = 0;
do {
int newInd = afterAt.indexOf(".", ind + 1);
if (newInd == ind || newInd == -1) {
String prefix = afterAt.substring(ind + 1);
if (prefix.length() > 1 && prefix.length() < 6) {
break;
} else {
return false;
}
} else {
ind = newInd;
}
} while (true);
dotCh = 0;
for (int i = 0; i < beforeAt.length(); i++) {
char ch = beforeAt.charAt(i);
if (!((ch >= 0x30 && ch <= 0x39) || (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a)
|| (ch == 0x2e) || (ch == 0x2d) || (ch == 0x5f))) {
return false;
}
if ((ch == 0x2e) && (ch == dotCh)) {
return false;
}
dotCh = ch;
}
return true;
}
You can simply google around for email validation regex pattern. Thats the easiest and efficient way to check email string format. see the link below.
http://www.zparacha.com/ultimate-java-regular-expression-to-validate-email-address/
http://leshazlewood.com/2006/02/04/java-email-address-validation-the-right-way-regular-expression/
You will find many other examples for regex. For Regex, check the following link.
http://www.regular-expressions.info/java.html

Resources