Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

<b>bsearch( ) with an Ordered Linked List : Can it be Done ? </b>

Status
Not open for further replies.

AussieBill

Technical User
May 12, 2000
3
AU
Hello folks,<br>Can anyone help ?<br>I want to READ in an Ordered Text file of Words into Memory - i.e Ordered Linked List. I'm OK here..<br>Then use bsearch() to locate a KeyWord and see if it exists in the Ordered Linked List. <br>Can it be done ? I only know how to use bsearch() with an Array.<br>Aussie Bill<br><br>
 
Below is the code:<br><br>Yes it can be done thru linked list also. The concept is : <br>In case of array you pass the index or subscript of the array. While in case of linked list you need to pass the pointer to the node. <br><br>If you need source code , I can try. <br>Does this answer your question ?<br>Thanx<br>Siddhartha Singh<br><A HREF="mailto:ssingh@aztecsoft.com">ssingh@aztecsoft.com</A><br><br>I am giving you the source code of linked list merge sort. Hope it will help in understanding you the logic for binary search.<br><br><br>/*<br>** Here's an example of how to sort a singly-linked list.&nbsp;&nbsp;I think it<br>** can be modified to sort a doubly-linked list, but it would get a bit<br>** more complicated.&nbsp;&nbsp;Note that this is a recursive method, but the<br>** recursion depth is limited to be proportional to the base 2 log of<br>** the length of the list, so it won't &quot;run away&quot; and blow the stack.<br>*/<br><br>#include &quot;snipsort.h&quot;<br><br>/* linked list sort -- public domain by Ray Gardner&nbsp;&nbsp;5/90 */<br><br>#include &lt;stdio.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* for NULL definition */<br>#include &lt;string.h&gt;<br><br><br>/* returns &lt; 0 if *p sorts lower than *q */<br>int keycmp (list *p, list *q)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return strcmp(p-&gt;key, q-&gt;key);<br>}<br><br>/* merge 2 lists under dummy head item */<br>list *lmerge (list *p, list *q)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list *r, head;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ( r = &head; p && q; )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( keycmp(p, q) &lt; 0 )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r = r-&gt;next = p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p = p-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r = r-&gt;next = q;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q = q-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r-&gt;next = (p ? p : q);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return head.next;<br>}<br><br>/* split list into 2 parts, sort each recursively, merge */<br>list *lsort (list *p)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list *q, *r;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( p )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q = p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for ( r = q-&gt;next; r && (r = r-&gt;next) != NULL; r = r-&gt;next )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q = q-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r = q-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q-&gt;next = NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( r )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p = lmerge(lsort(r), lsort(p));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return p;<br>}<br><br>#if 0 /* Not really main(), but a fill-in-the-blanks framework */<br><br>#ifdef __WATCOMC__<br>&nbsp;#pragma off (unreferenced)<br>#endif<br><br>main (void)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list *listp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* pointer to start of list */<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* first build unsorted list, then */<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listp = lsort(listp);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* rdg 10/93 */<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<br>}<br><br>#endif<br> <p>Siddhartha Singh<br><a href=mailto:siddhu_singh@hotmail.com>siddhu_singh@hotmail.com</a><br><a href=siddhu.freehosting.net> </a><br>
 
