hash table Insert Delete find constant time sort
�������� hash table • • • Insert Delete find (constant time( sort ������ Findmin findmax �������������� binary search tree
Hash function (1 st example) • ������ ASCII ������� public static int hash(String key, int table. Size){ int hash. Val = 0; for(int i =0; i<key. length(); i++) hash. Val += key. char. At(i); return hash. Val%table. Size; }
Hash function (2 nd example) • ��������������������� • ����������� public static int hash(String key, int table. Size){ return (key. char. At(0) +27*key. char. At(1) +729* key. char. AT(2))%table. Size; } 27*27 ��������������� ��� (10007 �����������
public static int hash(String key, int table. Size){ int hash. Val = 0; for(int i =0; i<key. length(); i++) hash. Val= 37*hash. Val+key. char. At(i); hash. Val %= table. Size; if(hash. Val<0) hash. Val += table. Size; ����� overflow return hash. Val; }
�������� 1. public interface Hashable 2. { 3. /** 4. * Compute a hash function for this object. 5. * @param table. Size the hash table size. 6. * @return (deterministically) a number between 7. * 0 and table. Size-1, distributed equitably. 8. */ 9. int hash( int table. Size ); 10. }
������� Public class Student implements Hashable{ private String name; private double number; private int year; public int hash(int table. Size){ return Separate. Chaining. Hash. Table. hash(name, table. Size); } ������ static method ������� public boolean equals(Object rhs){ return name. equals(((Student)rhs). name); } }
1. public class Separate. Chaining. Hash. Table 2. { 3. /** 4. * Construct the hash table. 5. */ 6. public Separate. Chaining. Hash. Table( ) 7. { 8. this( DEFAULT_TABLE_SIZE ); 9. } 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. /** * Construct the hash table. * @param size approximate table size. */ public Separate. Chaining. Hash. Table( int size ) { the. Lists = new Linked. List[ next. Prime( size ) ]; for( int i = 0; i < the. Lists. length; i++ ) the. Lists[ i ] = new Linked. List( ); }
20. 21. 22. 23. 24. 25. 26. 27. 28. /** * Insert into the hash table. If the item is * already present, then do nothing. * @param x the item to insert. ��� Student ���� */ public void insert( Hashable x ) { Linked. List which. List = the. Lists[ x. hash( the. Lists. length ) ]; Linked. List. Itr itr = which. List. find( x ); 29. 30. 31. } 32. 33. 34. 35. 36. 37. 38. 39. /** * Remove from the hash table. * @param x the item to remove. */ public void remove( Hashable x ) { the. Lists[ x. hash( the. Lists. length ) ]. remove( x ); } if( itr. is. Past. End( ) ) which. List. insert( x, which. List. zeroth( ) );
40. 41. 42. 43. 44. 45. 46. 47. /** * Find an item in the hash table. * @param x the item to search for. * @return the matching item, or null if not found. */ public Hashable find( Hashable x ) { return (Hashable)the. Lists[ x. hash( the. Lists. length ) ]. find( x ). retrieve( ); 48. } 49. 50. 51. 52. 53. 54. 55. 56. /** * Make the hash table logically empty. */ public void make. Empty( ) { for( int i = 0; i < the. Lists. length; i++ ) the. Lists[ i ]. make. Empty( ); }
57. 58. 59. 60. 61. 62. 63. 64. 65. /** * A hash routine for String objects. * @param key the String to hash. * @param table. Size the size of the hash table. * @return the hash value. */ public static int hash( String key, int table. Size ) { int hash. Val = 0; 66. 67. for( int i = 0; i < key. length( ); i++ ) hash. Val = 37 * hash. Val + key. char. At( i ); 68. 69. 70. hash. Val %= table. Size; if( hash. Val < 0 ) hash. Val += table. Size; 71. 72. return hash. Val; }
73. private static final int DEFAULT_TABLE_SIZE = 101; 74. 75. /** The array of Lists. */ private Linked. List [ ] the. Lists; 76. 77. 78. 79. 80. 81. 82. 83. 84. /** * Internal method to find a prime number at least as large as n. * @param n the starting number (must be positive). * @return a prime number larger than or equal to n. */ private static int next. Prime( int n ) { if( n % 2 == 0 ) n++; 85. 86. for( ; !is. Prime( n ); n += 2 ) ; 87. 88. return n; }
89. 90. 91. 92. 93. 94. 95. 96. 97. 98. /** * Internal method to test if a number is prime. * Not an efficient algorithm. * @param n the number to test. * @return the result of the test. */ private static boolean is. Prime( int n ) { if( n == 2 || n == 3 ) return true; 99. 100. if( n == 1 || n % 2 == 0 ) return false; 101. 102. 103. for( int i = 3; i * i <= n; i += 2 ) if( n % i == 0 ) return false; 104. 105. return true; }
106. 107. 108. 109. // Simple main public static void main( String [ ] args ) { Separate. Chaining. Hash. Table H = new Separate. Chaining. Hash. Table( ); 110. 111. final int NUMS = 4000; final int GAP = 37; 112. System. out. println( "Checking. . . (no more output means success)" ); 113. 114. 115. 116. for( int i = GAP; i != 0; i = ( i + GAP ) % NUMS ) H. insert( new My. Integer( i ) ); for( int i = 1; i < NUMS; i+= 2 ) H. remove( new My. Integer( i ) ); 117. 118. 119. for( int i = 2; i < NUMS; i+=2 ) if( ((My. Integer)(H. find( new My. Integer( i ) ))). int. Value( ) != i ) System. out. println( "Find fails " + i ); 120. 121. 122. 123. 124. 125. for( int i = 1; i < NUMS; i+=2 ) { if( H. find( new My. Integer( i ) ) != null ) System. out. println( "OOPS!!! " + i ); } 126. } }
����� • Load factor • ������������ Search time = time to do hashing + time to search list = constant + time to search list • Unsuccessful search Search time = ������ = ��� load factor
Open addressing implementation class Hash. Entry { Hashable element; // the element boolean is. Active; // false is deleted public Hash. Entry( Hashable e ){ this( e, true ); } public Hash. Entry( Hashable e, boolean i ){ element = e; is. Active = i; } }
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. public class Quadratic. Probing. Hash. Table{ private static final int DEFAULT_TABLE_SIZE = 11; /** The array of elements. */ private Hash. Entry [ ] array; // The array of elements private int current. Size; // The number of occupied cells public Quadratic. Probing. Hash. Table( ){ this( DEFAULT_TABLE_SIZE ); } null active nonactive /** * Construct the hash table. * @param size the approximate initial size. */ public Quadratic. Probing. Hash. Table( int size ){ allocate. Array( size ); make. Empty( ); }
18. /** 19. 20. 21. 22. 23. 24. * Internal method to allocate array. * @param array. Size the size of the array. */ private void allocate. Array( int array. Size ){ array = new Hash. Entry[ array. Size ]; } 25. 26. 27. 28. 29. 30. 31. 32. /** * Make the hash table logically empty. */ public void make. Empty( ){ current. Size = 0; for( int i = 0; i < array. length; i++ ) array[ i ] = null; }
33. 34. 35. 36. 37. 38. 39. /** * Return true if current. Pos exists and is active. * @param current. Pos the result of a call to find. Pos. * @return true if current. Pos is active. */ private boolean is. Active( int current. Pos ){ return array[ current. Pos ] != null && array[ current. Pos ]. is. Active; 40. }
41. /** 42. * Method that performs quadratic probing resolution. 43. * @param x the item to search for. 44. * @return the position where the search terminates. 45. */ 46. private int find. Pos( Hashable x ) { f(i)=i 2=f(i-1)+2 i-1 47. /* 1*/ int collision. Num = 0; 48. /* 2*/ int current. Pos = x. hash( array. length ); 49. /* 3*/ while( array[ current. Pos ] != null && 50. !array[ current. Pos ]. element. equals( x ) ){ 51. /* 4*/ current. Pos += 2 * ++collision. Num - 1; // Compute ith probe 52. /* 5*/ if( current. Pos >= array. length ) // Implement the mod 53. /* 6*/ current. Pos -= array. length; 54. } 55. /* 7*/ 56. } return current. Pos;
57. 58. 59. 60. 61. 62. 63. 64. 65. /** * Find an item in the hash table. * @param x the item to search for. * @return the matching item. */ public Hashable find( Hashable x ){ int current. Pos = find. Pos( x ); return is. Active( current. Pos ) ? array[ current. Pos ]. element : null; }
66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. /** * Insert into the hash table. If the item is * already present, do nothing. * @param x the item to insert. */ public void insert( Hashable x ) { // Insert x as active int current. Pos = find. Pos( x ); if( is. Active( current. Pos ) ) return; //x is already inside, so do nothing 77. array[ current. Pos ] = new Hash. Entry( x, true ); 78. 79. 80. 81. // Rehash; see Section 5. 5 if( ++current. Size > array. length / 2 ) rehash( ); }
82. 83. 84. 85. 86. 87. ���� O(N) ������� N /** * Expand the hash table. ����� rehash */ ������� private void rehash( ) 2 N { Hash. Entry [ ] old. Array = array; ������ 88. 89. 90. rehash // Create a new double-sized, empty table ������� allocate. Array( next. Prime( 2 * old. Array. length ) ); ���� current. Size = 0; 91. 92. 93. 94. // Copy table over for( int i = 0; i < old. Array. length; i++ ) if( old. Array[ i ] != null && old. Array[ i ]. is. Active ) insert( old. Array[ i ]. element ); 95. 96. return; } ����� index ��������
97. /** 98. * Remove from the hash table. 99. * @param x the item to remove. 100. */ 101. public void remove( Hashable x ) 102. { 103. int current. Pos = find. Pos( x ); 104. if( is. Active( current. Pos ) ) 105. array[ current. Pos ]. is. Active = false; 106. } hash, next. Prime, is. Prime �����
58 41 26 9 25 42 58������ 13 -(58%1
- Slides: 45