title: DataStructure

#+STARTUP: overview

Stack with Array

Java

build a Stack from Array, and fulfil its methods, remember, it is METHODS One example of its porperties: decimal to binary convertion

function StackwithArray(){
    this.items = [];

    StackwithArray.prototype.push = function (value){
        this.items.push(value);
    };

    StackwithArray.prototype.pop = function(){
        return this.items.pop();
    };

    StackwithArray.prototype.peek = function(){
        return this.items[this.items.length-1];
    };
    StackwithArray.prototype.isEmpty = function(){
        return this.items.length <= 0;
    };
    StackwithArray.prototype.size = function(){
        return this.items.length;
    };
    StackwithArray.prototype.toString = function(){
        tostring = '';
        for (var i = this.items.length-1; i >= 0; i--) {
            tostring += this.items[i]+' ';
        }
        return tostring;
    };
}

var stackwithArray = new StackwithArray();
stackwithArray.push(2);
stackwithArray.push(3);
stackwithArray.push(4);
stackwithArray.push(5);
stackwithArray.push(6);
console.log(stackwithArray.toString());
console.log('Size of  stackwitharray is: '+stackwithArray.size());
stackwithArray.pop();
console.log(stackwithArray.toString());
console.log('Size of  stackwitharray is: '+stackwithArray.size());
stackwithArray.peek();
console.log(stackwithArray.toString());
console.log('Size of  stackwitharray is: '+stackwithArray.size());
console.log(stackwithArray.isEmpty());

function decimal2binary (value){
    var stack = new StackwithArray();
    while(value > 0){
        stack.push(value%2);
        value = Math.floor(value/2);
    }
    var output = '';
    while(!stack.isEmpty()){
        output += stack.pop();
    }
    return output;
};

var target = 100090; 
decimal2binary(89);
console.log(target + ' convert to binary is '+ decimal2binary(target));
6 5 4 3 2 
Size of  stackwitharray is: 5
5 4 3 2 
Size of  stackwitharray is: 4
5 4 3 2 
Size of  stackwitharray is: 4
false
100090 convert to binary is 11000011011111010

Queue with Array

JS

Queeu rebuild

build a Queue from an Array and its methods, one example is Johnausking.

function QueueWithArray(){
    this.items = [];

    QueueWithArray.prototype.enqueue = function(value){
        this.items.push(value);
    };

    QueueWithArray.prototype.dequeue = function(){
        return this.items.shift();
    };

    QueueWithArray.prototype.front = function(){
        return this.items[0];
    };

    QueueWithArray.prototype.isEmpty = function(){
        return this.items.length <= 0;
    };

    QueueWithArray.prototype.size = function(){
        return this.items.length;
    };

    QueueWithArray.prototype.toString = function(){
        var tostring = ' ';
        for (var i = this.items.length -1; i >= 0; i--) {
            tostring += this.items[i]+' ';
        };
        return tostring;
    };
}

var queue = new QueueWithArray();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.enqueue(4);
queue.enqueue(5);
console.log(queue.toString());
queue.dequeue();
console.log(queue.toString());
queue.front();
console.log(queue.toString());
console.log(queue.isEmpty());

var personen = ['zhangsan', 'lisi', 'wangwu', 'zhaoliu', 'wuqi'];
function Johnausking(person, number){
    var queueplay = new QueueWithArray();
    for (var i = 0; i < person.length; i++) {
        queueplay.enqueue(person[i]);
    }

    while(queueplay.size() > 1){
        for (var j = 0; j <number-1; j++) {
            queueplay.enqueue(queueplay.dequeue());
        }
        queueplay.dequeue();
    }

    if (queueplay.size() == 1) {
        console.log('the left person is '+ queueplay.front());
        return person.indexOf(queueplay.front());
    }
    else
        return 'there are not only one person left';
}
console.log(Johnausking(personen, 3));
 5 4 3 2 1 
 5 4 3 2 
 5 4 3 2 
false
the left person is zhaoliu
3

Priority Queue

save all the information with priority, from small to big inner class can't use prototype

   function Priorityqueue(){
       this.array = [];
       function Node(value, priority){
           this.value = value;
           this.priority = priority;
       }

       Priorityqueue.prototype.enqueue = function(value, priority) {
           var element = new Node(value, priority);
           if (this.array.length == 0) {
               this.array.push(element);
           }else{
               var flag = false;
               for (var i = 0; i < this.array.length; i++) {
                   if (element.priority < this.array[i].priority) {
                       this.array.splice(i, 0, element);
                       flag = true;
                       break;
                   }
               }
               if (!flag) {
                   this.array.push(element);
               }
           }
       }

       Priorityqueue.prototype.dequeue = function(){
           return this.items.shift();
       };

       Priorityqueue.prototype.front = function(){
           return this.items[0];
       };

       Priorityqueue.prototype.isEmpty = function(){
           return this.items.length <= 0;
       };

       Priorityqueue.prototype.size = function(){
           return this.items.length;
       };

       Priorityqueue.prototype.toString = function(){
           var tostring = ' ';
           for (var i = this.array.length -1; i >= 0; i--) {
               tostring += this.array[i].value+':'+ this.array[i].priority+'   ';
           };
           return tostring;
       };

   }
   var priorityqueue = new Priorityqueue();
   priorityqueue.enqueue('m', 01);
   priorityqueue.enqueue('d', 59);
   priorityqueue.enqueue('l', 19);
   priorityqueue.enqueue('z', 251);
   priorityqueue.enqueue('x', 50);
   priorityqueue.enqueue('w', 504);

console.log(priorityqueue.toString());



 w:504   z:251   d:59   x:50   l:19   m:1   

Linkedlist

JS


append(elemenet) append element at the end of list insert(elemenet, position) insert elemenet at position of position update(position, elemenet) update the data to elemenet at position get(position) get the elemenet at position indexOf(elemenet) return the position of elemenet removeAt(position) remove the elemenet at position remove(elemenet) remove the elemenet no matater where it is isEmpty()
size() length of list toString()


in the update process, we have two ideas, one is normal, just change the node data the other is create a node with new data, so insert or update can be relavant

