SPLAY

来源:互联网 发布:vivo软件商店手机版 编辑:程序博客网 时间:2024/04/18 12:05
program splay_tree;
var     i,j,k,x,root,totnode,l,r,n:longint;        father,count,data:array[0..100]of longint;        sons:array[0..100,1..2]of longint;        st:longint;procedure rotate(x,w:longint);var     y,z:longint;begin        y:=father[x];        z:=count[y];        count[y]:=count[y]-count[x]+count[sons[x,w]];        count[x]:=z;        sons[y,3-w]:=sons[x,w];        if sons[x,w]<>0 then         father[sons[x,w]]:=y;        father[x]:=father[y];        if father[y]<>0 then         if y=sons[father[y],1] then sons[father[y],1]:=x else          sons[father[y],2]:=x;        father[y]:=x;        sons[x,w]:=y;end;procedure splay(x,y:longint);var     p,q:longint;begin        while father[x]<>0 do        begin         if father[father[x]]=y then          if x=sons[father[x],1] then rotate(x,2) else rotate(x,1)         else         begin          if father[x]=sons[father[father[x]],1] then q:=1 else q:=2;          if x=sons[father[x],1] then p:=1 else p:=2;          if p=q then           begin rotate(father[x],3-q);rotate(x,3-p);end          else           begin rotate(x,3-p);rotate(x,3-q);end         end;        end;        if y=0 then root:=x;end;procedure insert(v:longint);var     x:longint;begin        x:=root;        while x<>0 do        begin         count[x]:=count[x]+1;         if v<data[x] then if sons[x,1]=0 then break else x:=sons[x,1]                      else if sons[x,2]=0 then break else x:=sons[x,2];        end;        inc(totnode);        data[totnode]:=v;        father[totnode]:=x;        count[totnode]:=1;        if v<data[x] then sons[x,1]:=totnode else sons[x,2]:=totnode;        splay(totnode,0);end;procedure delete(x:longint);var     y:longint;begin        splay(x,0);        if sons[x,1]=0 then        begin         root:=sons[x,2];         father[sons[x,2]]:=0;        end        else        begin         y:=sons[x,1];         while sons[y,2]<>0 do          y:=sons[y,2];         splay(y,sons[x,1]);         root:=y;         father[y]:=0;         sons[y,2]:=sons[x,2];         count[y]:=count[y]+count[sons[x,2]];         if sons[x,2]<>0 then father[sons[x,2]]:=y;        end;end;function find(v:longint):longint;var     x:longint;begin        x:=root;        while x<>0 do         if v<data[x] then          x:=sons[x,1]         else          if v>data[x] then           x:=sons[x,2]          else           break;        splay(x,0);end;function rank(v:longint):longint;var     x:longint;begin        x:=find(v);        splay(x,0);        rank:=count[sons[x,1]]+1;end;function get(v:longint):longint;var     x:longint;begin        x:=root;        while v<>count[sons[x,1]]+1 do        if v<=count[sons[x,1]] then x:=sons[x,1]         else         begin          v:=v-count[sons[x,1]]-1;          x:=sons[x,2];         end;        splay(x,0);        get:=count[sons[x,1]]+1;end;procedure deleteline(l,r:longint);var       x,y,z:longint;begin        splay(l,0);        y:=sons[l,1];        while sons[y,2]<>0 do         y:=sons[y,2];        splay(r,0);        z:=sons[r,2];        while sons[z,1]<>0 do         z:=sons[z,1];        splay(y,0);        splay(z,y);        count[z]:=count[z]-count[sons[z,1]];        count[y]:=count[y]-count[sons[z,1]];        sons[z,1]:=0;end;begin        assign(input,'splay.in');        reset(input);        readln(n);        for i:=1 to n do        begin         readln(st);         case st of          1:begin readln(x);insert(x);end;          2:begin readln(x);delete(find(x));end;          3:begin readln(x);writeln(rank(x));end;          4:begin readln(x);writeln(get(x));end;          5:begin readln(l,r);deleteline(l,r);end;         end;        end;        close(input);end.       

各种过程的解释:

1.ROTATE(X,W) 表示将X节点左旋或者右旋,w=1时左旋,w=2时右旋。

2.SPLAY(X)         表示将X节点进行伸展。

3.INSERT(X)       表示插入一个值为X的节点。

4.DELETE(X)      表示删除X节点。

5.FIND(X)            表示找到值为X的点。

6.RANK(X)          表示X的排名。

7.GET(X)             表示找到第X小数。

8.DELETELINE(X)表示删除标号在L,R内的所有数。

原创粉丝点击