HI everyone. :) .I hope you can help me my function . I want the user to enter number of level "There are two levels" and then display students records in that level sorted by id .the one I wrote sorts then displays so the output is wrong .I tried to put the sort part after the level check but the program crashed. Any ideas??

here is the code

void displaysortbyID()
   
   {
       int levelno;
      
	  struct school *pre;
   
      struct school *move;
   
      struct school *temp;
      
      temp = (school *) malloc (sizeof(school));
  
     
      printf("\nEnter the number of level ");
	  scanf("%d",&levelno);
		
	  move=head;
  
      pre=head;
  
      move=move->next;
  
       
  
     while (move!=NULL)
  
      {  
  
      if ((pre->id)>(move->id))
  
      {
        temp->id=pre->id;
 
        pre->id=move->id;
  
        move->id=temp->id;
  
      }
 
      pre=pre->next;
  
      move=move->next;
 
     
	   } /*End of sorting*/
 	 
	  
	 { move=head;
	  
	  while (move!=NULL)
	  {   
		  if(move->level==levelno)
	 
		  {printf("\n\n The output is\n ");
          printf("\n\n  Id : %d",move->id);

		  printf("\n  Name : %s",move->name);

		  printf("\n  Adress : %s",move->address);
	      printf("\n  Phone : %d",move->phone);
		
		  printf("\n  Sex: %s",move->sex);

		  printf("\n  Level : %d",move-> level);
		  printf("\n  Average : %f",move->average);}
	   
		  move = move->next;
        }// end of while .
	  
	  }
	  
	  getch(); 
}

Dani AI

Generated

A short, practical plan for (builds on 's pointer-swapping note but avoids repeating the posted code).

The wrong output you saw comes from swapping only id while leaving the rest of each record in place — that leaves names/phones mismatched with IDs. Crashes when you moved the sort after the level check are usually pointer problems (null dereference or updating head/next incorrectly) rather than the level test itself. Two safe, simple fixes:

  • Easiest and least intrusive: collect pointers to the nodes that match the chosen level into a dynamic array, then call qsort on that array by id and print in array order. This keeps each record intact and avoids fiddling with links.
  • If you prefer an in-place linked-list solution, detach the matching nodes into a new list and run a pointer-based merge sort on that list (merge sort is O(n log n) and works well on linked lists).

Code sketch for the array + qsort approach (new code; different from posted snippets):

int cmp_id(const void *a, const void *b) {
    const struct school *const *pa = a;
    const struct school *const *pb = b;
    return ((*pa)->id > (*pb)->id) - ((*pa)->id < (*pb)->id);
}

/* collect pointers into arr[0..n-1], then: */
qsort(arr, n, sizeof(arr[0]), cmp_id);
/* iterate arr and print nodes in sorted order */

If doing an in-place list sort, see a standard explanation at Merge sort for linked list for a robust implementation.

Quick troubleshooting checklist

  • Check head for NULL and that loops guard ->next before dereference.
  • Update head when swapping at the front.
  • Match printf/scanf format specifiers to the actual field types.
  • Free any temporary array you allocate.
  • Avoid using getch() for portability; prefer standard input handling.

Any of the two approaches above will keep records consistent and avoid the mismatches and crashes you saw.

Recommended Answers

All 4 Replies

Here you go as in initial pass!

But you really need to swap the node links, not the contents of the node.

Also you should use a more complex sort then a slow bubble sort!

void displaysortbyID( void )
{
	struct school *pre;
	struct school *move;
	struct school temp;
	bool bFlg;
                 int levelno;

	printf("\nEnter the number of level ");
	scanf("%d",&levelno);



	bFlg = true;


	while (bFlg)			// Simple bubble sort. Loop until no swaps occur!
	{
	               move = head;
		bFlg = false;

		while (NULL != move->next)
		{  
                                               pre = move;
			move = move->next;

			if ( pre->id > move->id )		// Previous > next then need to swap
			{
				temp.id = pre->id;
				pre->id = move->id;
				move->id = temp.id;
				bFlg = true;				// A swap occured!
			}
		} 
	}				/*End of sorting*/

	for ( move = head; NULL != move; move = move->next)
	{   
		if (move->level == levelno)
		{
			printf("\n\n The output is\n ");
			printf("\n\n  Id : %d",move->id);

			printf("\n  Name : %s",move->name);

			printf("\n  Adress : %s",move->address);
			printf("\n  Phone : %d",move->phone);

			printf("\n  Sex: %s",move->sex);

			printf("\n  Level : %d",move-> level);
			printf("\n  Average : %f",move->average);
		}
	} // end of while .
}

getch(); 
}

That should give you the gist of what you need to do. But you don't want to be swapping the contents of records. You want to swap pointers.

if (head == pre)
{
    head = pre->next;
}

int i = pre->next;
pre->next = move->next;
move->next = i;

So they will be swapped!

And don't forget once swapped
---> mov ---> pre ---->
So set mov = pre or you'll wastefully retest mov to pre which you've just finished swapping!

Thanks alot. I'm going to try this now .

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.