**Reprint Please specify the Source: http://blog.csdn.net/ns_code/article/details/36421085**

Preface

This article does not intend to perpetuate the previous few styles (add gaze to all the source code), because to understand the full source of TreeMap. For bloggers. It really takes a lot of time and experience. It seems unlikely that there will be so much time to spend at the moment. Therefore, it is intended to read the source code on the TreeMap have a macroscopic grasp, and some of the implementation of some of the methods to do a more in-depth analysis.

Red and Black tree Brief introduction

TreeMap is based on red and black trees, here is a simple introduction to the red and black trees, red and black trees is a special two-fork sorting tree. About binary sort tree, see: http://blog.csdn.net/ns_code/article/details/19823463, Red-black tree through some restrictions. It does not appear in the case of extreme one-sided in the two-tree sort tree, which naturally increases the efficiency of the query relative to the binary sort tree.

The basic properties of the binary sort tree are as follows:

1, each node can only be red or black

2, the root node is black

3, each leaf node (nil node, empty node) is black.

4, suppose a knot is red. Then it has two sub-nodes that are black. This means that no adjacent two red nodes can appear on a path.

5. All paths from any node to each of its leaves include the same number of black nodes.

It is these limitations that make the longest path of any node in a red-black tree to its descendants no longer than twice times the shortest path. So it is a nearly balanced two-fork tree.

Speaking of red and black trees. Naturally, you have to compare it with the AVL tree.

Compared. The AVL tree is a strictly balanced binary tree. The red and black trees are not strictly balanced binary trees, just close to the balance, will not let the height of the tree as in the BST extreme situation equal to the number of nodes. In fact, where red and black trees can be used, they can also be implemented with AVL trees, but the application of red and black trees is very extensive, and AVL trees are very rarely used. When you run the INSERT, delete operation, the AVL tree needs to be adjusted more often than the red black tree (red black tree rotation adjustment of up to three times), relatively low efficiency, and red black tree statistical performance than the AVL tree is better, of course, the AVL tree in query efficiency may be better, but in fact, it is not much higher.

The insertion and deletion of red and black trees is very simple. is simply the insert delete operation of the two-fork sort tree. Red black tree is found to be more abnormal place naturally lies in the removal of the red and black trees after the adjustment operation (rotation and coloring), mainly the situation is very much, limited to the length and the master's familiarity is preferred, here is not intended to specifically introduce the removal of the red and black tree after the various circumstances and in fact, we have a macro on the understanding If you need to know specifically. Refer to the introduction of the algorithm or some related information.

treemap Source Code anatomyStorage Structure

The sort of treemap is based on the ordering of key, and each of its entry represents a node of the red and black tree, and the data structure of entry such as the following:

Static Final class Entry<k,v> implements map.entry<k,v> { //key K key; Value V value; Left child entry<k,v> = null; Right child entry<k,v> = null; Parent node entry<k,v>; Current node Color boolean color = BLACK; Constructor Entry (K key, V value, entry<k,v> parent) { This.key = key; This.value = value; This.parent = parent; } .。。。

。

。

}

Construction Method

Let's look at the construction method of TreeMap. TreeMap has 4 construction methods in common.

1, no-participation construction method

Public TreeMap () { comparator = null; }

using the No-reference construction method, do not specify the comparison device, at this time , the implementation of the order depends on the Key.compareto () method, so key must implement the comparable interface. and overwrite the CompareTo method.

2, the construction method with the comparison device

Public TreeMap (COMPARATOR<? Super K> Comparator) { this.comparator = Comparator; }

the construction method of the belt-comparison device is used. The sort depends on the comparison device. Key can not implement comparable interface.

3, with map of the construction method

Public TreeMap (map<? extends K,? extends v> m) { comparator = null; Putall (m); }

The constructor method does not specify a comparison, and calls the Putall method to add all the elements in the map to the TreeMap.

The source code for Putall is as follows:

Add all nodes in Map to treemap public void Putall (MAP<?Extends K,?

Extends v> map) {//Get map size int mapsize = Map.size (); Suppose the size of the TreeMap is 0, and the map size is not 0, and map is a sorted "Key-value pair" if (size==0 && mapsize!=0 && map instanceof So Rtedmap) {Comparator c = ((SortedMap) map). Comparator (); Suppose the treemap is equal to the map's, and/or copy all the elements of the map to TreeMap and return!

if (c = = Comparator | | (c! = null && c.equals (comparator))) {++modcount; try {buildfromsorted (mapsize, Map.entryset (). iterator (), NULL, NULL ); } catch (Java.io.IOException Cannothappen) {} catch (ClassNotFoundException Cannothappen) { } return; }}//Call Putall () in Abstractmap; The Putall () in Abstractmap also calls to TreeMap put () Super.putall (map); }

Obviously, suppose the elements in the map are in order. Call the buildfromsorted method to copy the elements in the map, which is highlighted in the next construction method, and if the elements in the map are not ordered, call the Abstractmap Putall (map) method. The method source code such as the following:

public void Putall (map<? extends K,?Extends v> m) { for (map.entry<? extends K,?

Extends V> e:m.entryset ()) put (E.getkey (), E.getvalue ());

It is very obvious that the elements in the map are put (inserted) into TreeMap. The main reason is that the elements in the map are stored in disorder. So insert them into the red and black trees. Keep it in order. and satisfies the nature of the red-black tree.

4. Construction method with SortedMap

Public TreeMap (Sortedmap<k,?Extends v> m) { comparator = M.comparator (); try { buildfromsorted (m.size (), M.entryset (). iterator (), NULL, NULL), } catch (java.io.IOException Cannothappen) { } catch (ClassNotFoundException Cannothappen) { } }

The comparison is first specified as M, depending on whether the constructor was called when the build method was generated, and then called the buildfromsorted method to insert elements from the SortedMap into TreeMap. Because the elements in the SortedMap are ordered, in fact it is the treemap created from the SortedMap, and the corresponding elements in the SortedMap are added to the treemap.

Insert Delete

Insert operation is the corresponding TreeMap put method, put operation in fact only need to follow the binary sorting tree insert step to operate, insert into the specified position, and then make adjustments to keep the red and black tree characteristics. The implementation of the put source code:

Public V put (K key, V value) {entry<k,v> t = root; If the red and black tree is empty, insert the root node if (t = = null) {//TBD:///5045147: (coll) Adding null to an empty TreeSet sh Ould//Throw NullPointerException/////Compare (key, key); Type check root = new Entry<k,v> (key, value, NULL); size = 1; modcount++; return null; } int cmp; Entry<k,v> parent; Split comparator and comparable paths comparator<? Super k> CPR = comparator; Find the insertion position (key, value) in the binary sort tree.The

//red-black tree is sorted by key, so it is searched by key. if (CPR = null) {do {parent = t; CMP = Cpr.compare (key, T.key); if (CMP < 0) T = t.left; else if (cmp > 0) t = t.right; else return T.setvalue (value); } while (t! = null); } else {if (key = = null) throw new NullPointerException (); comparable<? Super k> K = (comparable<?

Super k>) key; do {parent = t; CMP = K.compareto (T.key); if (CMP < 0) T = t.left; else if (cmp > 0) t = t.right; else return T.setvalue (value); } while (t! = null); }//For (Key-value) new node entry<k,v> e = new entry<k,v> (key, value, parent); if (CMP < 0) Parent.left = e; else Parent.right = e; After the new node is inserted. Call Fixafterinsertion to adjust the red-black tree.

Fixafterinsertion (e); size++; modcount++; return null; }

The fixafterinsertion here is the method of adjusting the tree after the node is inserted. No introduction is made here.

Delete operation and the corresponding TreeMap DeleteEntry method, the DeleteEntry method is the same only need to follow the binary sorting tree operation step Implementation can, delete the specified node, and then adjust the tree can be.

The implementation of the DeleteEntry method source code such as the following:

Delete "Red black tree node P" private void DeleteEntry (Entry<k,v> p) {modcount++; size--; if (P.left = null && p.right! = null) {entry<k,v> s = successor (p); P.key = S.key; P.value = S.value; p = s; } entry<k,v> replacement = (P.left! = null?) P.left:p.right); if (replacement! = null) {replacement.parent = p.parent; if (p.parent = = null) root = replacement; else if (p = = p.parent.left) P.parent.left = replacement; else p.parent.right = replacement; P.left = P.right = P.parent = null; if (P.color = = BLACK) fixafterdeletion (replacement); } else if (p.parent = = null) {root = null; } else {if (P.color = = BLACK) fixafterdeletion (p); if (p.parent! = null) {if (p = = p.parent.left) P.parent.left = null; else if (p = = p.parent.right) P.parent.right = null; P.parent = null; } } }

The following Fixafterdeletion method is the method of adjusting the tree after the node is deleted, and this is not introduced here.

Many other methods are not introduced here.

some summary

This article on the analysis of TreeMap a little bit more than the previous articles, treemap with no hashmap so much. We have a macro to compare me and compare it.

1, TreeMap is based on key to sort, its ordering and positioning need to rely on the comparison or overwrite comparable interface. It also eliminates the need for key to overwrite the Hashcode method and the Equals method to eliminate the repeated key. The key of HashMap is to ensure that there are no repeated keys by covering the Hashcode method and the Equals method.

2, TreeMap query, insert, delete efficiency are not hashmap high, generally only have to sort key to use TreeMap.

3. TreeMap key cannot be null, and HashMap key can be null.

Note: The source code for TreeSet and HashSet is no longer parsed, both of which are based on TreeMap and HASHMAP implementations. Only the corresponding node has only the key. Without value, the understanding of TreeMap and HashMap would be very easy for treeset and HashSet.

Anatomy of the "Java Collection source code" TREEMAP source code