function Linkedlist()
{
    //initialization
    this.head = null;
    this.size = 0;
    function Node(data){
        this.data = data;
        this.next = null;
    }

    //append(data)
    Linkedlist.prototype.append = function(data){
        var node = new Node(data);
        var current = this.head;
        if (this.size == 0) {
            this.head = node;
        }else{
            while(current.next){
                current = current.next;
            }
            current.next = node;
        }
        this.size+= 1;
        return;
    };
    //insert(element, position)
    Linkedlist.prototype.insert = function(data, position){
        if (position < 0 || position > this.size) {
            console.log('position is not vaild');
            return;
        }
        var node = new Node(data);
        var current = this.head;
        var pervies = null;
        var tmp = 0;
        while(tmp++ < position){
            pervies = current;
            current = current.next;
        }
        node.next = current;
        pervies.next= node;
        this.size += 1;
        return;
    };

    //update(element, position)
    Linkedlist.prototype.update = function(data, position){
        if (position < 0 || position > this.size) {
            console.log('position is not vaild');
            return;
        }
        // var node = new Node(data);
        // var current = this.head;
        // var pervies = null;
        // var tmp = 0;
        // while(tmp++ < position){
        //     pervies = current;
        //     current = current.next;
        // }
        // node.next = current.next;
        // pervies.next= node;

        var current = this.head;
        var tmp = 0;
        while(tmp++ < position){
            current = current.next;
        }
        current.data = data;
    };

    //get(position)
    Linkedlist.prototype.get = function(position){
        if (position < 0 || position > this.size) {
            console.log('position is not vaild');
            return;
        }
        let current = this.head;
        let tmp = 0;
        while(tmp++ < position){
            current = current.next;
        }
        console.log('at Position of '+position+' is: '+current.data);
        return;
    };

    //indexOf(elemenet)
    Linkedlist.prototype.indexOf = function(data){
        let current = this.head;
        let tmp = 0;
        while (current){
            if (current.data == data) {
                console.log('the elemenet '+data+' is at position of '+tmp);
                return tmp ;
            }
            current = current.next;
            tmp +=1;
        };
        if (!current) {
            console.log('the elemenet '+data+' is not exist');
            return;
        }
    };

    //removeAt(position)
    Linkedlist.prototype.removeAt = function(position){
        if (position < 0 || position >= this.size) {
            console.log('position is not vaild');
            return;
        }
        if (position == 0) {
            this.head = this.head.next;
        }else{
            var index = 0;
            var current = this.head;
            var pervies = null;
            while(index++ < position){
                pervies = current;
                current = current.next;
            }
            pervies.next =  current.next;
        }

        this.size -= 1;
    };

    //remove(elemenet)
    Linkedlist.prototype.remove = function(data){
        let tmp = this.indexOf(data);
        this.removeAt(tmp);

        // var current = this.head;
        // var pervies = null;
        // while(current && current.data != data){
        //     pervies = current;
        //     current = current.next;
        // }
        // if (current) {
        //     if (current == this.head) {
        //         this.head = this.head.next;
        //     }else{
        //         pervies.next = current.next;
        //     }
        // }else{
        //     console.log('the elemenet '+data+' is not exist');
        // }
    };

    //isEmpty()
    Linkedlist.prototype.isEmpty = function(){
        console.log(this.size ==0);
        return;
    };

    //size()
    Linkedlist.prototype.length = function(){
        console.log('the size of linkedlist is '+this.size);
        return;
    };

    // toString
    Linkedlist.prototype.toString = function(){
        if (this.size == 0) {
            console.log('No Elemenet');
            return;
        }
        let current = this.head;
        let liststring = "";
        while(current){
            liststring += current.data+" ";
            current = current.next;
        }
        console.log(liststring);
        return;
    };
}

var linkedlist = new Linkedlist;
linkedlist.append(1);
linkedlist.append(2);
linkedlist.append(30);
linkedlist.append(4);
linkedlist.append(5);
linkedlist.append(6);
linkedlist.toString();
linkedlist.insert('a', 2);
linkedlist.toString();
linkedlist.update('b', 2);
linkedlist.toString();
linkedlist.get(2);
linkedlist.isEmpty();
linkedlist.length();
linkedlist.toString();
linkedlist.indexOf('4');
linkedlist.removeAt(0);
linkedlist.toString();
linkedlist.length();
linkedlist.removeAt(5);
linkedlist.toString();
linkedlist.remove(2);
linkedlist.toString();
1 2 30 4 5 6 
1 2 a 30 4 5 6 
1 2 b 30 4 5 6 
at Position of 2 is: b
false
the size of linkedlist is 7
1 2 b 30 4 5 6 
the elemenet 4 is at position of 4
2 b 30 4 5 6 
the size of linkedlist is 6
2 b 30 4 5 
the elemenet 2 is at position of 0
b 30 4 5 

Python

class LinkNode:
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next


class Demo:
    def __init__(this):
        this.LinkedList = LinkNode(0)
        this.point = this.LinkedList

    def insert(this, x):
        this.point.next = LinkNode(x)
        this.point = this.point.next

    def create(this, numbers):
        for i in numbers:
            this.point.next = LinkNode(i)
            this.point = this.point.next

    def delete(this, value):
        # while(this.LinkedList.data != value):
        #     this.LinkedList = this.LinkedList.next
        # this.LinkedList = this.LinkedList.next
        index = this.LinkedList
        while(index.data != value):
            prev = index
            index = index.next
        prev.next = index.next


if __name__ == "__main__":
    demo = Demo()
    demo.create([1, 2, 3, 4, 5, 6, 7])
    demo.insert(10)
    demo.delete(5)
    while (demo.LinkedList):
        print(demo.LinkedList.data)
        demo.LinkedList = demo.LinkedList.next

0
1
2
3
4
6
7
10

DoubleVerketteList

C/C++

#include <stdio.h>
#include <stdlib.h>
#define N 10

typedef struct node{
  struct node* pronode;
  int data;
  struct node *nextnode;
}node;

node *initnode( node *p){
  p = (node *)malloc(sizeof(node));
  p->pronode = NULL;
  p->nextnode = NULL;
  p->data = 1;
  node *temp = p;
  for (int i = 1; i < N; ++i) {
    node *a =(node *)malloc(sizeof(node));
    a->nextnode = NULL;
    a->pronode = NULL;
    a->data = i+1;
    temp->nextnode = a;
    a->pronode = temp;
    temp = temp->nextnode;
  }
  return p;
}

void display(node *p){
  node *temp = p;
  while (temp) {
    while (temp->nextnode) {
      printf("%d ",temp->data );
      temp = temp->nextnode;
    }
    printf(", and  the last is %d\n",temp->data );
    temp = temp->nextnode;
  }
}

void insert(node *p, int x, int pos){
  node *a =(node *)malloc(sizeof(node));
  a->data = x;
  a->nextnode = NULL;
  a->pronode = NULL;
  if (x == 1) {
    a->nextnode = p;
    p->pronode = a;
    p = a;
  }else {
    node *temp = p;
    for (int i = 1; i < pos-1; i++) {
      temp = temp->nextnode;
    }
    if (temp->nextnode == NULL) {
      temp->nextnode = a;
      a->pronode = temp;
    }else {
      a->nextnode = temp->nextnode;
      temp->nextnode = a;
      a->pronode = temp;
      a->nextnode->pronode = a;   
      /* temp->nextnode->pronode = a; */  // this line do the same as last one, why???
      printf("%s\n", "nihao");
    }
  }
}

