Simple GUI Notepad Using Ruby

GUI Notepad Using Ruby Code require 'tk' class Notepad def saveFile file = File.open("note", "w") ...

Wednesday, June 10, 2015

Binary Search Tree | Deletion

Deletion of a node in a BST can be more complicated task than searching or inserting a node.

Suppose we want to delete a node P

1> If P is a leaf node i.e. it has no children, then we will just replace P by null.

          8                               8
        /   \          delete(9)        /   \
       3    10         ---------->     3    10
      / \   /                         / \
     1   5 9                         1   5

2> If P has only one child, then we will place the child to P's place.

          8                               8
        /   \          delete(10)       /   \
       3    10         ---------->     3     9
      / \   /                         / \
     1   5 9                         1   5

3>If P has two children, then we will identify P's successor. Call it Q. The successor Q either is a leaf or has only the right child. We will replace P by Q and delete Q.(if it has right child then follow method 2)

         8                              9
       /   \          delete(8)       /   \
      3    10         ---------->    3    10
     / \   /                        / \
    1   5 9                        1   5

C Program

#include <stdio.h>
#include <stdlib.h>

typedef struct BST
{
   struct BST *lc, *rc;
   int data;
}BST;

BST *insertNode(BST *T,int item)
{
    BST *curr = T,*prev = NULL,*temp = NULL;
    int found = 0;
    //Search for the proper position of the node to insert...
    while(curr != NULL && !found)
    {
        //Keeping track of the previous node...
        prev = curr; 
        // If item already exists...
        if(curr->data == item) 
        {
            found = 1;
            printf("\nItem %d Already Exists In The BST.\n",item);
        }
        else if(curr->data > item) {
            curr = curr->lc;
        }
        else {
            curr = curr->rc;
        }
    }
    //Creating a new node...
    temp = (BST*)malloc(sizeof(BST));
    temp->data = item;
    temp->lc = NULL;
    temp->rc = NULL;
    //Only for first node or time...
    if(T == NULL)
        T = temp;
    else if(item > prev->data)
        prev->rc = temp;
    else
        prev->lc = temp;
    return T;
}

void inorder(BST *t)
{
    if(t != NULL) 
    {
        inorder(t->lc);
        printf("%d ",t->data);
        inorder(t->rc);
    }
}

BST *deleteNode(BST *root,int item)
{
    BST *curr = root, *temp = NULL, *parent;
    while(curr != NULL)
    {
        if(curr->data == item)
            break;
        parent  = curr;
        if(item > curr->data)
            curr = curr->rc;
        else
            curr = curr->lc;
    }
    if(curr == NULL)
    {
        printf("\nDelete Request Failed. Value Not Exists.");
        return root;
    }
    else if(curr->lc == NULL && curr->rc == NULL) // Leaf node (case 1)
    {
        if(parent == NULL)
            root = NULL;
        else if(parent->lc == curr)
            parent->lc = NULL;
        else
            parent->rc = NULL;
        return root;
    }
    else if(curr->lc != NULL && curr->rc == NULL) // Only one child (case 2)
    {
        if (root->data == curr->data) 
            root = curr->lc;
        else if(parent->lc == curr)
            parent->lc = curr->lc;
        else
            parent->rc = curr->lc;
        free(curr);
        return root;
    }
    else if(curr->rc != NULL && curr->lc == NULL) // Only one child (case 2)
    {
        if (root->data == curr->data) 
            root = curr->rc;
        else if(parent->lc == curr)
            parent->lc = curr->rc;
        else
            parent->rc = curr->rc;
        free(curr);
        return root;
    }
    else // both child (case 3)
    {
        parent = curr;
        temp = curr->rc;
        while(temp->lc != NULL)
        {
            parent = temp;
            temp = temp->lc;
        }
        curr->data = temp->data;
        if(curr == parent)
            curr->rc = temp->rc;
        else
            parent->lc = temp->rc;      
        free(temp);
        return root;
    }
}

int main()
{
    BST *T = NULL;
    int value;
    T = insertNode(T, 8);
    insertNode(T, 3);
    insertNode(T, 10);
    insertNode(T, 1);
    insertNode(T, 5);
    insertNode(T, 9);
    
    printf("Full Tree: ");
    inorder(T);
    printf("\nAFter Deleting 9(leaf node): ");
    T = deleteNode(T, 9);
    inorder(T);
    printf("\nAFter Deleting 10(node w/ one child): ");
    T = deleteNode(T, 10);
    inorder(T);
    printf("\nAFter Deleting 8(root node): ");
    T = deleteNode(T, 8);
    inorder(T);
    printf("\nAFter Deleting 3(full node): ");
    T = deleteNode(T, 3);
    inorder(T);
    return 0;
}

Output

