在logN中搜索,插入,删除和删除最后的操作

时间:2015-06-15 10:41:32

标签: algorithm data-structures tree binary-search-tree

什么是最适合在O(log n)时间内支持以下操作的数据结构:

search(x) finds the element with key x 
insert(x) insert an element with a key x    
delete(x) delete an element with a key x    
deleteLast() removes the most recently inserted element

我知道二元搜索树可以很好地处理前三个操作。但是如何处理第四个查询。如果BST不是一个好的解决方案,也告诉我们最适合处理所有四个查询的数据结构。

3 个答案:

答案 0 :(得分:3)

感谢@ThomasJungblut推出此解决方案。

首先,建立一个BST来保存树叶中所需的信息 这其中自我解决了搜索,插入和放大删除要求。
为了解决“删除最近插入的元素”的要求,我们添加到每个叶子prev的结构中。 next字段,所以:

struct leaf
{
    int key;
    INFO_STRUCT info;
}

成为这个:

struct leaf
{
    int key;
    INFO_STRUCT info;
    leaf *prev;
    leaf *next;
}

除持有BST的根外,还要保留leaf *last。每次添加新元素时,它都会指向之前的元素并更新last

注意:此添加仅有助于查找请求的项目,删除本身需要log(n)

已编辑感谢@AlexeiShestakov

答案 1 :(得分:0)

只需要维护一个单独的临时指针,指向最近插入的节点的父元素。该指针可用于删除最近插入的元素。

我希望这可能有所帮助!

答案 2 :(得分:0)

正如您所提到的那样,在O(log n)时间内进行操作 所以可以通过维护 dualLink(biLink) b / w树中的节点和它的对应节点来使用AVL_TREE和双向链表完成链表。

插入会将节点作为mynode插入一个数据,其中键为x,链接(在双链表中引用相应节点为LN)在树 中双链表的对应节点 是一个引用Tree节点的节点,将插入双链表的前面,以便双链表的firstLink变量始终引用最近插入的元素 ::
1.)insert(x)::在AVL树中将密钥作为x插入数据 首先创建一个双向链接节点作为LN
现在树节点作为mynode
现在两个节点之间保持一个双层 2.)delete(x)::用于从树中删除节点
首先在树中找到该节点 现在首先删除该节点引用的doublelyLinked节点和
在树中删除该节点 3.)deleteLast():: For This Simply查找由doublelyLinked List(firstLink)的第一个节点引用的Tree的引用节点。
现在通过调用delete(firstLink.mynode.key)函数删除该节点 4.)search(x)::这很简单。

以上4个操作的时间复杂度在O(Logn)中,因为在doublyLinkedList上执行的所有操作都在O(1)中,并且AVL_TREE在上述操作中总是给出O(Log n)时间成本。

对于AVL_TREE,请从https://github.com/vivekFuneesh/AVL_TREE

下载

希望,这会有所帮助。
另外,我习惯于在java中编码,所以下面的代码是用java语言

class MyClass{
  /* Create first and last reference to double link list */

  static LinkNode firstLink=null,lastLink=null;

  /* Create root of Complete BST i.e. AVL Tree */

  static node rootAVL=null;

  public static void main(String[] arg){

  }

  /*To remove most recently inserted element in O(Log n) ,just delete element referenced by firstLink.myNode*/
  static void deleteLast(){
    if(firstLink==null){System.out.println("EMPTY TREE");}
    else{
      deletenode(firstLink.myNode.key,rootAVL,rootAVL);   
    }

  }


  /* Insert into AVL Tree a node by maintaining a double reference to and fro b/w AVL Tree's node and corresponding doubly linked list node. */
  /* Time Complexity:: O(Log n) */


  static void insert(int key,int data){
    LinkNode LN=new LinkNode();
    node mynode=new node();
    mynode.key=key;
    mynode.data=data;
    mynode.myLink=LN;
    LN.myNode=mynode;
    /* Insert double linklist node at first*/
    /* Time Complexity:: O(1) */
    insertLink(LN);
    /* Now insert mynode in AVL Tree using mynode.key as key. */

  }  

  /* delete node from AVL Tree in Time Cost ::O(Log n)*/


  static void deletenode(int key,node node,node root){
    if(node!=null){
      if(node.key==key){
        /* First remove it's corresponding doublyLinkednode */
        /* Time Complexity:: O(1)*/
        deleteLink(node.myLink);
        /*Now delete this node in Time Complexity:: O(Log n)*/

      }
      else if(key<node.key){
        deletenode(key,node.left,node);
      }
      else{deletenode(key,node.right,node);}
    }
  }


  /* Your delete(x) function in O(Log n) */
  static void delete(int key){
    if(rootAVL!=null){
      node MYNODE=null;
      /* First find that node with key as key then::delete doublylinked node corresponding to that node then:: delete that. */
      deletenode(key,rootAVL,rootAVL);
    }
    else System.out.println("EMPTY_TREE");
  }


  /* Delete LinkNode ln in Time Cost Of O(1) */


  static void deleteLink(LinkNode ln){
    if(firstLink==null){
      System.out.println("ERROR");System.exit(1);
    }
    else{
      if(firstLink==lastLink){  
        firstLink.myNode=null;  
        firstLink=lastLink=null;
      }
      else if(ln==lastLink){
        ln.left.right=null;
        ln.myNode=null;
        lastLink=ln.left;
        ln.left=null;
      }
      else if(ln==firstLink){
        firstLink.right.left=null;
        firstLink.myNode=null;
        firstLink=firstLink.right;
        firstLink.right=null;
      }
      else{
        ln.left.right=ln.right;
        ln.right.left=ln.left;
        ln.right=ln.left=null;
      }
    }
  }
  /*Insert at First in O(1) so that recently inserted element will always be referenced by  variable firstLink */


  static void insertLink(LinkNode ln){
    if(firstLink==null){
      lastLink=firstLink=ln;
    }
    else{
      firstLink.left=ln;
      ln.right=firstLink;
      firstLink=ln;
    }
  }

}  

AVL_TREE节点的数据结构

/* An AVL_TREE Node */

class node{
  int key=0;
  int data=0;
  int height=0;/* For maintaining height in AVL Tree*/
  node left=null,right=null;
  LinkNode myLink=null;
}  

双链接列表节点的数据结构

/* A double LinkList node */  
class LinkNode{
  LinkNode left=null,right=null;
  node myNode=null;
}