node *delete(node *p, int x){
  node *temp = p;  
  if (p->data == x) {
    p = p->nextnode;
    free(temp);
    return p;
  }

  while (temp->nextnode->nextnode != NULL && temp->nextnode->data != x) {
    temp = temp->nextnode;
  }
  if (temp->nextnode->nextnode == NULL) { // check if it is the last element
    if (temp->nextnode->data == x) {      // check if it is what we want 
      temp->nextnode = NULL;
      free(temp->nextnode);
      return p;
    }else {
      printf("there is no element of %d\n", x);
      return p;
    }
  }else {
    temp->nextnode = temp->nextnode->nextnode;
    temp->nextnode->pronode= temp;
    return p;
  }
}

int main(int argc, char *argv[])
{
  node *head = NULL;
  head = initnode(head);
  display(head);
  insert(head, 100, 6);
  display(head);
  delete(head, 100);
  display(head);
  /* 1, if only one elemenet in list */
  /* 2, execute : temp->nextnode->nextnode != NULL && temp->nextnode->data != x */
  /* 3, if while stop, check if temp->nextnode is the last element */
  /* 4, if temp->nextnode is what we want */
  node * p = delete(head, 2);
  display(p);
  return 0;
}
1 2 3 4 5 6 7 8 9 , and  the last is 10
nihao
1 2 3 4 5 100 6 7 8 9 , and  the last is 10
1 2 3 4 5 6 7 8 9 , and  the last is 10
1 3 4 5 6 7 8 9 , and  the last is 10

JS


append(elemenet) append element at the end of list insert(elemenet, position) insert elemenet at position of position update(position, elemenet) update the data to elemenet at position get(position) get the elemenet at position indexOf(elemenet) return the position of elemenet removeAt(position) remove the elemenet at position remove(elemenet) remove the elemenet no matater where it is isEmpty()
size() length of list toString()
forwardtoString()
backwardtoString()


function Doublelinkedlist(){
    //initialization
    this.head = null;
    this.tail = null;
    this.size = 0;
    function Node(data){
        this.data = data;
        this.perv = null;
        this.next = null;
    }
    // append(data)
    Doublelinkedlist.prototype.append = function(data){
        var node = new Node(data);
        if (this.size == 0) {
            this.head = node;
            this.tail = node;
        }else{
            var current = this.head;
            while(current.next){
                current = current.next;
            }
            current.next = node;
            node.perv = current;
            this.tail = node;
        }
        this.size += 1;
    };
    // insert(elemenet, position)
    Doublelinkedlist.prototype.insert = function(data, position){
        if (position < 0 || position >= this.size) {
            console.log('the position to insert is invalid');
            return;
        };
        var node = new Node(data);
        if (position == 0) {
            this.head.perv = node;
            node.next = this.head;
            this.head = node;
            this.size += 1;
            return;
        }else if(position == this.size-1){
            this.tail.next = node;
            node.perv = this.tail;
            this.tail = node;
            this.size += 1;
            return;
        }else{
            let tmp = 0;
            var current = this.head;
            while(tmp++ < position){
                current = current.next;
            }
            current.perv.next = node;
            node.perv = current.perv;
            node.next = current;
            current.perv = node;
            this.size += 1;
            return;
        }
    };
    // update(elemenet, position)
    Doublelinkedlist.prototype.update = function(data, position){
        if (position < 0 || position >= this.size) {
            console.log('the position to insert is invalid');
            return;
        };
        let tmp = 0;
        let current = this.head;
        while(tmp++ < position){
            current = current.next;
        }
        current.data = data;
    };
    // get(position)
    Doublelinkedlist.prototype.get = function(position){
        if (position < 0 || position >= this.size) {
            console.log('the position to insert is invalid');
            return;
        };
        var current = this.head;
        let tmp = 0;
        while(tmp++ < position){
            current = current.next;
        }
        return current.data;
    };


    // indexOf(elemenet)
    Doublelinkedlist.prototype.indexOf = function(data){
        var tmp = 0;
        var current = this.head;
        while(current){
            if (current.data == data) {
                return tmp;       
            }
            current = current.next;
            tmp += 1;
        };
        if (!current) {
            console.log('elemenet '+data+' is not in list');
            return -1;
        }
    };

    // removeAt(position)
    Doublelinkedlist.prototype.removeAt = function(position){
        if (position < 0 || position >= this.size) {
            console.log('the position to insert is invalid');
            return;
        };
        if (position == 0) {
            this.head.next.perv = null;
            this.head = this.head.next;
            this.size -= 1;
            return;
        }else if(position == this.size-1){
            this.tail.perv.next = null;
            this.tail = this.tail.perv;
            this.size -= 1;
            return;
        }else{
            var tmp = 0;
            var current = this.head;
            while(tmp++ < position){
                current = current.next;
            }
            current.perv.next = current.next;
            current.next.perv = current.perv;
            this.size -= 1;
            return;
        }
    };


    // remove(elemenet)
    Doublelinkedlist.prototype.remove = function(data){
        var index = this.indexOf(data);
        this.removeAt(index);
    };

    // isEmpty()
    Doublelinkedlist.prototype.isEmpty = function(){
        return this.size == 0;
    };
    //  length()
    Doublelinkedlist.prototype.length = function(){
        return this.size;
    };
    //forwardtoString()
    Doublelinkedlist.prototype.forwardtoString = function(){
        let current = this.head;
        let string = '';
        while(current){
            string += current.data + '  ';
            current = current.next;
        }
        console.log(string);
    };
    //backwardtoString()
    Doublelinkedlist.prototype.backwardtoString = function(){
        let current = this.tail;
        let string = '';
        while(current){
            string += current.data + '  ';
            current = current.perv;
        }
        console.log(string);
    };
    //toString
    Doublelinkedlist.prototype.toString = function(){
        this.forwardtoString();
    };
}

var doublelinkedlist = new Doublelinkedlist();
doublelinkedlist.append(1);
doublelinkedlist.append(2);
doublelinkedlist.append(3);
doublelinkedlist.append(4);
doublelinkedlist.append(5);
doublelinkedlist.append(6);
doublelinkedlist.forwardtoString();
doublelinkedlist.backwardtoString();
doublelinkedlist.toString();
console.log(doublelinkedlist.isEmpty());
console.log(doublelinkedlist.length());
doublelinkedlist.insert('a', 0);
doublelinkedlist.insert('b', doublelinkedlist.length()-1);
doublelinkedlist.insert('c', 1);
doublelinkedlist.toString();
doublelinkedlist.update('A', 0);
doublelinkedlist.update('B', doublelinkedlist.length()-1);
doublelinkedlist.update('C', 1);
doublelinkedlist.toString();
console.log(doublelinkedlist.get(0));
console.log(doublelinkedlist.indexOf('B'));
doublelinkedlist.removeAt(0)
doublelinkedlist.removeAt(doublelinkedlist.length()-1);
doublelinkedlist.toString();
doublelinkedlist.removeAt(1)
doublelinkedlist.toString();
doublelinkedlist.remove('C')
doublelinkedlist.remove(6)
doublelinkedlist.remove(4)
doublelinkedlist.toString();
1  2  3  4  5  6  
6  5  4  3  2  1  
1  2  3  4  5  6  
false
6
a  c  1  2  3  4  5  6  b  
A  C  1  2  3  4  5  6  B  
A
8
C  1  2  3  4  5  6  
C  2  3  4  5  6  
2  3  5  