Full Tree: 1 3 5 8 9 10
AFter Deleting 9(leaf node): 1 3 5 8 10
AFter Deleting 10(node w/ one child): 1 3 5 8
AFter Deleting 8(root node): 1 3 5
AFter Deleting 3(full node): 1 5
--------------------------------
Process exited after 0.4866 seconds with return value 0
Press any key to continue . . .

Tuesday, June 9, 2015

Binary Search Tree | Hight Of A Tree

Path:

The path from node N1 to node Nk is a sequence of nodes N1, N2, …, Nk where Ni is the parent of Ni+1. The length of the path is the number of nodes in the path.

     3
    / \
   1   4
  / \   \
 0   2   5
3 -> 1 -> 1 is path with 3 nodes.
Hight Of A Node:

Hight of a node N is the longest path from the node N to a leaf node (a node with no child). Hight of a leaf node is 0.

     3
    / \
   1   4
  / \   \
 0   2   5
Hight(node(1)) = length(1->0) = 2
Hight Of A Tree:

Hight of a tree T is the hight of its root node.

     3
    / \
   1   4
  / \   \
 0   2   5
Hight(node(3)) = length(3->1->0) = 3

C Program

#include <stdio.h>
#include <stdlib.h>

typedef struct BST
{
   struct BST *lc, *rc;
   int data;
}BST;

void inorder(BST *t)
{
    if(t != NULL) {
        inorder(t->lc);
        printf("%d ",t->data);
        inorder(t->rc);
    }
}

BST *insertNode(BST *T,int item)
{
    BST *curr = T,*prev = NULL,*temp = NULL;
    int found = 0;
    //Search for the proper position of the node to insert...
    while(curr != NULL && !found)
    {
        //Keeping track of the previous node...
        prev = curr; 
        // If item already exists...
        if(curr->data == item) 
        {
            found = 1;
            printf("\nItem %d Already Exists In The BST.\n",item);
        }
        else if(curr->data > item) {
            curr = curr->lc;
        }
        else {
            curr = curr->rc;
        }
    }
    //Creating a new node...
    temp = (BST*)malloc(sizeof(BST));
    temp->data = item;
    temp->lc = NULL;
    temp->rc = NULL;
    //Only for first node or time...
    if(T == NULL)
        T = temp;
    else if(item > prev->data)
        prev->rc = temp;
    else
        prev->lc = temp;
    return T;
}

int max(int a, int b) { return ((a > b)? a : b); }

int hightOfTree(BST *T)
{
    if (T == NULL)
        return 0;
    else
    {
        return (1 + max(hightOfTree(T->lc), hightOfTree(T->rc)));
    }
}

int main()
{
    BST *T = NULL;
    int value;
    
    printf("Enter Values In BST:\n");
    scanf("%d",&value);
    while (value != -999) {
        T = insertNode(T, value);
        scanf("%d",&value);
    }
    
    inorder(T);
    printf("\nHight Of Tree Is: %d.",hightOfTree(T));
    return 0;
}

Output

Enter Values In BST:
3 1 2 0 4 -999
0 1 2 3 4 
Hight Of Tree Is: 3.

Enter Values In BST:
5 4 3 2 1 -999
1 2 3 4 5 
Hight Of Tree Is: 5.

Running Time

This algorithm takes time proportional to the number of nodes in the tree i.e. O(n).

Binary Search Tree | Searching

We assume that a key and the subtree in which the key is searched for are given as an input. We'll take the full advantage of the BST-property.

Suppose we are at a node. If the node has the key that is being searched for, then the search is over. Otherwise, the key at the current node is either strictly smaller than the key that is searched for or strictly greater than the key that is searched for. If the former is the case, then by the BST property, all the keys in th left subtree are strictly less than the key that is searched for. That means that we do not need to search in the left subtree. Thus, we will examine only the right subtree. If the latter is the case, by symmetry we will examine only the right subtree.

Searching | Best Case

It takes O(lg(n)) time to search in this tree. as the hight is lg(n).

        5
       / \
      1   6
     / \
    0   2

Searching | Wrost Case

It takes O(n) time to search in this tree. as the hight is n.

        5
       / 
      4   
     / 
    3 
   / 
  2

C Program

#include <stdio.h>
#include <stdlib.h>

typedef struct BST
{
   struct BST *lc, *rc;
   int data;
}BST;

void inorder(BST *t)
{
    if(t != NULL) {
        inorder(t->lc);
        printf("%d ",t->data);
        inorder(t->rc);
    }
}

