@@ -587,6 +587,124 @@ func TestSearchTree_Select(t *testing.T) {
587587 }
588588}
589589
590+ func TestSearchTree_InOrderTraverse (t * testing.T ) {
591+ type insert struct {
592+ start int
593+ end int
594+ val string
595+ }
596+ tests := []struct {
597+ name string
598+ inserts []insert
599+ expectedVisits []string
600+ }{
601+ {
602+ name : "empty interval" ,
603+ inserts : []insert {},
604+ expectedVisits : []string {},
605+ },
606+ {
607+ name : "single interval" ,
608+ inserts : []insert {
609+ {start : 1 , end : 10 , val : "node1" },
610+ },
611+ expectedVisits : []string {"node1" },
612+ },
613+ {
614+ name : "multiple intervals" ,
615+ inserts : []insert {
616+ {start : 1 , end : 10 , val : "node1" },
617+ {start : 5 , end : 15 , val : "node2" },
618+ {start : 10 , end : 20 , val : "node3" },
619+ {start : 15 , end : 25 , val : "node4" },
620+ {start : 20 , end : 30 , val : "node5" },
621+ },
622+ expectedVisits : []string {"node1" , "node2" , "node3" , "node4" , "node5" },
623+ },
624+ {
625+ name : "multiple intervals with same end" ,
626+ inserts : []insert {
627+ {start : 1 , end : 10 , val : "node1" },
628+ {start : 5 , end : 15 , val : "node2" },
629+ {start : 10 , end : 20 , val : "node3" },
630+ {start : 15 , end : 25 , val : "node4" },
631+ {start : 20 , end : 30 , val : "node5" },
632+ {start : 25 , end : 30 , val : "node6" },
633+ },
634+ expectedVisits : []string {"node1" , "node2" , "node3" , "node4" , "node5" , "node6" },
635+ },
636+ {
637+ name : "multiple intervals with same end and same start" ,
638+ inserts : []insert {
639+ {start : 20 , end : 30 , val : "node5" },
640+ {start : 25 , end : 30 , val : "node6" },
641+ {start : 15 , end : 30 , val : "node7" },
642+ },
643+ expectedVisits : []string {"node7" , "node5" , "node6" },
644+ },
645+ {
646+ name : "interval spanning entire range" ,
647+ inserts : []insert {
648+ {start : 1 , end : 5 , val : "node1" },
649+ {start : 5 , end : 10 , val : "node2" },
650+ {start : 10 , end : 20 , val : "node3" },
651+ {start : 0 , end : 30 , val : "node4" },
652+ },
653+ expectedVisits : []string {"node4" , "node1" , "node2" , "node3" },
654+ },
655+ }
656+
657+ for _ , tc := range tests {
658+ t .Run (tc .name , func (t * testing.T ) {
659+ st := NewSearchTree [string ](func (x , y int ) int { return x - y })
660+
661+ for _ , insert := range tc .inserts {
662+ st .Insert (insert .start , insert .end , insert .val )
663+ }
664+
665+ got := []string {}
666+
667+ err := st .InOrderTraverse (func (start , end int , node string ) error {
668+ got = append (got , node )
669+ return nil
670+ })
671+ if err != nil {
672+ t .Fatalf ("st.InOrderTraverse(): error %v" , err )
673+ }
674+
675+ if ! reflect .DeepEqual (got , tc .expectedVisits ) {
676+ t .Errorf ("st.InOderTraverse(): got unexpected value %v; want %v" , got , tc .expectedVisits )
677+ }
678+ })
679+ }
680+
681+ t .Run ("stop traversal" , func (t * testing.T ) {
682+ st := NewSearchTree [string ](func (x , y int ) int { return x - y })
683+ st .Insert (17 , 19 , "node1" )
684+ st .Insert (5 , 8 , "node2" )
685+ st .Insert (21 , 24 , "node3" )
686+ st .Insert (4 , 8 , "node4" )
687+
688+ want := []string {"node4" , "node2" , "node1" }
689+ got := []string {}
690+ err := st .InOrderTraverse (func (start , end int , node string ) error {
691+ got = append (got , node )
692+ if node == "node1" {
693+ return StopTraversal
694+ }
695+ return nil
696+ })
697+
698+ if err != nil {
699+ t .Fatalf ("st.InOrderTraverse(): error %v" , err )
700+ }
701+
702+ if ! reflect .DeepEqual (got , want ) {
703+ t .Errorf ("st.InOderTraverse(): got unexpected value %v; want %v" , got , want )
704+ }
705+ })
706+ }
707+
590708func TestMultiValueSearchTree_AnyIntersection (t * testing.T ) {
591709 st := NewMultiValueSearchTree [string ](func (x , y int ) int { return x - y })
592710 defer mustBeValidTree (t , st .root )
@@ -1115,3 +1233,122 @@ func TestMultiValueSearchTree_MaxEnd(t *testing.T) {
11151233 }
11161234
11171235}
1236+
1237+ func TestMultiValueSearchTree_InOrderTraverse (t * testing.T ) {
1238+ type insert struct {
1239+ start int
1240+ end int
1241+ val string
1242+ }
1243+ tests := []struct {
1244+ name string
1245+ inserts []insert
1246+ expectedVisits [][]string
1247+ }{
1248+ {
1249+ name : "empty interval" ,
1250+ inserts : []insert {},
1251+ expectedVisits : [][]string {},
1252+ },
1253+ {
1254+ name : "single interval" ,
1255+ inserts : []insert {
1256+ {start : 1 , end : 10 , val : "node1" },
1257+ {start : 1 , end : 10 , val : "node2" },
1258+ },
1259+ expectedVisits : [][]string {{"node1" , "node2" }},
1260+ },
1261+ {
1262+ name : "multiple intervals" ,
1263+ inserts : []insert {
1264+ {start : 1 , end : 10 , val : "node1" },
1265+ {start : 5 , end : 15 , val : "node2" },
1266+ {start : 10 , end : 20 , val : "node3" },
1267+ {start : 15 , end : 25 , val : "node4" },
1268+ {start : 20 , end : 30 , val : "node5" },
1269+ },
1270+ expectedVisits : [][]string {{"node1" }, {"node2" }, {"node3" }, {"node4" }, {"node5" }},
1271+ },
1272+ {
1273+ name : "multiple intervals with same end" ,
1274+ inserts : []insert {
1275+ {start : 1 , end : 10 , val : "node1" },
1276+ {start : 5 , end : 15 , val : "node2" },
1277+ {start : 10 , end : 20 , val : "node3" },
1278+ {start : 15 , end : 25 , val : "node4" },
1279+ {start : 20 , end : 30 , val : "node5" },
1280+ {start : 25 , end : 30 , val : "node6" },
1281+ },
1282+ expectedVisits : [][]string {{"node1" }, {"node2" }, {"node3" }, {"node4" }, {"node5" }, {"node6" }},
1283+ },
1284+ {
1285+ name : "multiple intervals with same end and same start" ,
1286+ inserts : []insert {
1287+ {start : 20 , end : 30 , val : "node5" },
1288+ {start : 25 , end : 30 , val : "node6" },
1289+ {start : 15 , end : 30 , val : "node7" },
1290+ },
1291+ expectedVisits : [][]string {{"node7" }, {"node5" }, {"node6" }},
1292+ },
1293+ {
1294+ name : "interval spanning entire range" ,
1295+ inserts : []insert {
1296+ {start : 1 , end : 5 , val : "node1" },
1297+ {start : 5 , end : 10 , val : "node2" },
1298+ {start : 10 , end : 20 , val : "node3" },
1299+ {start : 0 , end : 30 , val : "node4" },
1300+ },
1301+ expectedVisits : [][]string {{"node4" }, {"node1" }, {"node2" }, {"node3" }},
1302+ },
1303+ }
1304+
1305+ for _ , tc := range tests {
1306+ t .Run (tc .name , func (t * testing.T ) {
1307+ st := NewMultiValueSearchTree [string ](func (x , y int ) int { return x - y })
1308+
1309+ for _ , insert := range tc .inserts {
1310+ st .Insert (insert .start , insert .end , insert .val )
1311+ }
1312+
1313+ got := [][]string {}
1314+
1315+ err := st .InOrderTraverse (func (start , end int , node []string ) error {
1316+ got = append (got , node )
1317+ return nil
1318+ })
1319+ if err != nil {
1320+ t .Fatalf ("st.InOrderTraverse(): error %v" , err )
1321+ }
1322+
1323+ if ! reflect .DeepEqual (got , tc .expectedVisits ) {
1324+ t .Errorf ("st.InOderTraverse(): got unexpected value %v; want %v" , got , tc .expectedVisits )
1325+ }
1326+ })
1327+ }
1328+
1329+ t .Run ("stop traversal" , func (t * testing.T ) {
1330+ st := NewMultiValueSearchTree [string ](func (x , y int ) int { return x - y })
1331+ st .Insert (17 , 19 , "node1" )
1332+ st .Insert (5 , 8 , "node2" )
1333+ st .Insert (21 , 24 , "node3" )
1334+ st .Insert (4 , 8 , "node4" )
1335+
1336+ want := [][]string {{"node4" }, {"node2" }, {"node1" }}
1337+ got := [][]string {}
1338+ err := st .InOrderTraverse (func (start , end int , node []string ) error {
1339+ got = append (got , node )
1340+ if node [0 ] == "node1" {
1341+ return StopTraversal
1342+ }
1343+ return nil
1344+ })
1345+
1346+ if err != nil {
1347+ t .Fatalf ("st.InOrderTraverse(): error %v" , err )
1348+ }
1349+
1350+ if ! reflect .DeepEqual (got , want ) {
1351+ t .Errorf ("st.InOderTraverse(): got unexpected value %v; want %v" , got , want )
1352+ }
1353+ })
1354+ }
0 commit comments