SingelKetteLinkeWithHead

C/C++

/* 带头节点 */
/* 建(创建C1) */
/* 查( 全查R1,  靠值查R2,   靠位查R3 ) */
/* 改 (         靠值改U1,  靠位改U2) */
/* 增(头插A1, 尾插A2,中值插A3, 中位插A4) */
/* 删(头删D1, 尾删D2,中值删D3, 中位删D4) */

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

typedef struct Link{
  int elem;
  struct Link *next;
}link;

link *initLinkC1(int j){
  link *p = (link *)malloc(sizeof(link));
  link *temp = p;
  int i;
  for (i=1; i <= j; i++) {
    link *a = (link *)malloc(sizeof(link));
    a->elem = i;
    a->next = NULL;
    temp->next = a;
    temp = temp->next;
  }
  return p;
}

void displayR1(link *p){
  link *temp = p;
  while(temp->next){
    printf("%d ",temp->next->elem);
    temp = temp->next;
  }
  printf("\n");
}

int displayR2(link *p, int k){
  link *temp = p;
  while (temp->next) {
    if (temp->next->elem == k) {
      return temp->next->elem;
    }
    temp = temp->next;
  }
  if (temp->next == NULL) {
    printf("the %d is not found \n", k);
  }
  return k;
}

int displayR3(link *p, int k){
  link *temp = p;
  int i = 0;
  while (i < k && temp->next) {
    temp = temp->next;
    i++;
  }
  if (i != k) {
    printf("the %d postion element is not found\n",k );
    return -1;
  }
  return temp->elem;
}

void changeelementU1(link *p, int i, int k){
  link *temp = p;
  while (temp->next != NULL){
    if (temp->elem == i){
      break;
    }
    temp = temp->next;
  }

  if (temp->next == NULL) {   // if temp is the last element,
    if (temp->elem != i) {    // if the last element is not what we want
      printf("there is no element which contains %d\n",i );
    }else {
      temp->elem = k;        // if the last one is what we want
    }
  }else {
    temp->elem = k;          // if temp is not the last one
  }
}

void changeelementU2(link *p, int i, int k){
  link *temp = p;
  int m = 0;
  while (m < i && temp->next != NULL){
    temp = temp->next;
    m++;
  }
  if (m != i) {             // if the length of list is shorter than given i
    printf("the %d postion element is not found\n",i );    
  }else {
    temp->elem = k;
  }
}

void addelementA1(link *p, int k){
  link *a = (link *)malloc(sizeof(link));
  a->elem = k;
  a->next = p->next;
  p->next = a;
}

void addelementA2(link *p, int k){
  link *temp = p;
  while (temp->next->next != NULL) {
    temp = temp->next;
  }
  link *a = (link *)malloc(sizeof(link));
  a->elem = k;
  a->next = NULL;
  temp->next->next = a;
}

void addelementA3(link *p, int i, int k){
  link *temp = p;
  while (temp->next != NULL) {
    if (temp->next->elem == i) {
      break;
    }
    temp = temp->next;
  }
  if (temp->next == NULL) {    // if temp is the last element
    if (temp->elem != i) {     // if the last element is not what we want :temp->elem != k
      printf("there is no element which contains %d\n",k );
    }else {                     // if the last element is what we want: temp->elem == k
      link *a = (link *)malloc(sizeof(link));
      a->elem = k;
      a->next = NULL;
      temp->next = a;
    }
  }else {                       // if temp->next->elem == k
    link *a = (link *)malloc(sizeof(link));
    a->elem = k;
    a->next = NULL;
    /* add the element behind i */
    a->next = temp->next->next;
    temp->next->next = a;
    /* add the element front of i */
    /* a->next = temp->next; */
    /* temp->next = a; */
  }
}

void addelementA4(link *p, int i, int k){
  link *temp = p;
  int m = 0;
  while (m < i && temp->next != NULL) {
    temp = temp->next;
    m++;
  }
  if (m != i) {                    // the length of list is shorter than i
      printf("the %d postion element is not found\n",i);
  }else if(!temp->next) {            // if temp is the last element of list      
      link *a = (link *)malloc(sizeof(link));
      a->elem = k;
      a->next = NULL;
      temp->next = a;
  }else {                           // if temp is not the element of list
    link *a = (link *)malloc(sizeof(link));
    a->elem = k;
    a->next = NULL;
    a->next = temp->next->next;
    temp->next->next = a;
    /* add the element front of i */
    /* a->next = temp->next; */
    /* temp->next = a; */
  }
}

void deleteelementD1(link *p){
  p->next = p->next->next;
}

void deleteelementD2(link *p){
  link *temp = p;
  while(temp->next->next){
    temp = temp->next;
  }
  temp->next = NULL;
  free(temp->next);
}

void deleteelementD3(link *p, int k){
  link *temp = p;
  while (temp->next->next != NULL){
    if (temp->next->elem == k){
      break;
    }
    temp = temp->next;
  }
  if (temp->next->next == NULL) {      // if temp->next is the last element
    if(temp->next->elem != k) {         // temp->next is the last, but it's not what we want
      printf("there is no element which contains %d\n",k );
    }else{                               // temp->next is the last, but is what we want
      temp->next = NULL;
      free(temp->next);
    }
  }else{                               // temp->next is not the last, so it must be what we look for
    temp->next = temp->next->next;
  }
}

void deleteelementD4(link *p, int k){
  link *temp = p;
  if (k == 1) {
    if (temp->next->next == NULL) {   // only one element auf dem List
      temp->next = NULL;
      free(temp->next);
      return;
    }else {
      temp->next = temp->next->next;
      return;
    }
  }
  // if k >=  2 and there are more than or equal 2 elements in list
  int m = 0;             
  while (m < k-1 && temp->next->next != NULL){
    temp = temp->next;
    m++;
  }
  if (m != k-1) {                              // list is shorter than k
    printf("the %d postion element is not found\n",k);
  }else if(temp->next->next == NULL){            // if temp->next->next is the last element
    temp->next = NULL;
    free(temp->next);
  }else{                                        // if temp->next->next is not the last element
    temp->next = temp->next->next;
  }
}

link *reserve(link* p){
  link * begin = NULL;
  link * mid = p->next;
  link * end = p->next->next;
  while (end) {
    mid->next = begin;
    begin = mid;
    mid = end;
    end = end->next;
  }
  mid->next = begin;
  link *m =(link *)malloc(sizeof(link));
  m->next = mid;
  return m;
}