BST *insertNode(BST *T,int item)
{
    BST *curr = T,*prev = NULL,*temp = NULL;
    int found = 0;
    //Search for the proper position of the node to insert...
    while(curr != NULL && !found)
    {
        //Keeping track of the previous node...
        prev = curr; 
        // If item already exists...
        if(curr->data == item) 
        {
            found = 1;
            printf("\nItem %d Already Exists In The BST.\n",item);
        }
        else if(curr->data > item) {
            curr = curr->lc;
        }
        else {
            curr = curr->rc;
        }
    }
    //Creating a new node...
    temp = (BST*)malloc(sizeof(BST));
    temp->data = item;
    temp->lc = NULL;
    temp->rc = NULL;
    //Only for first node or time...
    if(T == NULL)
        T = temp;
    else if(item > prev->data)
        prev->rc = temp;
    else
        prev->lc = temp;
    return T;
}

short searchNode(BST *T, int item)
{
 BST *curr = T,*prev = NULL,*temp = NULL;
    int found = 0;
    //Search for the proper position of the node to insert...
    while(curr != NULL && !found)
    {
        // If item already exists...
        if(curr->data == item) {
         return 1;
        }
        else if(curr->data > item) {
            curr = curr->lc;
        }
        else {
            curr = curr->rc;
        }
    }
    return 0;
}
int main()
{
    BST *T = NULL;
    int value;
    
    printf("Enter VAlues In BST:\n");
    scanf("%d",&value);
    while (value != -999) {
        T = insertNode(T, value);
        scanf("%d",&value);
    }
    
    inorder(T);

    printf("\nEnter A Search Value: ");
    scanf("%d",&value);
    printf("%d Is %sOn The Tree.\n",value,searchNode(T, value)?"":"Not ");
    
    printf("\nEnter Another Search Value: ");
    scanf("%d",&value);
    printf("%d Is %sOn The Tree.\n",value,searchNode(T, value)?"":"Not ");
    return 0;
}

Output

Enter VAlues In BST:
3 2 1 4 5 6 -999
1 2 3 4 5 6
Enter A Search Value: 5
5 Is On The Tree.

Enter Another Search Value: 7
7 Is Not On The Tree.

Monday, June 8, 2015

Binary Search Tree | Insertion

Binary Search Tree (BST) is node based binary tree data structure with the following properties:
  • The Left subtree contains the nodes with keys less than the node's key.
  • The Right subtree contains the nodes with keys greater than the node's key.
  • Both the right and left subtree should also be binary search tree.
  • There should not be any duplicate key.

Inserting a node in binary search tree behaves in the same manner as searching operation. Firstly, it checks whether the key is the same as that of root, if not then we either choose the right subtree or the left subtree depending on the value passed is greater or smaller than the root node value respectively.

Eventually, we will reach an external node where we will add the new node as its left or right child depending upon the node's key.

This is also a recursive operation, as we start from the root and go until we find the right place to insert to node.

Insertion time in a BST is proportional to the height of the tree.


Example

Insert: 5 2 8 1 4 7 9 0 3 6


(5) / \ (2) (8) / \ / \ (1) (4) (7) (9) / / / (0) (3) (6)

We used this structure with three members to represent each node in the tree. Here data represents the key of the node and lc and rc are pointers to the left and right subtree respectively

typedef struct BST
{
   struct BST *lc, *rc;
   int data;
}BST;

C Program

#include <stdio.h>
#include <stdlib.h>

typedef struct BST
{
   struct BST *lc,*rc;
   int data;
}BST;
 
void inOrder(BST *t)
{
    if(t != NULL) {
        inOrder(t->lc);
        printf("%d ",t->data);
        nOrder(t->rc);
    }
}
 
BST *insertNode(BST *T, int item)
{
    BST *curr = T,*prev = NULL,*temp = NULL;
    int found = 0;
    //Search for the proper position of the node to insert...
    while(curr != NULL && !found) {
        //Keeping track of the previous node...
        prev=curr; 
        // If item already exists...
        if(curr->data == item) {
            found = 1;
            printf("\nItem %d Already Exists In The BST.\n",item);
        }
        else if(curr->data > item)
            curr = curr->lc;
        else
            curr = curr->rc;
    }
    //Creating a new node...
    temp = (BST*)malloc(sizeof(BST));
    temp->data = item;
    temp->lc = NULL;
    temp->rc = NULL;
    //Only for first node or time...
    if(T == NULL)
        T = temp;
    else if(item > prev->data)
        prev->rc = temp;
    else
        prev->lc = temp;
    return T;
}
  
int main()
{
    BST *T = NULL;
    T = insertNode(T, 5);
    insertNode(T, 2);
    insertNode(T, 8);
    insertNode(T, 1);
    insertNode(T, 4);
    insertNode(T, 7);
    insertNode(T, 9);
    insertNode(T, 0);
    insertNode(T, 3);
    insertNode(T, 6);
    inOrder(T);
    return 0;
}

Output

0 1 2 3 4 5 6 7 8 9

Integer In Words Conversion

