什么是最适合在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不是一个好的解决方案,也告诉我们最适合处理所有四个查询的数据结构。
答案 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;
}