int main(int argc, char *argv[])
{
  /* 建(创建C1) */
  link *p = initLinkC1(9);
  printf("generate the list from 1 to 9 \n");
  /* 查( 全查R1,  靠值查R2,   靠位查R3 ) */  
  displayR1(p);
  int r2 = 3;
  printf("check if we can find %d in the list, and  to be %d\n", r2, displayR2(p, r2));
  int r3 = 10;
  printf("check if we can find %d postion in the list, and to be %d\n", r3, displayR3(p, r3));
  /* 改 (         靠值改U1,  靠位改U2) */
  printf("change the element 9 to 10 \n");
  changeelementU1(p, 9, 10);
  displayR1(p);
  printf("change the postion 9 to 10 \n");
  changeelementU2(p, 9, 11);
  displayR1(p);
  /* 增(头插A1, 尾插A2,中值插A3, 中位插A4) */
  printf("add 0 to the begin of list \n");
  addelementA1(p, 0);
  displayR1(p);
  printf("add 20 to the end of list \n");
  addelementA2(p, 20);
  displayR1(p);
  printf("add 18 to the list behind element 2 \n");
  addelementA3(p, 2, 15);
  displayR1(p);
  printf("add 18 to the list behind  postion 2 \n");
  addelementA4(p, 1, 18);
  displayR1(p);
  /* 删(头删D1, 尾删D2,中值删D3, 中位删D4) */
  printf("delete the frist lement \n");
  deleteelementD1(p);
  displayR1(p); 
  printf("delete the the last element \n");
  deleteelementD2(p);
  displayR1(p);
  printf("delete the element 1 \n");
  deleteelementD3(p, 1);
  displayR1(p);
  printf("delete the postion 2 \n");
  deleteelementD4(p, 2);
  displayR1(p);
  /* reverse倒叙  */
  /* 1 去掉头节点 */
  /*   2 从第一个元素开始反转,并连接 */
  /*   3 到end = null 停止 */
  /*   4 连接最后一个元素 */
  /*   5 开辟新的头节点 */
  /*   6 连接头节点,并返回 */
  printf("reserve the list\n");
  link *m = reserve(p);
  displayR1(m);
  return 0;
}


generate the list from 1 to 9 
1 2 3 4 5 6 7 8 9 
check if we can find 3 in the list, and  to be 3
the 10 postion element is not found
check if we can find 10 postion in the list, and to be -1
change the element 9 to 10 
1 2 3 4 5 6 7 8 10 
change the postion 9 to 10 
1 2 3 4 5 6 7 8 11 
add 0 to the begin of list 
0 1 2 3 4 5 6 7 8 11 
add 20 to the end of list 
0 1 2 3 4 5 6 7 8 11 20 
add 18 to the list behind element 2 
0 1 2 15 3 4 5 6 7 8 11 20 
add 18 to the list behind  postion 2 
0 1 18 2 15 3 4 5 6 7 8 11 20 
delete the frist lement 
1 18 2 15 3 4 5 6 7 8 11 20 
delete the the last element 
1 18 2 15 3 4 5 6 7 8 11 
delete the element 1 
18 2 15 3 4 5 6 7 8 11 
delete the postion 2 
18 15 3 4 5 6 7 8 11 
reserve the list
11 8 7 6 5 4 3 15 18

DoubleRecycleVerketteList

C/C++

#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct node {
  struct node * Nnode;
  struct node * Pnode;
  int data;
}node;

node *initDoubleRecycleVerketteList(int x){
  node * head = (node *)malloc(sizeof(node));
  head->data = 1;
  head->Nnode = NULL;
  head->Pnode = NULL;
  node * temp = head;
  for (int i = 2; i <=x; i++){
    node * a = (node *)malloc(sizeof(node));
    a->data = i;
    a->Nnode = NULL;
    a->Pnode = NULL;

    temp->Nnode = a;
    a->Pnode = temp;
    temp = temp->Nnode;
  }
  temp->Nnode = head;
  head->Pnode = temp;
  return head;
}

void display(node *p){
  node *temp = p;
  if (p != NULL) {
    do{
      printf("%d ", temp->data);
      temp = temp->Nnode;
    } while (temp != p);
  }else {
    printf("the list is empty\n");
  }
}  

int main(int argc, char *argv[])
{
  node * head = initDoubleRecycleVerketteList(N);
  display(head);
  return 0;
}

1 2 3 4 5 6 7 8 9 10

Priority Queues

description

Priority Queues is a set of instances, which
are sorted according to their keys
This can be implemented by binary heap
Heap sort all key with a Max-heap A

show-Max(A)

return A[0]

Extract-Max(A)

max = A[0]
A[0] <- A[A.heap_size]
A.heap_size--
Max-heap(A,A.heap_size, 0)
return max

Heap-increase-key(A, i, k)

increase the elemenet with i priority to k priority

A[i] <- k
while i > 1 and A[i] > A[parent(i)]:
    exchange (A[i], A[parent(i)])
    exchange (i, parent(i))

Heap-insert(A, k)

A.heap_size++
A[A.heap_size] = -\inf
Heap-include-key(A, A.heap_size, k)

StaticKetteList

C/C++

#include <stdio.h>
#define maxSize 6
typedef struct {
    int data;
    int cur;
}component;
//将结构体数组中所有分量链接到备用链表中
void reserveArr(component *array);
//初始化静态链表
int initArr(component *array);
//输出函数
void displayArr(component * array,int body);
//从备用链表上摘下空闲节点的函数
int mallocArr(component * array);
int main() {
    component array[maxSize];
    int body=initArr(array);
    printf("静态链表为:\n");
    displayArr(array, body);
    return 0;
}
//创建备用链表
void reserveArr(component *array){
    for (int i=0; i<maxSize; i++) {
        array[i].cur=i+1;//将每个数组分量链接到一起
        array[i].data=-1;
    }
    array[maxSize-1].cur=0;//链表最后一个结点的游标值为0
}
//提取分配空间
int mallocArr(component * array){
    //若备用链表非空,则返回分配的结点下标,否则返回 0(当分配最后一个结点时,该结点的游标值为 0)
    int i=array[0].cur;
    if (array[0].cur) {
        array[0].cur=array[i].cur;
    }
    return i;
}
//初始化静态链表
int initArr(component *array){
    reserveArr(array);
    int body=mallocArr(array);
    //声明一个变量,把它当指针使,指向链表的最后的一个结点,因为链表为空,所以和头结点重合
    int tempBody=body;
    for (int i=1; i<4; i++) {
        int j=mallocArr(array);//从备用链表中拿出空闲的分量
        array[tempBody].cur=j;//将申请的空闲分量链接在链表的最后一个结点后面
        array[j].data=i;//给新申请的分量的数据域初始化
        tempBody=j;//将指向链表最后一个结点的指针后移
    }
    array[tempBody].cur=0;//新的链表最后一个结点的指针设置为0
    return body;
}

void displayArr(component * array,int body){
  int tempBody=body;//tempBody准备做遍历使用
    while (array[tempBody].cur) {
        printf("%d,%d ",array[tempBody].data,array[tempBody].cur);
        tempBody=array[tempBody].cur;
    }
    printf("%d,%d\n",array[tempBody].data,array[tempBody].cur);
}