The problem is given a number (upto a certain range) we need to convert the number in words.

Example:

  1. 999 -> Nine Hundred Ninety-Nine
  2. 4 -> Four
  3. 0 -> Zero
  4. -230 -> Minus Two Hundred Thirty.
  5. 40 -> Forty

C Implementation

#include <stdio.h>

void print(int arr[], int n)
{
    int m, i;
    char *unit[] = {"","One","Two","Three","Four","Five","Six",
                    "Seven","Eight","Nine"};
    char *ten[] = {"","Ten","Twenty","Thirty","Forty",
                    "Fifty","Sixty","Seventy","Eighty","Ninety"};
    char *hundred[] = {"Ten","Eleven","Twelve","Thirteen","Fourteen",
                    "Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"};
    
    for(i = 0; i < 5; i++) {
        if(i != 3) {
            if(arr[i]) {
                if((arr[i]%10) != 0) {
                    if(arr[i] < 10)
                        printf("%s ",unit[arr[i]]);
                    else if(arr[i] <= 19)
                        printf("%s ",hundred[arr[i]%10]);
                    else
                        printf("%s-%s ",ten[arr[i]/10],unit[arr[i]%10]);
                }
                else
                    printf("%s ",ten[arr[i]/10]);
                switch(i) {
                case 0: printf("Coror ");break;
                case 1: printf("Lakh ");break;
                case 2: printf("Thousand ");
                }
            }
        }
        else if(arr[3]) {
            printf("%s ",unit[(arr[i])]);
            printf("Hundred ");
        }
    }
    printf("\b.");
}

void divide(long int temp)
{
    int arr[10], i;
    long int div = 10000000;
    for(i = 0; i < 5; i++) {
        arr[i] = temp/div;
        temp = temp%div;
        if(i == 2) div /= 10;
        else div /= 100;
    }
    print(arr, 10);
}

int main(void)
{
    int i,j;
    long int num,temp;

    printf("Enter A Number(9-dig): ");
    scanf("%lld",&num);
    
    temp = (num < 0)? (-1 * num) : num;

    printf("In Words: ");
    if(num < 0) {
        printf("Minus ");
        divide(temp);
    }
    else if(num == 0) {
        printf("Zero.");
    }
    else {
        divide(temp);
    }
    return 0;
}



Enter A Number(9-dig): 3
In Words: Three.

Enter A Number(9-dig): 120
In Words: One Hundred Twenty.

Enter A Number(9-dig): 0
In Words: Zero.

Enter A Number(9-dig): -120
In Words: Minus One Hundred Twenty.

Enter A Number(9-dig): 99999
In Words: Ninety-Nine Thousand Nine Hundred Ninety-Nine.

Enter A Number(9-dig): 999999
In Words: Nine Lakh Ninety-Nine Thousand Nine Hundred Ninety-Nine.

Enter A Number(9-dig): 9999999
In Words: Ninety-Nine Lakh Ninety-Nine Thousand Nine Hundred Ninety-Nine.

Enter A Number(9-dig): 002
In Words: Two.

Binary Insertion Sort

We can use binary search to reduce the number of comparisons in normal insertion sort. Binary Insertion Sort find use binary search to find the proper location to insert the selected item at each iteration. In normal insertion, sort it takes O(i) (at ith iteration) in worst case. we can reduce it to O(logi) by using binary search.

C Implementation

// Binary Insertion Sort
#include <stdio.h>
 
// A binary search based function to find the position
// where item should be inserted in a[low..high]
int binarySearch(int a[], int item, int low, int high)
{
    if (high <= low)
        return (item > a[low])?  (low + 1): low;
 
    int mid = (low + high)/2;
 
    if(item == a[mid])
        return mid+1;
 
    if(item > a[mid])
        return binarySearch(a, item, mid+1, high);
    return binarySearch(a, item, low, mid-1);
}
 
// Function to sort an array a[] of size 'n'
void insertionSort(int a[], int n)
{
    int i, loc, j, k, selected;
 
    for (i = 1; i < n; ++i)
    {
        j = i - 1;
        selected = a[i];
 
        // find location where selected should be inserted..
        loc = binarySearch(a, selected, 0, j);
 
        // Move all elements after location to create space..
        while (j >= loc)
        {
            a[j+1] = a[j];
            j--;
        }
        a[j+1] = selected;
    }
}
 
int main()
{
    int a[] = {37, 23, 0, 17, 12, 72, 31,
              46, 100, 88, 54};
    int n = sizeof(a)/sizeof(a[0]), i;
 
    insertionSort(a, n);
 
    printf("Sorted array: \n");
    for (i = 0; i < n; i++)
        printf("%d ",a[i]);
 
    return 0;
}

Output

Sorted array:
0 12 17 23 31 37 46 54 72 88 100