Thanks for your reply on TEk Tips forum (C), I appreciate this.<br>.....I have attached a file &quot;diction.c&quot; (which is a linked list of letters(a,b,c,...,p) which is sorted.<br>Say I am looking for letter 'c'&nbsp;&nbsp;if it exists in the linked list. How do I use bsearch() to find the if match in the linked list ?<br>&nbsp;<br>My Overall Problem:<br>I will READ in a already Sorted List of Words (Dictionary) into Memory - i.e usingOrdered Linked List.<br>I wanted to store the Words in an Array but don't know how many words exist, so cannot declare proper size of array.<br>So I guess I will have to use a linked list<br>Then use bsearch() to locate a KeyWord and see if it exists in the Ordered Linked List. If it can be done.<br>------------------------------------------------------------<br>See my attached file &quot;diction.c&quot; (at bottom page)<br>------------------------------------------------------------<br>BSEARCH: (function I need to use)<br>*bsearch( const void *key, const void * base, size_t nnemb, size_t size, int (*compar)(const void *, const void*) );<br>&nbsp;<br>e.g Search for word 'hello'&nbsp;&nbsp;in array :array[10] stores 10 words<br>&nbsp;<br>bsearch(&quot;hello&quot;, array, 10, sizeof(array[0]),comp)<br>where compare function is :-<br>int comp (const void *s1, const void *s2)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;return (strcmp(*(char **)s1, *(char **)s2));<br>}<br>-----------------------------------------------------------<br>-----------------------------------------------------------<br>#include &lt;stdio.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;ctype.h&gt;<br>#include &lt;stdlib.h&gt;<br><br>int comp(const void *s1, const void *s2);<br><br>typedef struct D_ENTRY_STRUCT LIST;<br>typedef LIST *LISTPTR;<br><br>struct D_ENTRY_STRUCT {<br> char&nbsp;&nbsp;letter;<br> struct D_ENTRY_STRUCT *next_rec;<br>};<br><br>LISTPTR add_to_list ( char, LISTPTR );<br>void show_list( void );<br>void free_memory_list( void );<br><br>LISTPTR first = NULL;<br><br>main ()<br>{<br> LISTPTR rec_addr;<br> int i=0;<br> char letter,ptr;<br><br> rec_addr = add_to_list('a', (LISTPTR)NULL );<br> first = rec_addr;<br> printf(&quot;Before Insertion\n&quot;);<br> while (i++&lt;15)<br> rec_addr = add_to_list('a'+i,rec_addr);<br> show_list();<br> printf(&quot;\nCount : %d&quot;,i);<br> printf(&quot;\nSearch key : &quot;);<br> letter = getchar();<br>// ptr = (char)bsearch(letter,first,16,sizeof(first),comp);<br>// if (ptr != NULL)<br>// printf(&quot;found&quot;);<br>// else<br>// printf(&quot;not found&quot;); */<br>// free_memory_list();<br> return 0;<br>}<br><br>LISTPTR add_to_list (char ch, LISTPTR prev_rec)<br>{<br> LISTPTR new_rec=NULL;<br><br> new_rec = (LISTPTR)malloc(sizeof(LIST));<br> if (!new_rec)<br> {<br> printf(&quot;\nUnable to allocate memory!\n&quot;);<br> exit(1);<br> }<br><br> new_rec-&gt;letter = ch;<br> new_rec-&gt;next_rec = NULL;<br><br> if (prev_rec)<br> prev_rec-&gt;next_rec = new_rec;<br><br> return(new_rec);<br>}<br><br>void show_list ( )<br>{<br> LISTPTR cur_ptr;<br> int counter=1;<br><br> printf(&quot;Rec addr&nbsp;&nbsp;&nbsp;Position&nbsp;&nbsp;&nbsp;Data&nbsp;&nbsp;&nbsp;Next Rec addr\n&quot;);<br> printf(&quot;========&nbsp;&nbsp;&nbsp;========&nbsp;&nbsp;&nbsp;====&nbsp;&nbsp;&nbsp;=============\n&quot;);<br> cur_ptr = first;<br> while (cur_ptr)<br> {<br> printf(&quot;&nbsp;&nbsp;%X&nbsp;&nbsp;&nbsp;&quot;, cur_ptr);<br> printf(&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%2i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%c&quot;,counter++,cur_ptr-&gt;letter);<br> printf(&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%X&nbsp;&nbsp;&nbsp;\n&quot;,cur_ptr-&gt;next_rec);<br> cur_ptr = cur_ptr-&gt;next_rec;<br> }<br>}<br><br>void free_memory_list ( )<br>{<br> LISTPTR cur_ptr, next_rec;<br> cur_ptr = first;<br> while (cur_ptr)<br> {<br> next_rec = cur_ptr-&gt;next_rec;<br> free(cur_ptr);<br> cur_ptr = next_rec;<br> }<br>}<br><br>int comp(const void *s1, const void *s2)<br>{<br> return (strcmp(*(char **)s1, *(char **)s2));<br>}<br><br><br>------------------------------------------------------------<br><br>
 
I will look into your code after sometime. Beucase right now I am very much busy. let me tell you the logic. You can then try yourself. Else whenever I will get time , will let you know.<br>&nbsp;<br>Note:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In an array case you know the lower limit (usually 0) and upper bound also. In case of linked list , your problem is how to know the uppor bound. Header is the lower bound. Since binary search involves previous knowledge of these bounds. <br>&nbsp;<br>Solution:<br>&nbsp;&nbsp;&nbsp;&nbsp;During fetching data into linked list just maintain a counter also . Which will keep count of the no. of nodes in the linked list. <br>Or you can know the number of nodes by this logic also<br>count = 1;<br>while(heade-&gt;next != NULL)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count++;<br>When you come out of the loop , count will be having the upper bound of the linked list. Now when you use your binary search in the program. Just use the numbers as in the case of array. But when you compute&nbsp;&nbsp;, use it like this way:<br>&nbsp;<br>Suppose in case of array , when you pass mid , last as a subscript. You use like array[mid] or array[last]. And then you pass these to comp function to check the values. Instead of this , in case of linked list. When you pass mid, then you have to implement the logic like:&nbsp;&nbsp;<br>&nbsp;<br>int k = 1;<br>node = header;<br>While(k &lt;= mid){<br>&nbsp;&nbsp;&nbsp;&nbsp;node = node-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;k++;<br>}<br>&nbsp;&nbsp;&nbsp;<br>This way when you come out of the loop , node will be having the value of mid&nbsp;&nbsp;position.<br>&nbsp;<br>&nbsp;Does this answer your question ?<br><br>&nbsp; <p>Siddhartha Singh<br><a href=mailto:siddhu_singh@hotmail.com>siddhu_singh@hotmail.com</a><br><a href=siddhu.freehosting.net> </a><br>
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top