静态链表为:
-1,2 1,3 2,4 3,0

Lookup Table

C/C++

#include <stdio.h>
#include <stdlib.h>
#define  KeyType int
typedef struct{
  KeyType key;
}ElemType;

typedef struct{
  ElemType *elem;
  int length;
}SSTable;

void create(SSTable ** table, int *context , int length){
  (*table)=(SSTable*)malloc(sizeof(SSTable));
  (*table)->length = length;
  (*table)->elem = (ElemType*)malloc((length+1)*sizeof(ElemType));
  for (int i =1; i <= length; i++) {
    (*table)->elem[i].key = *(context+i-1);
  }
}

int search(SSTable *table, int lookup){
  table->elem[0].key = lookup;
  int i = table->length;
  while (table->elem[i].key != table->elem[0].key) {
    i--;
  }
  return i;
}

int main(int argc, char *argv[])
{
  int context[] = {1, 3, 7, 23, 56, 89, 345};
  int length =  sizeof(context)/sizeof(int);
  SSTable *table;
  create(&table, context, length);
  int lookup = 3;
  int localation = search(table, lookup);
  if (localation) {
    printf("In\n");
  }else {
    printf("NOT In\n");
  }
  return 0;
}

In

Set

JS

function Dictionay() {
    // initialization
    this.items = {};
    Dictionay.prototype.set = function (key, value) {
        this.items[key] = value;
    };

    //has(key)
    Dictionay.prototype.has = function (key) {
        return this.items.hasOwnProperty(key);
    };

    //remove(key)
    Dictionay.prototype.remove = function (key) {

        if (!this.has(key)) return false;


        delete this.items[key];
        return true;
    };
    //get(key)
    Dictionay.prototype.get = function (key) {
        return this.has(key) ? this.items[key] : undefined;
    };

    //keys()
    Dictionay.prototype.keys = function () {
        return Object.keys(this.items);
    };

    //values()
    Dictionay.prototype.values = function () {
        return Object.values(this.items);
    };

    //size()
    Dictionay.prototype.size = function () {
        return this.keys().length;
    };

    //clear()
    Dictionay.prototype.clear = function () {
        this.items = {};
    };
}


var dict = new Dictionay();

dict.set("age", 18);
dict.set("name", "Coderwhy");
dict.set("height", 1.88);
dict.set("address", "广州市");

console.log(dict.keys()); // age,name,height,address
console.log(dict.values()); // 18,Coderwhy,1.88,广州市
console.log(dict.size()); // 4
console.log(dict.get("name")); // Coderwhy
dict.remove("height");
console.log(dict.keys());// age,name,address
dict.clear();

[ 'age', 'name', 'height', 'address' ]
[ 18, 'Coderwhy', 1.88, '广州市' ]
4
Coderwhy
[ 'age', 'name', 'address' ]

HashTable

JS

simple example

function HashTable(){
    //initialization
    this.limit = 7;
    this.storage = [];
    this.conut = 0;

    //hash()
    HashTable.prototype.hash = function(key){
        var hashCode = 0;
        for (var i = 0; i < key.length; i++) {
            hashCode =37*hashCode + key.charCodeAt(i);
        }
        hashCode = hashCode % this.limit;
        return hashCode;
    };
    //put(key, value)
    HashTable.prototype.put = function(key, value){
        var index = this.hash(key);
        var bucket = this.storage[index];
        if (bucket == null) {
            bucket = [];
            this.storage[index] = bucket;
        }
        var override = false;
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i];
            if (tuple[0] == key) {
                tuple[1] = value;
                override = true;
            }
        }
        if (!override) {
            bucket.push([key, value]);
            this.conut += 1;
        }
    };

    //get(key)
    HashTable.prototype.get = function(key){
        var index = this.hash(key);
        var bucket = this.storage[index];
        if (bucket == null) {
            return null;
        }
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i];
            if (tuple[0] == key) {
                return tuple[1];
            };
        };
        return null;
    };
    //remove(key)
    HashTable.prototype.remove = function(key){
        var index = this.hash(key);
        var bucket = this.storage[index];
        if (bucket == null) {
            return null;
        }
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i];
            if (tuple[0]== key){
                bucket.splice(i, 1);
                this.conut--;
                return tuple[1];
            }
        };
        return null;
    };
    //isEmpty()
    HashTable.prototype.isEmpty = function(){
        return this.conut == 0;
    };
    //size()
    HashTable.prototype.size = function(){
        return this.conut;
    };
}

var ht = new HashTable();
ht.put("abc", 1);
ht.put("bcd", 2);
ht.put("cde", 3);
ht.put("def", 4);
ht.put("efg", 5);
ht.put("fgh", 6);

console.log(ht.get("aaa"));
Console.log(ht.get("abc"));
console.log(ht.remove("bcd"));
console.log(ht.get("def"));


null
1
2
4

void swap(int *a, int *b){ int tmp = *a; ,*a = *b; ,*b = tmp; } void heapify(int A[], int N, int i){ int leftchild = i*2+1; int rightchild = i*2+2; int maxindex = i; if (leftchild < N && A[leftchild] > A[maxindex]) { maxindex = leftchild; } if (rightchild < N && A[rightchild] > A[maxindex]) { maxindex = rightchild; } if (maxindex != i) { swap(A[maxindex], A[i]); heapify(A, N, maxindex); } }

void build~heap~(int A[], int N){ int last~parent~ = (N-1-1)/2; int i; for (i = last~parent~; i >= 0; i--) { heapify(A, N, i); } }

int main(int argc, char *argv[]) { int A[] = {2, 1, 3, 4, 5, 3, 6, 7, 8, 4, 9, 45, 9,34, 23,345, 546,20, 23465, 90, 19}; int N = sizeof(A)/sizeof(int); build~heap~(A, N); for (int i = N-1; i >= 0; i--) { swap(A[i], A[0]); heapify(A, i, 0); }

for (int j = 0; j < N; ++j) { printf("%d ",A[j]); } return 0; }

vollstangdig example

