link-grammar-5.8.0/link-grammar/dict-file/read-dict.c
/**
 * insert_list() -
 * p points to a list of dict_nodes connected by their left pointers.
 * l is the length of this list (the last ptr may not be NULL).
 * It inserts the list into the dictionary.
 * It does the middle one first, then the left half, then the right.
 *
 * Note: I think this "insert middle, then left, then right" algo has
 * its origins as a lame attempt to hack around the fact that the
 * resulting binary tree is rather badly unbalanced. This has been
 * fixed by using the DSW rebalancing algo. Now, that would seem
 * to render this crazy bisected-insertion algo obsolete, but ..
 * oddly enough, it seems to make the DSW balancing go really fast!
 * Faster than a simple insertion. Go figure. I think this has
 * something to do with the fact that the dictionaries are in
 * alphabetical order! This subdivision helps randomize a bit.
 */
insert_list()
p points to a list of dict_nodes connected by their left pointers.
l is the length of this list (the last ptr may not be NULL).
It inserts the list into the dictionary.
It does the middle one first, then the left half, then the right.

I think this "insert middle, then left, then right" algo has
its origins as a lame attempt to hack around the fact that the
resulting binary tree is rather badly unbalanced. This has been
fixed by using the DSW rebalancing algo. Now, that would seem
to render this crazy bisected-insertion algo obsolete, but
oddly enough, it seems to make the DSW balancing go really fast.
Faster than a simple insertion. Go figure. I think this has
something to do with the fact that the dictionaries are in
alphabetical order. This subdivision helps randomize a bit.
insert_list () p points to a list of dict_nodes connected by their left pointers . l is the length of this list ( the last ptr may not be NULL ) . It inserts the list into the dictionary . It does the middle one first then the left half then the right . I think this " insert middle then left then right " algo has its origins as a lame attempt to hack around the fact that the resulting binary tree is rather badly unbalanced . This has been fixed by using the DSW rebalancing algo . Now that would seem to render this crazy bisected - insertion algo obsolete but oddly enough it seems to make the DSW balancing go really fast . Faster than a simple insertion . Go figure . I think this has something to do with the fact that the dictionaries are in alphabetical order . This subdivision helps randomize a bit .
void insert_list(Dictionary dict, Dict_node * p, int l)
{
	Dict_node * dn, *dn_head, *dn_second_half;
	int k, i; 
	if (l == 0) return;
	k = (l-1)/2;
	dn = p;
	for (i = 0; i < k; i++)
	{
		dn = dn->left;
	}
	dn_second_half = dn->left;
	dn->left = dn->right = NULL;
	if (is_idiom_word(dn->string))
	{
		prt_error("Warning: Word \"%s\" found near line %d of \"%s\".\n"
		        "\tWords ending \".Ix\" (x a number) are reserved for idioms.\n"
		        "\tThis word will be ignored.\n",
		        dn->string, dict->line_number, dict->name);
		free(dn);
	}
	else
	{
		if (contains_underbar(dn->string))
		{
			insert_idiom(dict, dn);
		}
		dict->root = insert_dict(dict, dict->root, dn);
		insert_length_limit(dict, dn);
		dict->num_entries++;
		if ((verbosity_level(D_DICT+0) && !is_warning_suppressed(dict, DUP_BASE)) ||
		    verbosity_level(D_SPEC+3))
		{
			const char *sm = strchr(dn->string, SUBSCRIPT_MARK);
			char *bareword;
			if (NULL != sm)
			{
				bareword = strdupa(dn->string);
				bareword[sm - dn->string] = '\0';
			}
			else
			{
				bareword = (char *)dn->string;
			}
			if ((dn_head = strict_lookup_list(dict, bareword)) != NULL)
			{
				bool match_found = false;
				for (Dict_node *dnx = dn_head; dnx != NULL; dnx = dnx->right) {
					if (0 != strcmp(dnx->string, dn->string))
					{
						if (!match_found)
						{
							prt_error("Warning: The word \"%s\" found near line "
										 "%d of \"%s\"\n\t matches the following words:",
										 dn->string, dict->line_number, dict->name);
							match_found = true;
						}
						prt_error("\t%s", dnx->string);
					}
				}
				if (match_found) prt_error("\n");
				file_free_lookup(dn_head);
			}
		}
	}
	insert_list(dict, p, k);
	insert_list(dict, dn_second_half, l-k-1);
}
void insert_list ( Dictionary dict , Dict_node * p , int l ) { Dict_node * dn , * dn_head , * dn_second_half ; int k , i ; if ( l == 0 ) return ; k = ( l - 1 ) / 2 ; dn = p ; for ( i = 0 ; i < k ; i ++ ) { dn = dn -> left ; } dn_second_half = dn -> left ; dn -> left = dn -> right = NULL ; if ( is_idiom_word ( dn -> string ) ) { prt_error ( " \" \" \" \" \n " " \t \" \" \n " " \t \n " , dn -> string , dict -> line_number , dict -> name ) ; free ( dn ) ; } else { if ( contains_underbar ( dn -> string ) ) { insert_idiom ( dict , dn ) ; } dict -> root = insert_dict ( dict , dict -> root , dn ) ; insert_length_limit ( dict , dn ) ; dict -> num_entries ++ ; if ( ( verbosity_level ( D_DICT + 0 ) && ! is_warning_suppressed ( dict , DUP_BASE ) ) || verbosity_level ( D_SPEC + 3 ) ) { const char * sm = strchr ( dn -> string , SUBSCRIPT_MARK ) ; char * bareword ; if ( NULL != sm ) { bareword = strdupa ( dn -> string ) ; bareword [ sm - dn -> string ] = ' \0 ' ; } else { bareword = ( char * ) dn -> string ; } if ( ( dn_head = strict_lookup_list ( dict , bareword ) ) != NULL ) { bool match_found = false ; for ( Dict_node * dnx = dn_head ; dnx != NULL ; dnx = dnx -> right ) { if ( 0 != strcmp ( dnx -> string , dn -> string ) ) { if ( ! match_found ) { prt_error ( " \" \" " " \" \" \n \t " , dn -> string , dict -> line_number , dict -> name ) ; match_found = true ; } prt_error ( " \t " , dnx -> string ) ; } } if ( match_found ) prt_error ( " \n " ) ; file_free_lookup ( dn_head ) ; } } } insert_list ( dict , p , k ) ; insert_list ( dict , dn_second_half , l - k - 1 ) ; }
insert_list()
 p points to a list of dict_nodes connected by their left pointers.
insert_list () p points to a list of dict_nodes connected by their left pointers .
/* length of first half */ /* dn now points to the middle element */ /* Warn if there are words with a subscript that match a bare word. */