Theoretical Computer Science 556 (2014) 25–33
Contents lists available at ScienceDirect
Theoretical Computer Science www.elsevier.com/locate/tcs
A loopless algorithm for generating multiple binary tree sequences simultaneously ✩ Ro-Yu Wu a , Jou-Ming Chang b,∗ , Hung-Chang Chan c , Kung-Jui Pai d a
Department of Industrial Management, Lunghwa University of Science and Technology, Taoyuan, Taiwan Institute of Information and Decision Sciences, National Taipei University of Business, Taipei, Taiwan Department of Computer Science and Information Engineering, Yuanpei University, Hsinchu, Taiwan d Department of Industrial Engineering and Management, Ming Chi University of Technology, New Taipei City, Taiwan b c
a r t i c l e
i n f o
Article history: Received 23 February 2014 Received in revised form 12 June 2014 Accepted 31 July 2014 Available online 22 August 2014 Keywords: Binary trees Loopless generating algorithms Gray-code order Constant amortized time
a b s t r a c t Pallo and Wu et al. respectively introduced the left-weight sequences (LW-sequences) and right-weight sequences (RW-sequences) for representing binary trees. In this paper, we introduce two new types of binary tree sequences called the left-child sequences (LC-sequences) and right-child sequences (RC-sequences). Next, we propose a loopless algorithm associated with rotations of binary trees for generating LW-, RW-, LC-, and RCsequences simultaneously. Moreover, we show that LW- and RW-sequences are generated in Gray-code order, and LC- and RC-sequences are generated so that each sequence can be obtained from its predecessor by changing at most two digits. Our algorithm is shown to be more efficient in both space and time than the existing known algorithms. © 2014 Published by Elsevier B.V.
1. Introduction Combinatorial objects are usually encoded by integer sequences and are generated in a particular order. Since a large amount of objects need to be generated, the design of efficient generating schemes are necessary. Ehrlich [1] defined that an algorithm for generating objects is a loopless generating algorithm provided the computation of changing one object into the next one only takes a constant time. In particular, if the change between two successive objects is limited by only one integer, the generation results in a Gray-code order. Loopless algorithms for generating binary trees [6,8,11–13,18] and their generalization called k-ary trees [2–4,9,19] have attracted a great deal of attention. In these literatures, some of generating schemes are based on tree rotations [2–4,6,8,12]. Although many types of integer sequences have been introduced to encode binary trees, the so-called left-weight sequences (LW-sequences) are the most common type of adoption [7]. For generating LW-sequences of binary trees, Pallo [7] has proposed a constant amortized time (CAT for short) algorithm that generates sequences in lexicographic order. Shortly afterwards, van Baronaigien and Ruskey [10] designed a recursive CAT algorithm that generates LW-sequences in a Graycode order. Roughly a decade later, Vajnovszki [12] developed a loopless algorithm associated with rotations of binary trees for generating LW-sequences by way of Williamson’s idea [14]. At a later time, based on the traversal in a rotation graph
✩ A preliminary version of this work was reported in the Proceedings of the 7th International Conference, COCOA 2013, Lecture Notes in Computer Science, vol. 8287, 2013, pp. 340–350. This work was supported by the National Science Council Taiwan under Contracts NSC102-2221-E-262-013 and NSC102-2221-E-141-001-MY3. Corresponding author. E-mail address:
[email protected] (J.-M. Chang).
*
http://dx.doi.org/10.1016/j.tcs.2014.07.030 0304-3975/© 2014 Published by Elsevier B.V.
26
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
Fig. 1. A binary tree T of weight 10.
constructed by a special type of rotation on the left-arm (or right-arm) of a tree, Wu et al. [15] provided a recursive CAT algorithm to generate LW-sequences of binary trees in lexicographic order. In that paper, to efficiently transform binary tree sequences, they made use of the concept of mirror image of LW-sequences to define the right-weight sequences (RWsequences) for binary trees. Because the usual binary trees are implemented so that nodes are allocated by structures and children of a node are accessed through pointers (i.e., the structure and pointer representation), this motivates us to define integer sequences connoting child’s information to represent binary trees. Two new types of binary tree sequences called the left-child sequences (LC-sequences) and the right-child sequences (RC-sequences) are introduced in the next section. In this paper, we present a loopless algorithm associated with rotations of binary trees for generating four types of binary tree sequences simultaneously, including LW-, RW-, LC-, and RC-sequences. In particular, LW- and RW-sequences are generated in Gray-code order, and LC- and RC-sequences are generated so that each sequence can be obtained from its predecessor by changing at most two digits. To the best of our knowledge, this is the first time that a loopless generating algorithm can simultaneously generate multiple types of binary tree sequences. Moreover, we show that the proposed algorithm has a high efficiency in the space and time requirements. In fact, to generate sequences of binary trees with n internal nodes, our loopless algorithm requires totally 6n + O (1) memory space, and each generation needs no more than 4 comparisons and takes an amortized cost with at most 8 assignments when n is larger. 2. Preliminaries A binary tree T considered here is a rooted, ordered tree with n internal nodes numbered by 1, 2, . . . , n in inorder (i.e., visit recursively the left subtree, root and then the right subtree of T ) such that every internal node has exactly two children called the left child and the right child. Such a binary tree is also referred to an extended binary tree [5]. For a node i ∈ T , the subtree rooted at i is denoted by T i . Also, the subtree rooted at the left child (respectively, right child) of i is called the left subtree (respectively, right subtree) of i and is denoted by L i (respectively, R i ). 2.1. Left-weight and right-weight sequences The weight of a binary tree T , denoted by w ( T ), is defined to be the number of leaves in T . Clearly, w ( T ) = n + 1 and T i contains w ( T i ) − 1 internal nodes for 1 i n. The left weight of a node i ∈ T , denoted by w ( T , i ), is defined to be the number of leaves in L i , i.e., w ( T , i ) = w ( L i ). Pallo [7] further defined the integer sequence w ( T ) = ( w ( T , 1), w ( T , 2), . . . , w ( T , n)) to be the left-weight sequence (LW-sequence for short) of T . Similarly, the right weight of a node i ∈ T is w r ( T , i ) = w ( R i ) and the integer sequence w r ( T ) = ( w r ( T , 1), w r ( T , 2), . . . , w r ( T , n)) is called the rightweight sequence (RW-sequence for short) of T in [15]. For notational convenience, if the tree T is clear from the context, we simply write w (i ) and w r (i ) instead of w ( T , i ) and w r ( T , i ), respectively. For example, Fig. 1 shows a binary tree T with 9 internal nodes whose LW- and RW-sequences are w ( T ) = (1, 2, 1, 1, 3, 6, 1, 1, 3) and w r ( T ) = (1, 4, 2, 1, 1, 4, 2, 1, 1), respectively. For a binary tree T , there is a linear time transformation between w ( T ) and w r ( T ) in [15]. Pallo [7] and Wu et al. [15] respectively characterized an integer sequence to be an LW-sequence or RW-sequence of a binary tree as follows. Theorem 1. (See [7,15].) Let w = ( w 1 , w 2 , . . . , w n ) be an integer sequence. Then, (a) w is the LW-sequence of a binary tree T with n internal nodes if and only if the following conditions are fulfilled for all i ∈ {1, 2, . . . , n}: (i) 1 w i i and (ii) i − w i j − w j for all j ∈ [i − w i + 1, i ]. (b) w is the RW-sequence of a binary tree T with n internal nodes if and only if the following conditions are fulfilled for all i ∈ {1, 2, . . . , n}: (i) 1 w i n − i + 1 and (ii) i + w i j + w j for all j ∈ [i , i + w i − 1]. For a binary tree T , a path from the root to its leftmost leaf (respectively, rightmost leaf) is called the left arm (respectively, right arm). The following lemma shows that a node on the left arm or right arm of a subtree is easy to be checked.
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
27
In particular, if we imagine that T is the right subtree (respectively, left subtree) of a dummy node numbered by 0 (respectively, n + 1), it is easy to check from Lemma 1 that a node x is in the left arm (respectively, right arm) of T if and only if x = w (x) (respectively, x + w r (x) = n + 1), and x is the root of T if and only if w (x) + w r (x) = n + 1. Lemma 1. (See [15].) Let T be a binary tree and i ∈ T an internal node. If x is a descendant of i, the following statements hold: (a) The node x is contained in the left arm of R i if and only if x − w (x) = i. (b) The node x is contained in the right arm of L i if and only if x + w r (x) = i. Lemma 2. (See [15].) Let T be a binary tree and i ∈ T an internal node. Suppose that i is not the root of T and let p be the parent of i. Then, the following statements hold: (a) The node i is the right child of p if and only if p = i − w (i ) (i.e., w r ( p ) = w (i ) + w r (i )). (b) The node i is the left child of p if and only if p = i + w r (i ) (i.e., w ( p ) = w (i ) + w r (i )). 2.2. Left-child and right-child sequences Let T be a binary with n internal nodes numbered by 1, 2, . . . , n in inorder. In the following, we introduce two new types of sequences to represent T . The left-child sequence (LC-sequence for short) of T , denoted by c ( T ) = (c ( T , 1), c ( T , 2), . . . , c ( T , n)), is an integer sequence where the term c ( T , i ), 1 i n, is defined as follows:
c (T , i ) =
0 if the left child of i is a leaf; j if j is the left child of i in T .
(1)
Similarly, we denote cr ( T ) = (cr ( T , 1), cr ( T , 2), . . . , cr ( T , n)) as the right-child sequence (RC-sequence for short) of T , where we use the right child instead of the left child in (1) to define the term cr ( T , i ). Obviously, c ( T , i ) < i and either cr ( T , i ) = 0 or cr ( T , i ) > i. In particular, c ( T , 1) = cr ( T , n) = 0. Customarily, we omit the parameter T in the terms c ( T , i ) and cr ( T , i ) if it is clear from the context. For instance, the LC-sequence and RC-sequence of the binary tree T shown in Fig. 1 are c ( T ) = (0, 1, 0, 0, 3, 2, 0, 0, 7) and cr ( T ) = (0, 5, 4, 0, 0, 9, 8, 0, 0), respectively. For a binary tree T , we denote α (k) = i (or α −1 (i ) = k) to mean that a node i has kth position in the preorder traversal of T . We now characterize an integer sequence to be an LC-sequence or RC-sequence of a binary tree as follows. Theorem 2. Let c = (c 1 , c 2 , . . . , cn ) be an integer sequence. Then, (a) c is the LC-sequence of a binary tree T with n internal nodes if and only if the following conditions are fulfilled for all i ∈ {1, 2, . . . , n}: (i) 0 c i < i and (ii) c j = 0 or c j > c i for all c i < j < i. (b) c is the RC-sequence of a binary tree T with n internal nodes if and only if the following conditions are fulfilled for all i ∈ {1, 2, . . . , n}: (i) c i > i or c i = 0 and (ii) c j = 0 or c j < c i for all i < j < c i . Proof. We only prove (a) because (b) can be verified by a similar way. For the “only if” part, (i) is obvious. If c i < j < i, then both nodes j and its left chid are contained in the right subtree of c i . Clearly, c j = 0 if the left child of j is a leaf; otherwise, c j > c i . Thus, (ii) follows. Conversely, we show that if c satisfies conditions (i) and (ii), then the preorder of the corresponding binary tree T can be determined by c. Since all internal nodes of T are numbered by 1, 2, . . . , n in inorder, it follows that the tree can be constructed. For i = 1, 2, . . . , n, we define the following function:
si =
sc i if c i = 0; i − 1 otherwise.
(2)
We claim that the preorder of the corresponding binary tree T can be obtained by the following rule: if si < s j or si = s j for j < i, then α −1 (i ) < α −1 ( j ) (e.g. see Table 1 for the instance c = (0, 1, 0, 0, 3, 2, 0, 0, 7)). To show the assertion, we need to prove that if α −1 (i ) < α −1 ( j ), then either si < s j or si = s j for j < i. Consider two nodes i , j ∈ T and, without loss of generality, assume α −1 (i ) < α −1 ( j ). Let i ∈ T i and j ∈ T j be nodes with the smallest integers in the inorder traversal of T , respectively. Clearly, 0 = c i < i i and 0 = c j < j j. By (2), we have si = sc i = si = i − 1 and s j = sc j = s j = j − 1. There are three cases for the positions of i and j in T as follows. Case 1: j ∈ L i . In this case, we have j < i. According to (i), we need to consider the following two subcases: Case 1.1: c i < j < i. In this case, we have j ∈ R c i , and thus c i = 0 and i c i < j. If c j = 0, then si = i − 1 < j − 1 = s j . Otherwise, it follows from (ii) that c j > c i . In this case, j ∈ R c i implies i < j , and thus si = i − 1 < j − 1 = s j . Case 1.2: j c i < i. In this case, we have j ∈ L c i ∪ {c i } and c i = 0. Obviously, if j is on the left arm of T c i , then i = j , and it follows from (2) that si = s j . Otherwise, there is a node k on the left arm of L c i such that j ∈ R k . Clearly, k < j < i. Thus, by substituting k for c i , an argument similar to Case 1.1 shows that si < s j . Case 2: j ∈ R i . In this case, we have i < j. Clearly, j ∈ R i , and thus i i < j . This implies si = i − 1 < j − 1 = s j .
28
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
Table 1 Determining the preorder of a tree by giving its LC-sequence. i
1
2
3
4
5
6
7
8
9
ci si
0 0 3 6
1 0 2 2
0 2 5 1
0 3 6 5
3 2 4 3
2 0 1 4
0 6 8 9
0 7 9 7
7 6 7 8
α −1 (i ) α (i )
Fig. 2. Linear time transformations of binary tree sequences.
Case 3: i and j have a common ancestor k such that i ∈ L k and j ∈ R k . Clearly, i ∈ L k , j ∈ R k and i i < k < j j. Thus, si = i − 1 < j − 1 = s j . 2 We can also reformulate c ( T , i ) and cr ( T , i ) as follows. Lemma 3. Let T be a binary tree and i ∈ T an internal node. Then
(a) c (i ) =
(b) cr (i ) =
0 if the left child of i is a leaf; min{x ∈ [1, i − 1] | x + w r (x) = i } otherwise. 0 if the right child of i is a leaf; max{x ∈ [i + 1, n] | x − w (x) = i } otherwise.
Proof. By symmetry, we only prove (a). Suppose that the left child of i is not a leaf of T and let c (i ) = j. By Lemma 1, x + w r (x) = i if and only if x is contained in the right arm of T j (i.e., L i ). In particular, j x whenever x is contained in the right arm of T j . 2 Lemma 4. Let T be a binary tree and i ∈ T an internal node. The following conditions hold:
(a) w (i ) =
(b) w r (i ) =
1 if c (i ) = 0; w (c (i )) + i − c (i ) otherwise. 1 w r (cr (i )) + cr (i ) − i
if cr (i ) = 0; otherwise.
Proof. By symmetry, we only prove (a). Clearly, if c (i ) = 0, then w (i ) = 1. Otherwise, by Lemma 2 we have i = c (i ) + w r (c (i )). Thus, w (i ) = w ( L i ) = w ( T c (i ) ) = w (c (i )) + w r (c (i )) = w (c (i )) + i − c (i ). 2 By Lemma 3, we can design linear time transformations from w r ( T ) to c ( T ) and from w ( T ) to cr ( T ), respectively. Also, by Lemma 4, we can design linear time transformations from c ( T ) to w ( T ) and from cr ( T ) to w r ( T ), respectively. Therefore, the four types of binary tree sequences can transform to each other in linear time. Fig. 2 shows all procedures of transformation.
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
29
Fig. 3. Left rotation and right rotation.
2.3. Tree rotations A rotation is a simple operation that reconstructs a binary tree into another tree and preserves its inorder. For a binary tree T and two nodes x, y ∈ T where x is the right child of y, a left rotation at x, denoted by ρ ( T , x), is an operation that raises x to the place of y, such that y becomes the new left child of x and the left subtree of x becomes the new right subtree of y, while the remaining parts of the tree are unchanged. A right rotation at a node x, denoted by ρr ( T , x), is the reverse operation of ρ ( T , x), i.e., if we apply the right rotation after a left rotation at a node, it reconstructs the original tree. See Fig. 3 for an illustration. Also, for notational convenience, we use the same notation ρ ( T , x) or ρr ( T , x) to denote the resulting tree that performs the rotation. The following propositions directly follow from the definition of rotations and thus we omit the proof since its validity can easily be checked from Lemma 2. Proposition 1. For a binary tree T and two nodes x, y ∈ T where x is the right child of y. Let L = ρ ( T , x). Then (a) (b) (c) (d) (e)
w r ( L , y ) = w ( T , x) and w ( L , x) = w ( T , x) + w ( T , y ); cr ( L , y ) = c ( T , x) and c ( L , x) = y; If y is the left child of a node z, then z = x + w r (x) and c ( L , z) = x; If y is the right child of a node z, then z = y − w ( y ) and cr ( L , z) = x; Except for the above changes, the left child and right child (respectively, left weight and right weight) of every other node in L remain unchanged.
Proposition 2. For a binary tree T and two nodes x, y ∈ T where y is the left child of x. Let R = ρr ( T , x). Then (a) (b) (c) (d) (e)
w ( R , x) = w r ( T , y ) and w r ( R , y ) = w r ( T , y ) + w r ( T , x); c ( R , x) = cr ( T , y ) and cr ( R , y ) = x; If x is the left child of a node z, then z = x + w r (x) and c ( R , z) = y; If x is the right child of a node z, then z = x − w (x) and cr ( R , z) = y; Except for the above changes, the left child and right child (respectively, left weight and right weight) of every other node in R remain unchanged.
3. A loopless generation of binary tree sequences
2n
1 Let Tn be the set of binary trees with n internal nodes. It is well-known that |Tn | = n+ . A systematic way to 1 n describe all binary tree sequences is the use of coding trees. A coding tree Tn is a rooted tree consisting of n levels such that every node is associated with a label and the full labels along a path from the root to a leaf in Tn represent the sequence of a binary tree T ∈ Tn . To facilitate the description of Tn , the following terms are used in [16]. We say that a non-leaf node x ∈ Tn has an up-fragment (respectively, a down-fragment) if the labels of x’s children in Tn are arranged from left to right in increasing order (respectively, decreasing order). In particular, a coding tree is called a flip-flap tree if the following conditions hold: (1) every non-leaf node has either an up-fragment or a down-fragment; (2) if a node has an up-fragment, then its adjacency siblings (if exist) must have a down-fragment, and vice versa. Accordingly, we construct a coding tree such that the root has label 1 and, for each level i 2, the two particular labels 1 and i always appear in any fragment of level i. Moreover, if we restrict that the two nodes with labels 1 and i are on the boundary in every fragment and the two types of fragments (i.e., up-fragments and down-fragments) alternately appear in each level of Tn , then the resulting coding tree is a flip-flap tree. In this case, if the full labels along the path in the left arm of Tn are determined, then so is the arrangement of Tn . Since we have two choices to label a node (except the root) in the left arm of Tn , there are at least 2n−1 different ways to construct a flip-flap tree. For instance, Fig. 4 shows a flip-flap tree T5 begins with the sequence (1, 2, 3, 4, 5) in its left arm. In this case, the initial fragment in each level of T5 is given by a down-fragment.
30
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
Fig. 4. A flip-flap tree T5 for LW-sequences.
In the above arrangement of Tn , if u and v are two adjacent leaves, the sequences from the root to u and to v are said to be consecutive. The following lemma establishes the base of our loopless algorithm such that an enumeration of LW-sequences in Gray-code order can be achieved. Lemma 5. In a flip-flap tree, any two consecutive LW-sequences differ in exactly one digit. Proof. Let w ( T 1 ) and w ( T 2 ) be consecutive sequences with respect to two adjacent leaves u and v in Tn , and let w be the lowest common ancestor of u and v. It is clear that labels collected from the root to node w are the same for leaves u and v, and are different for w’s children. By the flip-flap arrangement, the remaining labels for leaves u and v must also be the same. Thus, there is only one position having different digits for w ( T 1 ) and w ( T 2 ). 2 A procedure called NextTree() is developed to perform either a left rotation or a right rotation at node i for generating the next tree sequences. Arrays w (1..n), w r (1..n), c (1..n) and cr (1..n) are used to store the current LW-, RW-, LC- and RC-sequences, respectively. We initially set w ( j ) = j, w r ( j ) = 1, c ( j ) = j − 1 and cr ( j ) = 0 for j = 1, . . . , n. That is, the first generated tree is the left-skew tree. In addition, two auxiliary arrays ρ (1..n) and F (1..n) are employed to record important information for nodes 1, 2, . . . , n. The setting ρ (i ) = 1 (respectively, ρ (i ) = −1) indicates that the current operation performed at node i is a left rotation (respectively, a right rotation), and in this moment the fragment at level i of Tn will be an up-fragment (respectively, a down-fragment). Also, we use F (i ) to keep the track of positions to be processed for node i. In the beginning, let i = n and, for 1 j n, we set up ρ ( j ) = −1 and F ( j ) = j. When NextTree() is invoked, it performs the following steps: 1. Determine the case to perform a left rotation or a right rotation at node i. 1.1 The case of a left rotation (i.e., an up-fragment at level i of Tn ): • Let p be the parent of i (in this case, i is the right child of p). If p is not the root of the current tree T , let q be the parent of p. • Perform the rotation T = ρ ( T , i ). • According to Proposition 1(c) and 1(d), if p is the left child of q in T , update c ( T , q) = i; otherwise, update cr ( T , q) = i. • According to Proposition 1(a) and 1(b), update w r ( T , p ), w ( T , i ), cr ( T , p ) and c ( T , i ). • If i is not on the left arm of T , perform ρ ( T , n) in the next iteration. 1.2 The case of a right rotation (i.e., a down-fragment at level i of Tn ): • Let q be the left child of i. If i is not the root of the current tree T , let p be the parent of i. • Perform the rotation T = ρr ( T , i ). • According to Proposition 2(c) and 2(d), if i is the left child of p in T , update c ( T , p ) = q; otherwise, update cr ( T , p ) = q. • According to Proposition 2(a) and 2(b), update w ( T , i ), w r ( T , q), c ( T , i ) and cr ( T , q). • If i still has a left child in T , perform ρr ( T , n) in the next iteration.
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
31
Fig. 5. The loopless procedure NextTree().
2. If the fragment is in face of a boundary (i.e., i is on the left arm of T for Step 1.1 or i has no left child in T for Step 1.2), then we perform the following: • Change the type of rotation in the next iteration (i.e., ρ (i ) = −ρ (i )). • Propagate the information of F from an upper level to a lower level in Tn (i.e., F (i ) = F (i − 1)). • Recover the information of F for the upper level of Tn (i.e., F (i − 1) = i − 1). • Set F (n) to be the node that will be rotated in the next iteration (i.e., i = F (n)). • Retrieve the initial value of F (n) (i.e., F (n) = n). 3. When i = 1, all tree sequences have been generated. Fig. 5 gives the implementation in detail. Table 2 shows the list of binary tree sequences generated by NextTree() when n = 5. Fig. 6 shows the flip-flap tree T5 , where we put an integer i under a letter ‘R’ (respectively, a letter ‘L’) between two consecutive LW-sequences to mean that a sequence is obtained from its predecessor by performing a right rotation (respectively, a left rotation) at node i. To guarantees that the procedure has a constant delay time, by way of an illustration in Fig. 6 we can easily proceed to the following analysis. Lemma 6. NextTree() takes an amortized cost with at most 4 comparisons and 8 +
3 2n−1
assignments.
Proof. Let N c and N a denote the expected number of comparisons and the expected number of assignments used in the procedure. We can check from NextTree() that there are 3 comparisons in the best case and 4 comparisons in the worst case. It follows that N c 4. For computing the upper bound of N a , it is easy to see that the procedure requires at most 7 assignments when the rotation is performed at node n. Otherwise, it requires at most 11 assignments. Moreover, from the
32
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
Table 2 The lists of binary tree sequences generated by NextTree() when n = 5. Tree
LW-seq.
RW-seq.
LC-seq.
RC-seq.
Tree
LW-seq.
RW-seq.
LC-seq.
RC-seq.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
(1, 2, 3, 4, 5) (1, 2, 3, 4, 1) (1, 2, 3, 1, 1) (1, 2, 3, 1, 2) (1, 2, 3, 1, 5) (1, 2, 1, 1, 5) (1, 2, 1, 1, 3) (1, 2, 1, 1, 2) (1, 2, 1, 1, 1) (1, 2, 1, 2, 1) (1, 2, 1, 2, 3) (1, 2, 1, 2, 5) (1, 2, 1, 4, 5) (1, 2, 1, 4, 1) (1, 1, 1, 4, 1) (1, 1, 1, 4, 5) (1, 1, 1, 3, 5) (1, 1, 1, 3, 4) (1, 1, 1, 3, 1) (1, 1, 1, 2, 1) (1, 1, 1, 2, 3)
(1, 1, 1, 1, 1) (1, 1, 1, 2, 1) (1, 1, 3, 2, 1) (1, 1, 3, 1, 1) (1, 1, 2, 1, 1) (1, 3, 2, 1, 1) (1, 4, 2, 1, 1) (1, 4, 3, 1, 1) (1, 4, 3, 2, 1) (1, 4, 1, 2, 1) (1, 4, 1, 1, 1) (1, 3, 1, 1, 1) (1, 2, 1, 1, 1) (1, 2, 1, 2, 1) (3, 2, 1, 2, 1) (3, 2, 1, 1, 1) (4, 2, 1, 1, 1) (5, 2, 1, 1, 1) (5, 2, 1, 2, 1) (5, 4, 1, 2, 1) (5, 4, 1, 1, 1)
(0, 1, 2, 3, 4) (0, 1, 2, 3, 0) (0, 1, 2, 0, 0) (0, 1, 2, 0, 4) (0, 1, 2, 0, 3) (0, 1, 0, 0, 2) (0, 1, 0, 0, 3) (0, 1, 0, 0, 4) (0, 1, 0, 0, 0) (0, 1, 0, 3, 0) (0, 1, 0, 3, 4) (0, 1, 0, 3, 2) (0, 1, 0, 2, 4) (0, 1, 0, 2, 0) (0, 0, 0, 1, 0) (0, 0, 0, 1, 4) (0, 0, 0, 2, 1) (0, 0, 0, 2, 4) (0, 0, 0, 2, 0) (0, 0, 0, 3, 0) (0, 0, 0, 3, 4)
(0, 0, 0, 0, 0) (0, 0, 0, 5, 0) (0, 0, 4, 5, 0) (0, 0, 5, 0, 0) (0, 0, 4, 0, 0) (0, 3, 4, 0, 0) (0, 5, 4, 0, 0) (0, 3, 5, 0, 0) (0, 3, 4, 5, 0) (0, 4, 0, 5, 0) (0, 5, 0, 0, 0) (0, 4, 0, 0, 0) (0, 3, 0, 0, 0) (0, 3, 0, 5, 0) (2, 3, 0, 5, 0) (2, 3, 0, 0, 0) (4, 3, 0, 0, 0) (5, 3, 0, 0, 0) (4, 3, 0, 5, 0) (2, 4, 0, 5, 0) (2, 5, 0, 0, 0)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
(1, 1, 1, 2, 4) (1, 1, 1, 2, 5) (1, 1, 1, 1, 5) (1, 1, 1, 1, 4) (1, 1, 1, 1, 3) (1, 1, 1, 1, 2) (1, 1, 1, 1, 1) (1, 1, 2, 1, 1) (1, 1, 2, 1, 2) (1, 1, 2, 1, 4) (1, 1, 2, 1, 5) (1, 1, 2, 3, 5) (1, 1, 2, 3, 4) (1, 1, 2, 3, 1) (1, 1, 2, 4, 1) (1, 1, 2, 4, 5) (1, 1, 3, 4, 5) (1, 1, 3, 4, 1) (1, 1, 3, 1, 1) (1, 1, 3, 1, 2) (1, 1, 3, 1, 5)
(5, 3, 1, 1, 1) (4, 3, 1, 1, 1) (4, 3, 2, 1, 1) (5, 3, 2, 1, 1) (5, 4, 2, 1, 1) (5, 4, 3, 1, 1) (5, 4, 3, 2, 1) (5, 1, 3, 2, 1) (5, 1, 3, 1, 1) (5, 1, 2, 1, 1) (4, 1, 2, 1, 1) (4, 1, 1, 1, 1) (5, 1, 1, 1, 1) (5, 1, 1, 2, 1) (3, 1, 1, 2, 1) (3, 1, 1, 1, 1) (2, 1, 1, 1, 1) (2, 1, 1, 2, 1) (2, 1, 3, 2, 1) (2, 1, 3, 1, 1) (2, 1, 2, 1, 1)
(0, 0, 0, 3, 2) (0, 0, 0, 3, 1) (0, 0, 0, 0, 1) (0, 0, 0, 0, 2) (0, 0, 0, 0, 3) (0, 0, 0, 0, 4) (0, 0, 0, 0, 0) (0, 0, 2, 0, 0) (0, 0, 2, 0, 4) (0, 0, 2, 0, 3) (0, 0, 2, 0, 1) (0, 0, 2, 3, 1) (0, 0, 2, 3, 4) (0, 0, 2, 3, 0) (0, 0, 2, 1, 0) (0, 0, 2, 1, 4) (0, 0, 1, 3, 4) (0, 0, 1, 3, 0) (0, 0, 1, 0, 0) (0, 0, 1, 0, 4) (0, 0, 1, 0, 3)
(5, 4, 0, 0, 0) (2, 4, 0, 0, 0) (2, 3, 4, 0, 0) (5, 3, 4, 0, 0) (2, 5, 4, 0, 0) (2, 3, 5, 0, 0) (2, 3, 4, 5, 0) (3, 0, 4, 5, 0) (3, 0, 5, 0, 0) (5, 0, 4, 0, 0) (3, 0, 4, 0, 0) (4, 0, 0, 0, 0) (5, 0, 0, 0, 0) (4, 0, 0, 5, 0) (3, 0, 0, 5, 0) (3, 0, 0, 0, 0) (2, 0, 0, 0, 0) (2, 0, 0, 5, 0) (2, 0, 4, 5, 0) (2, 0, 5, 0, 0) (2, 0, 4, 0, 0)
Fig. 6. A flip-flap tree T5 and a sequence of rotations.
observation of a flip-flap tree, we can see that the number of rotations at node n is equal to the difference between the number of leaves and the number of their parents, i.e., |Tn | − |Tn−1 | (e.g., we have 42 − 14 = 28 for T5 ). Thus,
Na
7(|Tn | − |Tn−1 |) + 11|Tn−1 |
|Tn |
=7+4·
n+1 n
2n−2
−1 · n2n =8+ n
3 2n − 1
.
2
We summarize our main result as the following theorem. Theorem 3. All binary trees with n internal nodes encoded by LW-, RW-, LC-, and RC-sequences can be generated simultaneously in O (|Tn |) time using 6n + O (1) memory space and each generation requires only constant time. In particular, LW-sequences and RW-sequences are generated in Gray-code order, and discriminatingly, LC-sequences and RC-sequences are generated so that each sequence can be obtained from its predecessor by changing at most two digits. Proof. For NextTree(), the memory requirement is obvious as those stated in the procedure (see Fig. 5) and the time complexity directly follows from Lemma 6. In the following, we show that all binary tree sequences can be generated and
R.-Y. Wu et al. / Theoretical Computer Science 556 (2014) 25–33
33
refer the reader to [17] for the proof of a generalized case called t-ary trees (see Corollary 3 for computing |Tn,t | given there and note that |Tn | = |Tn,2 |). Since the procedure NextTree() performs either a left rotation or a right rotation, by Propositions 1 and 2, every rotation can generate the four types of binary tree sequences. Moreover, according to the flip-flap tree Tn , our algorithm performs a list of rotations to generate binary tree sequences (see Fig. 6 as an illustration). Thus, the total number of binary tree sequences to be generated is equal to the number of leaves in Tn . Lucas et al. [6] showed that the underlying coding trees for several algorithms that generate binary tree representations (including LW-sequences generated in [7]) are isomorphic 1 2n and each of such coding trees with n levels contains n+ leaves (i.e., the Catalan number). Since our flip-flap tree Tn is a 1 n rearrangement of the coding tree in [7] such that up-fragments and down-fragments alternately appear in each level of Tn , the number of leaves does not be changed. Consequently, this shows that all binary trees with n internal nodes encoded by LW-, RW-, LC-, and RC-sequences can be correctly generated. In addition, by Lemma 5, we have known that LW-sequences is generated in a Gray-code order. From another point of view, we can check the procedure to see that a digit in the current LW-sequence (respectively, RW-sequence) will be changed either in Line 9 (respectively, Line 8) for a right rotation or in Line 21 (respectively, Line 22) for a left rotation. Thus, for these two types of sequences, there only one digit is changed for each generation. By contrast, for LC-sequences (respectively, RC-sequences), the change of the two digits occurs either in the case that we perform a right rotation at node i whose parent is a left child (respectively, right child) of a node or in the case that we perform a left rotation at node i who is a left child (respectively, right child) of its parent (see Lines 5 and 11 or Lines 18 and 23 for LC-sequences, and Lines 7 and 10 or Lines 20 and 24 for RC-sequences). For all other cases in each of the generation of LC-sequences or RC-sequences, there is only one digit to be changed. 2 4. Concluding remarks In this paper, we design a loopless algorithm associated with rotations of binary trees for generating LW-, RW-, LC-, and RC-sequences simultaneously. Also, we prove that our algorithm is possessed of a high efficiency in space and time requirements. Compared with the loopless algorithm that associates with rotations to generate LW-sequences of binary trees in [12], ours is more efficient in both space and time. Our algorithm needs 6n + O (1) space and each generation requires 3/4 comparisons and 7/11 assignments in the best/worst case between two successive sequences. In fact, a result pointed in [19] shows that Vajnovszki’s algorithm needs 8n + O (1) space and each generation requires 3/5 comparisons and 9/13 assignments in its best/worst case between two successive sequences. We know that almost all combinatorial objects have integer sequence representation. Since different representations are derived from some structural properties of these objects, there must be a natural correspondence between the different representations. As to the future research, we believe that the idea of this paper could easily be imitated to generate multiple types of sequences for other combinatorial objects, such as k-ary trees. Applying this technique to generate other combinatorial objects is still open. References [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19]
G. Ehrlich, Loopless algorithms for generating permutations, combinations, and other combinatorial configurations, J. ACM 20 (1973) 500–513. J.F. Korsh, Loopless generation of k-ary tree sequences, Inform. Process. Lett. 52 (1994) 243–247. J.F. Korsh, P. LaFollette, Loopless generation of Gray codes for k-ary trees, Inform. Process. Lett. 70 (1999) 7–11. J.F. Korsh, S. Lipschutz, Shift and loopless generation of k-ary trees, Inform. Process. Lett. 65 (1998) 235–240. D.E. Knuth, The Art of Computer Programming: Vol. 4, Fascicle 4A – Generating All Trees, Addison–Wesley, 2005. J.M. Lucas, D. van Baronaigien Roelants, F. Ruskey, On rotations and the generation of binary trees, J. Algorithms 15 (1993) 343–366. J. Pallo, Enumerating, ranking and unranking binary trees, Comput. J. 29 (1986) 171–175. D. van Baronaigien Roelants, A loopless algorithm for generating binary tree sequences, Inform. Process. Lett. 39 (1991) 189–194. D. van Baronaigien Roelants, A loopless Gray-code algorithm for listing k-ary trees, J. Algorithms 35 (2000) 100–107. D. van Baronaigien Roelants, F. Ruskey, A Hamiltonian path in the rotation lattice of binary trees, Congr. Numer. 59 (1987) 313–318. T. Takaoka, O (1) time algorithms for combinatorial generation by tree traversal, Comput. J. 42 (1999) 400–408. V. Vajnovszki, On the loopless generation of binary tree sequences, Inform. Process. Lett. 68 (1998) 113–117. V. Vajnovszki, Generating a Gray code for P-sequences, J. Math. Model. Algorithms 1 (2002) 31–41. S.G. Williamson, Combinatorics for Computer Science, Computer Science Press, Rockville, MD, 1985. R.-Y. Wu, J.-M. Chang, Y.-L. Wang, A linear time algorithm for binary tree sequences transformation using left-arm and right-arm rotations, Theoret. Comput. Sci. 355 (2006) 303–314. R.-Y. Wu, J.-M. Chang, Y.-L. Wang, Loopless generation of non-regular trees with a prescribed branching sequence, Comput. J. 53 (2010) 661–666. R.-Y. Wu, J.-M. Chang, Y.-L. Wang, Ranking and unranking of t-ary trees using RD-sequences, IEICE Trans. Inform. Syst. E94-D (2011) 226–232. L. Xiang, K. Ushijima, On O (1) time algorithms for combinatorial generation, Comput. J. 44 (2001) 292–302. L. Xiang, K. Ushijima, C. Tang, Efficient loopless generation of Gray codes for k-ary trees, Inform. Process. Lett. 76 (2000) 169–174.