实现在J2ME中解压缩ZIP文件

实现在J2ME中解压缩ZIP文件   -- 未审核 编辑文档
     超级短小精悍的ZIP解压缩类,只有280行Java代码,混淆并压缩后的class文件仅4K左右,特别适用于j2me开发。

     解压缩算法来自网上那个著名的GZIP.java,只添加了解析ZIP文件格式的部分。

list()方法:
 

    列出zip包中所有的文件及目录,列出的是包括路径的全名,比如文件"dir1/dir2/file.txt",或目录"dir1/dir2/",注意路径分隔符是正斜杠'/',目录的最后一个字符一定是'/'。
get(String filename)方法:
 

    从zip包中解压缩给定名字的文件,返回字节数组。
ZipMe(InputStream is):
 

    从一个输入流读取zip文件,可以是jar包中的文件,也可以是通过FileConnection获取的手机文件系统中的文件,或从网络上下载的zip包。

下面的例子代码访问jar包中的zip文件并逐一解压缩包中的所有文件:

1. InputStream is = "".getClass().getResourceAsStream("/res/test.zip"); 
2.        ZipMe file = new ZipMe(is);
3.        is.close();
4.        Vector p = file.list();
5.        for (int i = 0; i < p.size(); i++) {
6.            String name = (String) p.get(i);
7.            byte[] bb = file.get(name);
8.            System.out.println("file: " + name + " / data_len: " + (bb != null ? bb.length : -1));
9.        }
10. 
11. 
12. 
13. ====================================================
14. package net.cnjm.j2me.utils;
15. 
16. import java.io.*;
17. import java.util.*;
18. 
19. public class ZipMe {
20. 
21.    private static final int BTYPE_NONE = 0;
22.    private static final int BTYPE_DYNAMIC = 2;
23.    private static final int MAX_BITS = 16;
24.    private static final int MAX_CODE_LITERALS = 287;
25.    private static final int MAX_CODE_DISTANCES = 31;
26.    private static final int MAX_CODE_LENGTHS = 18;
27.    private static final int EOB_CODE = 256;
28. 
29.    private static final int LENGTH_EXTRA_BITS[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,
30.            1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 };
31.    private static final int LENGTH_VALUES[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11,
32.            13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131,
33.            163, 195, 227, 258, 0, 0 };
34.    private static final int DISTANCE_EXTRA_BITS[] = { 0, 0, 0, 0, 1, 1, 2, 2,
35.            3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
36.            13, 13 };
37.    private static final int DISTANCE_VALUES[] = { 1, 2, 3, 4, 5, 7, 9, 13, 17,
38.            25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049,
39.            3073, 4097, 6145, 8193, 12289, 16385, 24577 };
40.    private static final int DYNAMIC_LENGTH_ORDER[] = { 16, 17, 18, 0, 8, 7, 9,
41.            6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
42. 
43.    private int curIndex, curByte, curBit;
44. 
45.    public final  byte[] inflate(byte data[], int startIdx, int size) {
46.        curIndex = startIdx;
47.        byte ret[] = new byte[size];
48.        int idx, bfinal, btype;
49.        idx = bfinal = btype = curByte = curBit = 0;
50.        do {
51.            bfinal = readBits(data, 1);
52.            btype = readBits(data, 2);
53.            if (btype == BTYPE_NONE) {
54.                curBit = 0;
55.                // LEN.
56.                int len = readBits(data, 16);
57.                // NLEN.
58.                readBits(data, 16);
59.                System.arraycopy(data, curIndex, ret, idx, len);
60.                curIndex += len;
61.                idx += len;
62.            } else {
63.                int literalTree[], distanceTree[];
64.                if (btype == BTYPE_DYNAMIC) {
65.                    int hlit = readBits(data, 5) + 257;
66.                    int hdist = readBits(data, 5) + 1;
67.                    int hclen = readBits(data, 4) + 4;
68.                    byte lengthBits[] = new byte[MAX_CODE_LENGTHS + 1];
69.                    for (int i = 0; i < hclen; i++)
70.                        lengthBits[DYNAMIC_LENGTH_ORDER[i]] = (byte) readBits(data, 3);
71.                    int lengthTree[] = huffmanTree(lengthBits, MAX_CODE_LENGTHS);
72.                    literalTree = huffmanTree(codeLengths(data,
73.                            lengthTree, hlit), hlit - 1);
74.                    distanceTree = huffmanTree(codeLengths(data,
75.                            lengthTree, hdist), hdist - 1);
76.                } else {
77.                    byte literalBits[] = new byte[MAX_CODE_LITERALS + 1];
78.                    for (int i = 144; --i >= 0; literalBits[i] = 8);
79.                    for (int i = 256; --i >= 144; literalBits[i] = 9);
80.                    for (int i = 280; --i >= 256; literalBits[i] = 7);
81.                    for (int i = 288; --i >= 280; literalBits[i] = 8);
82.                    literalTree = huffmanTree(literalBits, MAX_CODE_LITERALS);
83. 
84.                    byte distanceBits[] = new byte[MAX_CODE_DISTANCES + 1];
85.                    for (int i = distanceBits.length; --i >= 0; distanceBits[i] = 5);
86.                    distanceTree = huffmanTree(distanceBits, MAX_CODE_DISTANCES);
87.                }
88.                int code = 0, leb = 0, deb = 0;
89.                while ((code = readCode(data, literalTree)) != EOB_CODE) {
90.                    if (code > EOB_CODE) {
91.                        code -= 257;
92.                        int length = LENGTH_VALUES[code];
93.                        if ((leb = LENGTH_EXTRA_BITS[code]) > 0)
94.                            length += readBits(data, leb);
95.                        code = readCode(data, distanceTree);
96.                        int distance = DISTANCE_VALUES[code];
97.                        if ((deb = DISTANCE_EXTRA_BITS[code]) > 0)
98.                            distance += readBits(data, deb);
99.                        int offset = idx - distance;
100.                        while (distance < length) {
101.                            System.arraycopy(ret, offset, ret, idx, distance);
102.                            idx += distance;
103.                            length -= distance;
104.                            distance <<= 1;
105.                        }
106.                        System.arraycopy(ret, offset, ret, idx, length);
107.                        idx += length;
108.                    } else {
109.                        ret[idx++] = (byte) code;
110.                    }
111.                }
112.            }
113.        } while (bfinal == 0);
114.        return ret;
115.    }
116. 
117.    private final int readBits(byte bb[], int n) {
118.        int data = (curBit == 0 ? (curByte = (bb[curIndex++] & 0xFF))
119.                : (curByte >> curBit));
120.        for (int i = (8 - curBit); i < n; i += 8) {
121.            curByte = (bb[curIndex++] & 0xFF);
122.            data |= (curByte << i);
123.        }
124.        curBit = (curBit + n) & 7;
125.        return (data & ((1 << n) - 1));
126.    }
127. 
128.    private final int readCode(byte bb[], int tree[]) {
129.        int node = tree[0];
130.        while (node >= 0) {
131.            if (curBit == 0) curByte = (bb[curIndex++] & 0xFF);
132.            node = (((curByte & (1 << curBit)) == 0) ? tree[node >> 16]
133.                    : tree[node & 0xFFFF]);
134.            curBit = (curBit + 1) & 7;
135.        }
136.        return (node & 0xFFFF);
137.    }
138. 
139.    private final byte[] codeLengths(byte bb[], int lentree[], int count) {
140.        byte bits[] = new byte[count];
141.        for (int i = 0, code = 0, last = 0; i < count;) {
142.            code = readCode(bb, lentree);
143.            if (code >= 16) {
144.                int repeat = 0;
145.                if (code == 16) {
146.                    repeat = 3 + readBits(bb, 2);
147.                    code = last;
148.                } else {
149.                    if (code == 17)
150.                        repeat = 3 + readBits(bb, 3);
151.                    else
152.                        repeat = 11 + readBits(bb, 7);
153.                    code = 0;
154.                }
155.                while (repeat-- > 0)
156.                    bits[i++] = (byte) code;
157.            } else {
158.                bits[i++] = (byte) code;
159.            }
160.            last = code;
161.        }
162.        return bits;
163.    }
164. 
165.    private final static int[] huffmanTree(byte bits[], int maxCode) {
166.        int bl_count[] = new int[MAX_BITS + 1];
167.        for (int i = 0, n = bits.length; i < n; i++)
168.            bl_count[bits[i]]++;
169.        int code = 0;
170.        bl_count[0] = 0;
171.        int next_code[] = new int[MAX_BITS + 1];
172.        for (int i = 1; i <= MAX_BITS; i++)
173.            next_code[i] = code = (code + bl_count[i - 1]) << 1;
174.        int tree[] = new int[(maxCode << 1) + MAX_BITS];
175.        int treeInsert = 1;
176.        for (int i = 0; i <= maxCode; i++) {
177.            int len = bits[i];
178.            if (len != 0) {
179.                code = next_code[len]++;
180.                int node = 0;
181.                for (int bit = len - 1; bit >= 0; bit--) {
182.                    int value = code & (1 << bit);
183.                    if (value == 0) {
184.                        int left = tree[node] >> 16;
185.                        if (left == 0) {
186.                            tree[node] |= (treeInsert << 16);
187.                            node = treeInsert++;
188.                        } else
189.                            node = left;
190.                    } else {
191.                        int right = tree[node] & 0xFFFF;
192.                        if (right == 0) {
193.                            tree[node] |= treeInsert;
194.                            node = treeInsert++;
195.                        } else
196.                            node = right;
197.                    }
198.                }
199.                tree[node] = 0x80000000 | i;
200.            }
201.        }
202.        return tree;
203.    }
204.    
205.    private byte[] data;
206.    
207.    private Hashtable htToc;
208.    
209.    public ZipMe(byte[] data) {
210.        reset(data);
211.    }
212.    
213.    public ZipMe(InputStream is) throws IOException {
214.        byte[] bb = inputStreamToBytes(is);
215.        reset(bb);
216.    }
217.    
218.    public final ZipMe reset(byte[] data) {
219.        this.data = data;
220.        htToc = null;
221.        return this;
222.    }
223.    
224.    public final Vector list() {
225.        Hashtable toc;
226.        if ((toc = htToc) == null) {
227.            toc = htToc = new Hashtable();
228.            int offset, i;
229.            offset = i = 0;
230.            for (;;) {
231.                int n = read(data, offset, 4);
232.                if (n != 0x04034B50) break; // end of data section
233.                offset += 8; // header,pkware_ver,global_flag
234.                int method = read(data, offset, 2);
235.                offset += 10; // method,date,time,crc
236.                int size = read(data, offset, 4);
237.                offset += 4; // compressed_size
238.                int orisize = read(data, offset, 4);
239.                offset += 4; // original_size
240.                int filenamelen = read(data, offset, 2);
241.                offset += 2;
242.                int extlen = read(data, offset, 2);
243.                offset += 2;
244.                String filename = new String(data, offset, filenamelen);
245.                offset += filenamelen + extlen;
246.                toc.put(filename, new int[] { offset, size, orisize, method, i++ } );
247.                offset += size;
248.            }
249.        }
250.        Vector ret = new Vector(toc.size());
251.        for (Enumeration e = toc.keys(); e.hasMoreElements();) {
252.            String filename = (String) e.nextElement();
253.            ret.add(filename);
254.        }
255.        return ret;
256.    }
257.    
258.    public final byte[] get(String name) {
259.        if (htToc == null) list();
260.        int[] info = (int[]) htToc.get(name);
261.        if (info == null) return null;
262.        if (info[1] == 0) return new byte[0];
263.        if (info[3] == 0) { // store
264.            byte[] ret = new byte[info[2]];
265.            System.arraycopy(data, info[0], ret, 0, info[2]);
266.            return ret;
267.        } else if (info[3] == 8) { // deflate
268.            byte[] ret = inflate(data, info[0], info[2]);
269.            return ret;
270.        }
271.        return null;
272.    }
273.    
274.    private static final int read(byte[] data, int offset, int len) {
275.        int ret = 0;
276.        for (int i = offset, j = 0, n = offset + len; i < n; i++, j += 8) {
277.            ret |= ((data[i] & 0xff) << j);
278.        }
279.        return ret;
280.    }
281.    
282.    private static final byte[] inputStreamToBytes(InputStream is) throws IOException {
283.        ByteArrayOutputStream bos = new ByteArrayOutputStream();
284.        byte[] bb = new byte[10000];
285.        for (int len = is.read(bb); len > 0; len = is.read(bb)) {
286.            bos.write(bb, 0, len);
287.        }
288.        return bos.toByteArray();
289.    }
290.    

 

/*
 * GZIP library for j2me applications.
 *
 * Copyright (c) 2004-2006 Carlos Araiz (caraiz@java4ever.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package com.java4ever.apime.io;

import java.io.*;

/**
 * Clase que permite leer ficheros GZIP.
 *
 * @author Carlos Araiz
 *
 * @version 1.2.0
 */
public class GZIP
{
 // M醩caras para el flag.
 private static final int FTEXT_MASK  = 1;
 private static final int FHCRC_MASK  = 2;
 private static final int FEXTRA_MASK = 4;
 private static final int FNAME_MASK  = 8;
 private static final int FCOMMENT_MASK = 16;
 // Tipos de bloques.
 private static final int BTYPE_NONE  = 0;
 private static final int BTYPE_FIXED = 1;
 private static final int BTYPE_DYNAMIC = 2;
 private static final int BTYPE_RESERVED = 3;
 // L韒ites.
 private static final int MAX_BITS   = 16;
 private static final int MAX_CODE_LITERALS = 287;
 private static final int MAX_CODE_DISTANCES = 31;
 private static final int MAX_CODE_LENGTHS = 18;
 private static final int EOB_CODE   = 256;
 // Datos prefijados (LENGTH: 257..287 / DISTANCE: 0..29 / DYNAMIC_LENGTH_ORDER: 0..18).
 private static final int LENGTH_EXTRA_BITS[]    = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99};
 private static final int LENGTH_VALUES[]        = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0};
 private static final int DISTANCE_EXTRA_BITS[]  = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
 private static final int DISTANCE_VALUES[]      = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
 private static final int DYNAMIC_LENGTH_ORDER[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};

 /*************************************************************************/

 // Variables para la lectura de datos comprimidos.
 private static int gzipIndex,gzipByte,gzipBit;

 /*************************************************************************/
 /*************************************************************************/

 /**
  * Descomprime un fichero GZIP.
  *
  * @param gzip Array con los datos del fichero comprimido
  *
  * @return Array con los datos descomprimidos
  */
 public static byte[] inflate(byte gzip[]) throws IOException
 {
  // Inicializa.
  gzipIndex=gzipByte=gzipBit=0;
  // Cabecera.
  if (readBits(gzip,16)!=0x8B1F||readBits(gzip,8)!=8) throw new IOException("Invalid GZIP format");
  // Flag.
  int flg=readBits(gzip,8);
  // Fecha(4) / XFL(1) / OS(1).
  gzipIndex+=6;
  // Comprueba los flags.
  if ((flg&FEXTRA_MASK)!=0) gzipIndex+=readBits(gzip,16);
  if ((flg&FNAME_MASK)!=0) while (gzip[gzipIndex++]!=0);
  if ((flg&FCOMMENT_MASK)!=0) while (gzip[gzipIndex++]!=0);
  if ((flg&FHCRC_MASK)!=0) gzipIndex+=2;
  // Tama駉 de los datos descomprimidos.
  int index=gzipIndex;
  gzipIndex=gzip.length-4;
  byte uncompressed[]=new byte[readBits(gzip,16)|(readBits(gzip,16)<<16)];
  int uncompressedIndex=0;
  gzipIndex=index;
  // Bloque con datos comprimidos.
  int bfinal=0,btype=0;
  do
  {
   // Lee la cabecera del bloque.
   bfinal=readBits(gzip,1);
   btype=readBits(gzip,2);
   // Comprueba el tipo de compresi髇.
   if (btype==BTYPE_NONE)
   {
    // Ignora los bits dentro del byte actual.
    gzipBit=0;
    // LEN.
    int len=readBits(gzip,16);
    // NLEN.
    int nlen=readBits(gzip,16);
    // Lee los datos.
    System.arraycopy(gzip,gzipIndex,uncompressed,uncompressedIndex,len);
    gzipIndex+=len;
    // Actualiza el 韓dice de los datos descomprimidos.
    uncompressedIndex+=len;
   }
   else
   {
    int literalTree[],distanceTree[];
    if (btype==BTYPE_DYNAMIC)
    {
     // N鷐ero de datos de cada tipo.
     int hlit=readBits(gzip,5)+257;
     int hdist=readBits(gzip,5)+1;
     int hclen=readBits(gzip,4)+4;
     // Lee el n鷐ero de bits para cada c骴igo de longitud.
     byte lengthBits[]=new byte[MAX_CODE_LENGTHS+1];
     for (int i=0;i<hclen;i++) lengthBits[DYNAMIC_LENGTH_ORDER[i]]=(byte)readBits(gzip,3);
     // Crea los c骴igos para la longitud.
     int lengthTree[]=createHuffmanTree(lengthBits,MAX_CODE_LENGTHS);
     // Genera los 醨boles.
     literalTree=createHuffmanTree(decodeCodeLengths(gzip,lengthTree,hlit),hlit-1);
     distanceTree=createHuffmanTree(decodeCodeLengths(gzip,lengthTree,hdist),hdist-1);
    }
    else
    {
     byte literalBits[]=new byte[MAX_CODE_LITERALS+1];
     for (int i=0;i<144;i++) literalBits[i]=8;
     for (int i=144;i<256;i++) literalBits[i]=9;
     for (int i=256;i<280;i++) literalBits[i]=7;
     for (int i=280;i<288;i++) literalBits[i]=8;
     literalTree=createHuffmanTree(literalBits,MAX_CODE_LITERALS);
     //
     byte distanceBits[]=new byte[MAX_CODE_DISTANCES+1];
     for (int i=0;i<distanceBits.length;i++) distanceBits[i]=5;
     distanceTree=createHuffmanTree(distanceBits,MAX_CODE_DISTANCES);
    }
    // Descomprime el bloque.
    int code=0,leb=0,deb=0;
    while ((code=readCode(gzip,literalTree))!=EOB_CODE)
    {
     if (code>EOB_CODE)
     {
      code-=257;
      int length=LENGTH_VALUES[code];
      if ((leb=LENGTH_EXTRA_BITS[code])>0) length+=readBits(gzip,leb);
      code=readCode(gzip,distanceTree);
      int distance=DISTANCE_VALUES[code];
      if ((deb=DISTANCE_EXTRA_BITS[code])>0) distance+=readBits(gzip,deb);
      // Repite la informaci髇.
      int offset=uncompressedIndex-distance;
      while (distance<length)
      {
       System.arraycopy(uncompressed,offset,uncompressed,uncompressedIndex,distance);
       uncompressedIndex+=distance;
       length-=distance;
       distance<<=1;
      }
      System.arraycopy(uncompressed,offset,uncompressed,uncompressedIndex,length);
      uncompressedIndex+=length;
     }
     else uncompressed[uncompressedIndex++]=(byte)code;
    }
   }
  }
  while (bfinal==0);
  //
  return uncompressed;
 }

 /**
  * Lee un n鷐ero de bits
  *
  * @param n N鷐ero de bits [0..16]
  */
 private static int readBits(byte gzip[],int n)
 {
  // Asegura que tenemos un byte.
  int data=(gzipBit==0?(gzipByte=(gzip[gzipIndex++]&0xFF)):(gzipByte>>gzipBit));
  // Lee hasta completar los bits.
  for (int i=(8-gzipBit);i<n;i+=8)
  {
   gzipByte=(gzip[gzipIndex++]&0xFF);
   data|=(gzipByte<<i);
  }
  // Ajusta la posici髇 actual.
  gzipBit=(gzipBit+n)&7;
  // Devuelve el dato.
  return (data&((1<<n)-1));
 }

 /**
  * Lee un c骴igo.
  */
 private static int readCode(byte gzip[],int tree[])
 {
  int node=tree[0];
  while (node>=0)
  {
   // Lee un byte si es necesario.
   if (gzipBit==0) gzipByte=(gzip[gzipIndex++]&0xFF);
   // Accede al nodo correspondiente.
   node=(((gzipByte&(1<<gzipBit))==0)?tree[node>>16]:tree[node&0xFFFF]);
   // Ajusta la posici髇 actual.
   gzipBit=(gzipBit+1)&7;
  }
  return (node&0xFFFF);
 }

 /**
  * Decodifica la longitud de c骴igos (usado en bloques comprimidos con c骴igos din醡icos).
  */
 private static byte[] decodeCodeLengths(byte gzip[],int lengthTree[],int count)
 {
  byte bits[]=new byte[count];
  for (int i=0,code=0,last=0;i<count;)
  {
   code=readCode(gzip,lengthTree);
   if (code>=16)
   {
    int repeat=0;
    if (code==16)
    {
     repeat=3+readBits(gzip,2);
     code=last;
    }
    else
    {
     if (code==17) repeat=3+readBits(gzip,3);
      else repeat=11+readBits(gzip,7);
     code=0;
    }
    while (repeat-->0) bits[i++]=(byte)code;
   }
   else bits[i++]=(byte)code;
   //
   last=code;
  }
  return bits;
 }

 /**
  * Crea el 醨bol para los c骴igos Huffman.
  */
 private static int[] createHuffmanTree(byte bits[],int maxCode)
 {
  // N鷐ero de c骴igos por cada longitud de c骴igo.
  int bl_count[]=new int[MAX_BITS+1];
  for (int i=0;i<bits.length;i++) bl_count[bits[i]]++;
  // M韓imo valor num閞ico del c骴igo para cada longitud de c骴igo.
  int code=0;
  bl_count[0]=0;
  int next_code[]=new int[MAX_BITS+1];
  for (int i=1;i<=MAX_BITS;i++) next_code[i]=code=(code+bl_count[i-1])<<1;
  // Genera el 醨bol.
  // Bit 31 => Nodo (0) o c骴igo (1).
  // (Nodo) bit 16..30 => 韓dice del nodo de la izquierda (0 si no tiene).
  // (Nodo) bit 0..15 => 韓dice del nodo de la derecha (0 si no tiene).
  // (C骴igo) bit 0..15
  int tree[]=new int[(maxCode<<1)+MAX_BITS];
  int treeInsert=1;
  for (int i=0;i<=maxCode;i++)
  {
   int len=bits[i];
   if (len!=0)
   {
    code=next_code[len]++;
    // Lo mete en en 醨bol.
    int node=0;
    for (int bit=len-1;bit>=0;bit--)
    {
     int value=code&(1<<bit);
     // Inserta a la izquierda.
     if (value==0)
     {
      int left=tree[node]>>16;
      if (left==0)
      {
       tree[node]|=(treeInsert<<16);
       node=treeInsert++;
      }
      else node=left;
     }
     // Inserta a la derecha.
     else
     {
      int right=tree[node]&0xFFFF;
      if (right==0)
      {
       tree[node]|=treeInsert;
       node=treeInsert++;
      }
      else node=right;
     }
    }
    // Inserta el c骴igo.
    tree[node]=0x80000000|i;
   }
  }
  return tree;
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值