function HashTable() {
    // 定义属性
    this.storage = []
    this.count = 0
    this.limit = 8

    // 定义相关方法
    // 判断是否是质数
    HashTable.prototype.isPrime = function (num) {
        var temp = parseInt(Math.sqrt(num))
        // 2.循环判断
        for (var i = 2; i <= temp; i++) {
            if (num % i == 0) {
                return false
            }
        }
        return true
    }

    // 获取质数
    HashTable.prototype.getPrime = function (num) {
        while (!isPrime(num)) {
            num++
        }
        return num
    }

    // 哈希函数
    HashTable.prototype.hashFunc = function(str, max) {
        // 1.初始化hashCode的值
        var hashCode = 0

        // 2.霍纳算法, 来计算hashCode的数值
        for (var i = 0; i < str.length; i++) {
            hashCode = 37 * hashCode + str.charCodeAt(i)
        }

        // 3.取模运算
        hashCode = hashCode % max
        return hashCode
    }

    // 插入数据方法
    HashTable.prototype.put = function (key, value) {
        // 1.获取key对应的index
        var index = this.hashFunc(key, this.limit)

        // 2.取出数组(也可以使用链表)
        // 数组中放置数据的方式: [[ [k,v], [k,v], [k,v] ] , [ [k,v], [k,v] ]  [ [k,v] ] ]
        var bucket = this.storage[index]

        // 3.判断这个数组是否存在
        if (bucket === undefined) {
            // 3.1创建桶
            bucket = []
            this.storage[index] = bucket
        }

        // 4.判断是新增还是修改原来的值.
        var override = false
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] === key) {
                tuple[1] = value
                override = true
            }
        }

        // 5.如果是新增, 前一步没有覆盖
        if (!override) {
            bucket.push([key, value])
            this.count++

            if (this.count > this.limit * 0.75) {
                var primeNum = this.getPrime(this.limit * 2)
                this.resize(primeNum)
            }
        }
    }

    // 获取存放的数据
    HashTable.prototype.get = function (key) {
        // 1.获取key对应的index
        var index = this.hashFunc(key, this.limit)

        // 2.获取对应的bucket
        var bucket = this.storage[index]

        // 3.如果bucket为null, 那么说明这个位置没有数据
        if (bucket == null) {
            return null
        }

        // 4.有bucket, 判断是否有对应的key
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] === key) {
                return tuple[1]
            }
        }

        // 5.没有找到, return null
        return null
    }

    // 删除数据
    HashTable.prototype.remove = function (key) {
        // 1.获取key对应的index
        var index = this.hashFunc(key, this.limit)

        // 2.获取对应的bucket
        var bucket = this.storage[index]

        // 3.判断同是否为null, 为null则说明没有对应的数据
        if (bucket == null) {
            return null
        }

        // 4.遍历bucket, 寻找对应的数据
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] === key) {
                bucket.splice(i, 1)
                this.count--

                // 缩小数组的容量
                if (this.limit > 7 && this.count < this.limit * 0.25) {
                    var primeNum = this.getPrime(Math.floor(this.limit / 2))
                    this.resize(primeNum)
                }
            }
            return tuple[1]
        }

        // 5.来到该位置, 说明没有对应的数据, 那么返回null
        return null
    }

    // isEmpty方法
    HashTable.prototype.isEmpty = function () {
        return this.count == 0
    }

    // size方法
    HashTable.prototype.size = function () {
        return this.count
    }

    // 哈希表扩容
    HashTable.prototype.resize = function (newLimit) {
        // 1.保存旧的数组内容
        var oldStorage = this.storage

        // 2.重置属性
        this.limit = newLimit
        this.count = 0
        this.storage = []

        // 3.遍历旧数组中的所有数据项, 并且重新插入到哈希表中
        oldStorage.forEach(function (bucket) {
            // 1.bucket为null, 说明这里面没有数据
            if (bucket == null) {
                return
            }

            // 2.bucket中有数据, 那么将里面的数据重新哈希化插入
            for (var i = 0; i < bucket.length; i++) {
                var tuple = bucket[i]
                this.put(tuple[0], tuple[1])
            }
        }).bind(this)
    }
}


Binary tree

By delete:


without child just delete with one child just overwirte itself with two child with precursor or Successor and recursive if necessary


RedBlack tree

5 Rules

  • alle node red or black
  • root black
  • leaf black null
  • red can't together
  • all path has the same number of black

2 whirl

  • left whirl, Counterclockwise
  • right whirl, clockwise

just whirl, if there is a node or a branch between the two whirled node, after the whirling, it's still in the between!!!

5 casese to add new red node


1 no root add root 2 black father just add new node 3 red father, red uncle black father, black uncle, red grandfather 4 red father, black uncle, left child black father, black uncle, red grandfather, right whirl 5 red father, black uncle, right child left whirl, to step 4


3,4,5 will be repeated if necessary!

Cartesian tree

this tree has two property,
1, it's a heap, which mean, the parents are all smaller than their childen
2, we can get the original array with the IN-order scan of the tree

How to build cartesian tree
for inserting a new node, we compare it to the root and the rightest edge,
if it is smaller than the root, trun the all(include the root) to be new node's left child
if it is bigger, go down to the next node, if go to the leaf, add it just as right child
if it is bigger, go down to the next node, if it is smaller than one node,
                                           trun all to be the left child, and new node as right chilc

this can be done in time compexity

Binary Heap

Binary Heap example deviced by heap sort

let swap = function (left:number, right:number){
  return [right, left]
  }

let heapfly =  function(list:number[], length:number, index:number){
      var leftchild = index*2+1
      var rightchild = index*2+2
      var maxindex = index
      if (leftchild < length && list[leftchild] >list[maxindex]) {
          [leftchild, maxindex] = swap(leftchild, maxindex)
      }

    if (rightchild < length && list[rightchild]>list[maxindex]) {
        [rightchild, maxindex] = swap(rightchild, maxindex)
      }
      if (maxindex != index) {
          [list[maxindex], list[index]] = swap(list[maxindex], list[index])
          heapfly(list, length, maxindex)
      }
  }
 let build_heap = function (list:number[], lenght:number){
      var lastperent = Math.floor((length-1-1) / 2);
      for (var i = lastperent; i >= 0; i--) {
          heapfly(list, length, i);
      }
  }
  var list: number[] = [2, 1, 3, 4, 5, 3, 5, 7, 8, 45,  9, 25, 34, 23, 345, 546, 20, 23465, 90, 19];
  console.log(list)
  var length: number = list.length;
  build_heap(list, length)

  for (var i = length-1; i >= 0; i--) {
      [list[i], list[0]]= swap(list[i], list[0])
      heapfly(list, i, 0)
  }
  console.log(list)

[
    2,  1,     3,  4,   5,
    3,  5,     7,  8,  45,
    9, 25,    34, 23, 345,
  546, 20, 23465, 90,  19
]
[
   1,  2,   3,   3,     4,
   5,  5,   7,   8,     9,
  19, 20,  23,  25,    34,
  45, 90, 345, 546, 23465
]

Binomial-tree

Definition: if k > 0, .

digraph diagramm {
A0;
B0 -> B1;
C0 -> C1;
C0 -> C2;
C2 -> C3;
D0 -> D1; 
D0 -> D2;
D0 -> D3;
D2 -> D4;
D3 -> D5;
D3 -> D6;
D6 -> D7;

}   

Binomial Heap

Binomial Heap is a forest of binomial Tree
1. all binomial tree are min(max)imum heap property
2. with different order Binomial Tree consist Binomial Heap, non duplicated order binomial tree
digraph diagramm {
A0;
A0 -> B0;
B0 -> B1;

B0 -> C0;
C0 -> C1;
C0 -> C2;
C2 -> C3;

C0 -> D0;
D0 -> D1; 
D0 -> D2;
D0 -> D3;
D2 -> D4;
D3 -> D5;
D3 -> D6;
D6 -> D7;
}   

