/* ************************************************************ this procedures traverse the trie in depth first order so that the suffixes (stored in the leaf) are recovered in lexicographic order ************************************************************ */ static void traverse_trie(node *h) { node *p, *nextp; if(h->skip<0) Aux[Aux_written++] = (Int32) h->down; else { p = h->down; assert(p!=NULL); do { nextp = p->right; if(nextp!=NULL) { assert(nextp->key>=p->key); // if there are 2 nodes with equal keys // they must be considered in inverted order if(nextp->key==p->key) { traverse_trie(nextp); traverse_trie(p); p = nextp->right; continue; } } traverse_trie(p); p=nextp; } while(p!=NULL); } }
/* **************************************************************** routine for deep-sorting the suffixes a[0] ... a[n-1] knowing that they have a common prefix of length "depth" **************************************************************** */ void blind_ssort(Int32 *a, Int32 n, Int32 depth) { int neg_integer_cmp(const void *, const void *); node *find_companion(node *head, UChar *s); void insert_suffix(node *h, Int32 suf, int n, UChar mmchar); void traverse_trie(node *h); Int32 compare_suffixes(Int32 suf1, Int32 suf2, Int32 depth); void free_node_mem(); Int32 i,j,aj,lcp; node nh, *root, *h; // ---- sort suffixes in order of increasing length qsort(a,n, sizeof(Int32), neg_integer_cmp); // --- skip suffixes which have already reached the end-of-text for(j=0;j<n;j++) if(a[j]+depth < Text_size) break; if(j>=n-1) return; // everything is already sorted! // ------ init stack ------- Stack = (node **) malloc(n*sizeof(node *)); if(Stack==NULL) { fprintf(stderr,"Out of memory! (blind_ssort)\n"); exit(1); } // ------- init root with the first unsorted suffix nh.skip = -1; nh.right = NULL; nh.down = (void *) a[j]; root = &nh; // ------- insert suffixes a[j+1] ... a[n-1] for(i=j+1;i<n;i++) { h=find_companion(root, Text+a[i]); assert(h->skip==-1); assert(Stack_size<=i-j); aj=(Int32) h->down; assert(aj>a[i]); lcp = compare_suffixes(aj,a[i],depth); insert_suffix(root, a[i], lcp, Text[aj+lcp]); } // ---- traverse the trie and get suffixes in lexicographic order Aux=a; Aux_written = j; traverse_trie(root); assert(Aux_written==n); free_node_mem(); free(Stack); }
void blind_ssort(UInt32 *a, Int32 n, Int32 depth) { Int32 i,j,aj,lcp; node nh, *root, *h; /* ---- sort suffixes in order of increasing length */ qsort(a,n, sizeof(Int32), neg_integer_cmp); /* --- skip suffixes which have already reached the end-of-text */ for(j=0;j<n;j++) if(a[j]+(UInt32)depth < (UInt32)Text_size) break; if(j>=n-1) return; /* everything is already sorted! */ /* ------ init stack ------- */ Stack = (node **) malloc(n*sizeof(node *)); if(Stack==NULL) { fprintf(stderr,"Out of memory! (blind_ssort)\n"); exit(1); } /* ------- init root with the first unsorted suffix */ nh.skip = -1; nh.right = NULL; nh.down = (node *) a[j]; root = &nh; /* ------- insert suffixes a[j+1] ... a[n-1] */ for(i=j+1;i<n;i++) { h=find_companion(root, Text+a[i]); assert(h->skip==-1); assert(Stack_size<=i-j); aj=(Int32) h->down; assert((UInt32)aj>a[i]); lcp = compare_suffixes(aj,a[i],depth); insert_suffix(root, a[i], lcp, Text[aj+lcp]); } /* ---- traverse the trie and get suffixes in lexicographic order */ Aux=a; Aux_written = j; traverse_trie(root); assert(Aux_written==(UInt32)n); free_node_mem(); free(Stack); }