Each order has only one Binomial Tree, conlidataion is required at each min-extract, merge

Fibonacci Heap

lazy Binomial Heap

For merge Operation:
Just concatenate the two binomial Heap, without the consolidation step

For Min-extra:
after extracte the minmum we merge  the root list.
the conlidataion will not be executed after merge, until now
clean the masse

key-decrease O(1)

key-decrease is also lazy, just cut it off, and add to rootlist

amortised Min-extra to

amortised operation reduce Min-extra to

damaged Fibonacci Heap

For all perents, if one child is loss, will be marked as red, if the second also loss, the perent will be cut off, and add to root list.

Max-damaged-Fibonacci-Heap

Max-damaged-Fibonacci-Heap has Fibonacci number nodes

Van Emde Boas Tree

description

we want to have a data structure, which can inert, delete, succ, pred, in

Open Address

for a dynamical Set S, we maintain an array A[n] only with bit 0 or 1. if i S, A[i] = 1 Set S:


1 3 4 2 5 7 8 12 11 15 14 17 20 9


Array A[]


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

1 1 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 0 0 1



min: max membership insert delete succ pred


open address + binary tree

Build a binary tree with array A[], which are repersentation of set S. Set S:


1 3 4 2 5 7 8 12 11 15 14 17 20 9


Array A[]


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

1 1 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 0 0 1



min: max membership insert delete succ pred


Open address + squart n tree

This is the same idea like with binary tree, just reduce the level to 3 we assume that the number of elements is


min: max membership insert delete succ pred


photo van Emde Boas tree

description

Array A[] in recursive stored in a tree,
this tree has many block recursively, and each block has three components,
1. integel u: indicate the elements of such block
2. point to summary, which is also a block
3. a array of lenght <span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.04em;vertical-align:-0.2397em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.8003em;"><span class="svg-align" style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span class="mord mathnormal" style="padding-left:0.833em;">u</span></span><span style="top:-2.7603em;"><span class="pstrut" style="height:3em;"></span><span class="hide-tail" style="min-width:0.853em;height:1.08em;"><svg xmlns="http://www.w3.org/2000/svg" width='400em' height='1.08em' viewBox='0 0 400000 1080' preserveAspectRatio='xMinYMin slice'><path d='M95,702 c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14 c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54 c44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10 s173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429 c69,-144,104.5,-217.7,106.5,-221 l0 -0 c5.3,-9.3,12,-14,20,-14 H400000v40H845.2724 s-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7 c-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z M834 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.2397em;"><span></span></span></span></span></span></span></span></span>, each elemenet in array point to a such block recursively

the smallest block only contains two elemenet, and it's u=2 and no sammary pointer

we start with the block, which integel u is the smallest we define: high(x) = floor low(x) = x mod index(x,y) = so x = index(high(x), low(x))

membership

Prototype_veb_member(V,x)
if V.u == 2:
  return V[x]
else return Prototype_veb_member(V.cluster[high(x)], low(x))

insert

delete

secc

pred

Van Emde Boas Tree

q implement

/* 
 * Code for van emde boas tree. Try to implement function for predecessor as
 * an exercise.
 */

#include <cmath>
#include <iostream>
#include <vector>

class vEB
{
  int u;
  int min;
  int max;
  vEB *summary;
  std::vector<vEB *> children;

  int high(int k){
    int x = std::ceil(std::sqrt(u));
    return std::floor(k / x);
  }

  int low(int k){
    int x = std::ceil(std::sqrt(u));
    return k % x;
  }

  int index(int k, int kk){
    return (k * (int)std::sqrt(u)) + kk;
  }

public:
  vEB(int U){
    // u = std::pow(std::sqrt(U), 2);
    u = U;
    min = U;
    max = -1;

    if (u <= 2){
      summary = nullptr;
      children = std::vector<vEB *> (0, nullptr);
    }
    else{
      int children_count = std::ceil(std::sqrt(u));
      int children_size = std::ceil(u / std::sqrt(u));

      summary = new vEB(children_count);
      children = std::vector<vEB *> (children_count, nullptr);
      for(int i = 0; i < children_count; ++i){
        children[i] = new vEB(children_count);
      }
    }
  }

  void insert(int k){
    if(min > max){
      min = max = k;
      return;
    }

    if(k < min){
      int temp;
      temp = min;
      min = k;
      k = temp;
    }

    if(k > max)
      max = k;

    if(u == 2){
      max = k;
      return;
    }

    int i = high(k);
    int j = low(k);

    children[i]->insert(j);

    if(children[i]->max == children[i]->min)
      summary->insert(i);
  }

  void remove(int k){
    if(min > max)
      return;

    if(min == max){
      min = u;
      max = -1;
      return;
    }

    if(u == 2){
      if(k == 1){
        if(min == 1){
          min = u;
          max = -1;
        }
        else if(min == 0)
          max = 0;
      }
      else
        if(max == 0){
          min = u;
          max = -1;
        }
        else if(max == 1)
          min = 1;
      return;
    }

    if(k == min){
      int i = summary->min;
      min = index(i, children[i]->min);
      return;
    }

    int i = high(k);
    int j = low(k);

    children[i]->remove(j);

    if(children[i]->min > children[i]->max){
      summary->remove(i);
    }

    if(k == max){
      if(summary->min > summary->max){
        max = min;
      }
      else{
        i = summary->min;
        max = index(i, children[i]->max);
      }
    }
  }

  int getMin(){
    return min;
  }
  int getMax(){
    return max;
  }

  int universe(){
    return u;
  }

  int successor(int k){
    if(k <= min)
      return min;
    else if(k > max)
      return u;

    int i = high(k);
    int j = low(k);

    if(j <= children[i]->max){
      int res = children[i]->successor(j);
      if(res >= (u / (int)std::sqrt(u)))
        return u;
      return k - j + res;
    }
    else{
      int res = children[summary->successor(i)]->min;
      if(res >= children[summary->min]->u)
        return u;
      return index(summary->successor(i), res);
    }
  }
};

int main(){
  vEB tree(1 << 4);
  std::cout << "Insert 12, 10, 13, 14\n";
  tree.insert(3);
  tree.insert(5);
  tree.insert(7);
  tree.insert(9);
  tree.insert(10);
  tree.insert(13);
  tree.insert(14);
  std::cout << "Successor of 12 is\n";
  std::cout << tree.successor(12) << '\n';
  tree.remove(13);
  std::cout << "Removing 13. Now successor of 13 is\n";
  std::cout << tree.successor(13) << '\n';
  tree.remove(14);
  std::cout << "Removing 14. Now successor of 13 is\n";
  std::cout << tree.successor(13) << '\n';
  std::cout << "16, which is universe size, means no successor.\n";

  return 0;
}