Link to home
Start Free TrialLog in
Avatar of darentan
darentan

asked on

Pointer Linklist record sorting

Hi, below is my program , i thinking of sort all the records via using the datarecord.year in ascending order



Program Books;

Uses Crt;     {Use because of clear screen command used}

Type
   DataRecord = Record
                   Bookname  : String [50];
                   Author    : String [30];
                   Publisher : String [30];
                   Year      : Integer    ;
                   Size      : String [ 2];
                   Pages     : Integer    ;
                   Price     : Real       ;
                   Intro     : String [30];
                End;  {end of record}
   
   ListPointer = ^ListRecord;
   ListRecord  = Record
                    DataField : DataRecord;  {data field type}
                    NextField : ListPointer  {pointer address to next book}
                 End;
   
Var
   FirstPointer : ListPointer;
   
   
   {************************************************************************
   Procedure Name : Initialise
   Input : Invoke by main program to do initialise all the pointers.
   Task  : Initialise and set the relationship for current, firstpointer
   ,nextfield and clear data that may exist in currentpointer
   Output: It will reset and clear all data present in the records/pointers.
   ************************************************************************* }
Procedure Initialise;

Var
   Input          : Char;
   CurrentPointer : ListPointer;
   
Begin
   While Assigned (FirstPointer) Do   {Test if a pointer variable is nil}
     
   Begin
      CurrentPointer := FirstPointer;   {Force current pointer to first node}
      FirstPointer   := FirstPointer^. NextField;
      Dispose (CurrentPointer);         {Once first node deleted, rest also}
   End;
   WriteLn ('The bookcase is Empty but ready for books.');
   Repeat
      Write ('Press "m" to return to Main Menu > ');
      ReadLn (Input);
      Input := UpCase (Input);  {allow m or M to be accepted}
   Until Input = 'M'
End;


{************************************************************************
  Procedure Name : Addbook
  Input : Invoke by main program to do capturing of all books.
  Task  : Accept user input on the books and save it to the record.
  Output: Record will hold all the data and store into memory
************************************************************************* }
Procedure Addbook;

Var
   CurrentPointer, TempPointer : ListPointer;
   Continue : Char;
   
Begin
   Repeat
      New (CurrentPointer);             {Creates a new dynamic variable}
      With CurrentPointer^. DataField Do
      Begin
         WriteLn;
         WriteLn ('Please input details including');
         Write ('Bookname           : '); ReadLn (Bookname );
         Write ('Author             : '); ReadLn (Author   );
         Write ('Publisher          : '); ReadLn (Publisher);
         Write ('Publication year   : '); ReadLn (Year     );
         Write ('Size               : '); ReadLn (Size     );
         Write ('Pages              : '); ReadLn (Pages    );
         Write ('Sale price         : '); ReadLn (Price    );
         Write ('Brief introduction : '); ReadLn (Intro    );
      End;

      CurrentPointer^. NextField := Nil;   {Ensure & set next node to nil}
      If FirstPointer = Nil Then           {Is first node empty?         }
         FirstPointer := CurrentPointer    {Setting the first node       }
      Else
      Begin
         TempPointer := FirstPointer;
         While TempPointer^. NextField <> Nil Do
            TempPointer := TempPointer^. NextField;     {Set next node}
         TempPointer^. NextField := CurrentPointer;
      End;
      Write ('Add more (y/n) ?   : '); ReadLn (Continue);
      Continue := UpCase (Continue);
      While (Continue <> 'Y') And (Continue <> 'N') Do
      Begin
         WriteLn ('Invalid! Accept Y/N only');
         Write   ('Add more (y/n) ? : '); ReadLn (Continue);
         Continue := UpCase (Continue);
         Delay (300);
      End;
   Until Continue = 'N';
End;


{************************************************************************
  Procedure Name : DelRecord
  Input : Invoke by readlist procedure to delete current record.
  Task  : Delete current record from record and.
  Output: Current book record will be remove from the main book record.
************************************************************************* }
Procedure DelRecord (Var RecordToDelete : ListPointer);

Var
   CurrentPointer, PreviousPointer : ListPointer;
   
Begin
   CurrentPointer := FirstPointer;
   While (CurrentPointer <> RecordToDelete) And (CurrentPointer <> Nil) Do
   Begin
      PreviousPointer := CurrentPointer;
      CurrentPointer := CurrentPointer^. NextField;
   End;
   If CurrentPointer <> Nil Then { NIL would mean "not found" }
   Begin
      If CurrentPointer = FirstPointer Then { Is it the first Record? }
         FirstPointer := CurrentPointer^. NextField
      Else
         PreviousPointer^. NextField := CurrentPointer^. NextField;
   End;
   RecordToDelete := CurrentPointer^. NextField;
   Dispose (CurrentPointer);
End;


{************************************************************************
  Procedure Name : Readlist
  Input : Invoke by main_menu procedure to display all the records.
  Task  : Read and display the contents of the list.
  Output: Display all the books informations in the record, one at a time.
************************************************************************* }
Procedure ReadList;


Var
   CurrentPointer : ListPointer;
   Purchase       : Char;
   ViewNext       : Char;
   
Begin
   CurrentPointer := FirstPointer;
   WriteLn ('The contents of the list: ');
   If currentpointer = Nil Then
   Begin
      WriteLn;
      WriteLn ('The bookcase is empty');
      Delay (800);
   End;
   While CurrentPointer <> Nil Do
   Begin
      With CurrentPointer^. DataField Do
      Begin
         WriteLn;
         Write ('Bookname             : '); WriteLn (bookname);
         Write ('Author               : '); WriteLn (author);
         Write ('Publisher            : '); WriteLn (publisher);
         Write ('Publication year     : '); WriteLn (Year);
         Write ('Size                 : '); WriteLn (Size);
         Write ('Pages                : '); WriteLn (pages);
         Write ('Sale price           : '); WriteLn ('$', price : 4 : 2);
         Write ('Brief introduction   : '); WriteLn (intro);
         Write ('Purchase (y/n)?      : '); ReadLn (purchase);
         Repeat
            purchase := UpCase (purchase);
            If Not (purchase In ['Y', 'N'] ) Then
            Begin
               WriteLn ('Invalid! Accept Y/N only');
               Write ('Purchase (y/n)? : '); ReadLn (purchase);
            End;
         Until (purchase = 'N') Or (purchase = 'Y');
         If purchase = 'Y' Then
            Delrecord (currentpointer) {This currentpointer record will be}
         Else                          {pass to the delrecord procedure   }
            CurrentPointer := CurrentPointer^. NextField;
      End;
     
      Write ('View the next (y/n)? : '); ReadLn (viewnext);
      Repeat
         viewnext := UpCase (viewnext);
         If Not (viewnext In ['Y', 'N'] ) Then
         Begin
            WriteLn ('Invalid! Accept Y/N only');
            Write ('View the next (y/n)? : '); ReadLn (viewnext);
         End;
      Until (viewnext = 'N') Or (viewnext = 'Y');
     
      If viewnext = 'Y' Then
      Begin
         If currentpointer = Nil Then
            currentpointer := firstpointer;
         Continue;
      End
      Else
         If viewnext = 'N' Then
            CurrentPointer := FirstPointer;
      Exit;
   End;
End;



{************************************************************************
  Procedure Name : Sold
  Input : Invoke by main menu of the program.
  Task  : It keep track of all the book purchased during the view book
          procedure where user have the option to purchase the book.
  Output: Display all the book purchased by the user.
************************************************************************* }
Procedure Sold;
Begin
End;


{************************************************************************
  Procedure Name : Search
  Input : Invoke by main menu of the program.
  Task  : Using year field in the record, the program will search through
          all the records and display results that match the query.
  Output: Display all the book based on the year input by the user.
************************************************************************* }
Procedure Search;

Var
   found          : Boolean;
   bk_year        : Integer;
   PreviousPointer: ListPointer;
   CurrentPointer : ListPointer;
   Again          : Char;
   Input          : Char;
   
Begin
   Repeat
      Repeat
         Found := False;
         Write ('Please input the year of the book (1900-2000) > '); ReadLn (bk_year);
      Begin
         PreviousPointer := Nil;
         CurrentPointer := FirstPointer;
         While (CurrentPointer <> Nil) And (Not Found) Do
            If CurrentPointer^. DataField. Year = bk_year Then
               Found := True
            Else
            Begin
               PreviousPointer := CurrentPointer;
               CurrentPointer := CurrentPointer^. NextField
            End
      End;

      If Not Found Then
      Begin
         WriteLn ('Sorry no book published in ', bk_year, ' is for sale');
         Repeat
            Write ('Press "y" to try again : ');     ReadLn (again);
            If Not (again  In ['Y', 'y'] ) Then
            Begin
               WriteLn ('Press "y" to try again : ');
            End;
           
         Until (again In ['y', 'Y'] );
      End
      Else
         With CurrentPointer^. DataField Do
         Begin
            WriteLn;
            Write ('Bookname             : '); WriteLn (bookname);
            Write ('Author               : '); WriteLn (author);
            Write ('Publisher            : '); WriteLn (publisher);
            Write ('Publication year     : '); WriteLn (Year);
            Write ('Size                 : '); WriteLn (Size);
            Write ('Pages                : '); WriteLn (pages);
            Write ('Sale price           : '); WriteLn ('$', price : 4 : 2);
            Write ('Brief introduction   : '); WriteLn (intro);
            Write ('Press "m" to return to Main Menu > ');
            ReadLn (Input);
            Input := UpCase (Input);  {allow m or M to be accepted}
           
         End;
     
   Until found = True;
   Until (Input = 'M');
End;


{************************************************************************
  Procedure Name : Main_Menu
  Input : Invoke by main body of the program.
  Task  : It display to use the choices he can do, input books records,
          reset book records or view and purchase the books.
  Output: Display the main menu of the program and awaits user inputs.
************************************************************************* }
Procedure Main_Menu;

Var
   Option : Char ;
   
Begin
   Repeat
      ClrScr;
      WriteLn ('Books for Sale');
      WriteLn ('--------------');
      WriteLn ('1. View books');
      WriteLn ('2. Initialise bookcase');
      WriteLn ('3. Add Books');
      WriteLn ('4. Display the books sold');
      WriteLn ('5. Search a book');
      WriteLn ('0. Quit');
      Write ('Enter your choice > '); ReadLn (Option);
     
      Case Option Of
         '1': Readlist;
         '2': Initialise;
         '3': Addbook;
         '4': Sold;
         '5': Search;
         '0': Exit
         Else
            Write ('Invalid Choice, Please enter 1, 2, 3 or 0');
         Delay (300);
         ClrScr;
      End;
   Until Option = '0';
End;


{*********************************************************************}
{Main Body of the Program}
{*********************************************************************}
Begin
   ClrScr;     {Ensure the program start in a fresh new screen}
   Main_menu
End.

Avatar of dbrunton
dbrunton
Flag of New Zealand image

And the question is?



Avatar of My name is Mud
My name is Mud

Program Books;
Uses
  Crt;     {Use because of clear screen command used}
Type
  DataRecord = Record
    Bookname  : String [50];
    Author    : String [30];
    Publisher : String [30];
    Year      : Integer    ;
    Size      : String [ 2];
    Pages     : Integer    ;
    Price     : Real       ;
    Intro     : String [30];
  End;  {end of record}

ListPointer = ^ListRecord;

ListRecord  = Record
  DataField : DataRecord;  {data field type}
  PrevField : ListPointer; {Just Add a double link <- Data ->}
  NextField : ListPointer  {pointer address to next book}
End;

Var
  FirstPointer : ListPointer;
  LastPointer  : ListPointer;

{ Procedure to sort the list using the bubble sort method }
Procedure Sort_List;
Var
  Index1,Index2: Integer;
  MaxNum: Integer;
  Previous: ListPointer;
  Current: ListPointer;

  { Function to count the number of items in the list.}
  Function Count_Items: Integer;
  Var
    I: Integer;
    CurrentPointer : ListPointer;
  Begin
    CurrentPointer:=FirstPointer;
    I:=0;
    While CurrentPointer <> Nil Do
      Begin
        I:=I+1;
        CurrentPointer:=CurrentPointer^.NextField;
      End;
    Count_Items:=I;
  End;

  Procedure ChangePlaces(Var Prev,Curr: ListPointer);
  Var
    Temp: DataRecord;
  Begin
    Temp:=Prev^.DataField;
    Prev^.DataField:=Curr^.DataField;
    Curr^.DataField:=Temp;
  End;

Begin
  MaxNum:=Count_Items;
  If MaxNum > 1 then
    Begin
      Previous:=FirstPointer;
      Current:=LastPointer;
      For Index1:=1 To MaxNum-1 Do
        Begin
          For Index2:=MaxNum DownTo Index1+1 Do
            Begin
              If Previous^.DataField.Year > Current^.DataField.Year Then
                ChangePlaces(Previous,Current);
              Current:=Current^.PrevField
            End;
          Previous:=Previous^.NextField;
          Current:=LastPointer
        End
    End
End;

Procedure ViewAll;
Var
  Current: ListPointer;
Begin
  Current:=FirstPointer;
  While Current <> NIL Do
    Begin
      With Current^.DataField Do
        Begin
          Write(Year,' ');
          Write(Bookname,' ');
          Write(Author,' ');
          Write(Publisher,' ');
          Write(Size,' ');
          Write(Pages,' ');
          Write(Price,' ');
          WriteLn(Intro,' ');
        End;
      Current:=Current^.NextField
   End;
  WriteLn(#10#13'Press Enter to go to Menu'); ReadLn
End;

{************************************************************************
Procedure Name : Initialise
Input : Invoke by main program to do initialise all the pointers.
Task  : Initialise and set the relationship for current, firstpointer
,nextfield and clear data that may exist in currentpointer
Output: It will reset and clear all data present in the records/pointers.
************************************************************************* }
Procedure Initialise;
Var
  Input          : Char;
  CurrentPointer : ListPointer;
Begin
  While Assigned (FirstPointer) Do   {Test if a pointer variable is nil}
    Begin
      CurrentPointer := FirstPointer;   {Force current pointer to first node}
      FirstPointer   := FirstPointer^. NextField;
      Dispose (CurrentPointer);         {Once first node deleted, rest also}
    End;
  WriteLn ('The bookcase is Empty but ready for books.');
  Repeat
    Write ('Press "m" to return to Main Menu > ');
    ReadLn (Input);
    Input := UpCase (Input);  {allow m or M to be accepted}
  Until Input = 'M'
End;

{************************************************************************
Procedure Name : Addbook
Input : Invoke by main program to do capturing of all books.
Task  : Accept user input on the books and save it to the record.
Output: Record will hold all the data and store into memory
************************************************************************* }
Procedure Addbook;
Var
  CurrentPointer, TempPointer : ListPointer;
  Continue : Char;
Begin
  Repeat
    New (CurrentPointer);             {Creates a new dynamic variable}
    With CurrentPointer^. DataField Do
      Begin
        WriteLn;
        WriteLn ('Please input details including');
        Write ('Bookname           : '); ReadLn (Bookname );
        Write ('Author             : '); ReadLn (Author   );
        Write ('Publisher          : '); ReadLn (Publisher);
        Write ('Publication year   : '); ReadLn (Year     );
        Write ('Size               : '); ReadLn (Size     );
        Write ('Pages              : '); ReadLn (Pages    );
        Write ('Sale price         : '); ReadLn (Price    );
        Write ('Brief introduction : '); ReadLn (Intro    );
      End;
    CurrentPointer^. NextField := Nil;   {Ensure & set next node to nil}
    If FirstPointer = Nil Then           {Is first node empty?         }
      Begin
        CurrentPointer^.PrevField:=NIL;
        FirstPointer := CurrentPointer    {Setting the first node       }
      End
    Else
      Begin
        TempPointer := FirstPointer;
        While TempPointer^. NextField <> Nil Do
          TempPointer := TempPointer^. NextField;     {Set next node}
        TempPointer^. NextField := CurrentPointer;
        CurrentPointer^.PrevField:=TempPointer;
      End;

    {Add this line to know where the Link Ends}
    LastPointer:=CurrentPointer;

    Write ('Add more (y/n) ?   : '); ReadLn (Continue);
    Continue := UpCase (Continue);
    While (Continue <> 'Y') And (Continue <> 'N') Do
      Begin
        WriteLn ('Invalid! Accept Y/N only');
        Write   ('Add more (y/n) ? : '); ReadLn (Continue);
        Continue := UpCase (Continue);
        Delay (300);
      End;
  Until Continue = 'N';
End;

{************************************************************************
Procedure Name : DelRecord
Input : Invoke by readlist procedure to delete current record.
Task  : Delete current record from record and.
Output: Current book record will be remove from the main book record.
************************************************************************* }
Procedure DelRecord (Var RecordToDelete : ListPointer);
Var
  CurrentPointer, PreviousPointer : ListPointer;
Begin
  CurrentPointer := FirstPointer;
  While (CurrentPointer <> RecordToDelete) And (CurrentPointer <> Nil) Do
    Begin
      PreviousPointer := CurrentPointer;
      CurrentPointer := CurrentPointer^. NextField;
    End;
  If CurrentPointer <> Nil Then { NIL would mean "not found" }
    Begin
      If CurrentPointer = FirstPointer Then { Is it the first Record? }
        FirstPointer := CurrentPointer^. NextField
      Else
        PreviousPointer^. NextField := CurrentPointer^. NextField;
    End;
  RecordToDelete := CurrentPointer^. NextField;
  Dispose (CurrentPointer);
End;

{************************************************************************
Procedure Name : Readlist
Input : Invoke by main_menu procedure to display all the records.
Task  : Read and display the contents of the list.
Output: Display all the books informations in the record, one at a time.
************************************************************************* }
Procedure ReadList;
Var
  CurrentPointer : ListPointer;
  Purchase       : Char;
  ViewNext       : Char;
Begin
  CurrentPointer := FirstPointer;
  WriteLn ('The contents of the list: ');
  If currentpointer = Nil Then
    Begin
      WriteLn;
      WriteLn ('The bookcase is empty');
      Delay (800);
    End;
  While CurrentPointer <> Nil Do
    Begin
      With CurrentPointer^. DataField Do
        Begin
          WriteLn;
          WriteLn ('Bookname             : ',bookname);
          WriteLn ('Author               : ',author);
          WriteLn ('Publisher            : ',publisher);
          WriteLn ('Publication year     : ',Year);
          WriteLn ('Size                 : ',Size);
          WriteLn ('Pages                : ',pages);
          WriteLn ('Sale price           : ','$',price:4:2);
          WriteLn ('Brief introduction   : ',intro);
          Write ('Purchase (y/n)?      : '); ReadLn (purchase);
          Repeat
            purchase := UpCase (purchase);
            If Not (purchase In ['Y', 'N'] ) Then
              Begin
                WriteLn ('Invalid! Accept Y/N only');
                Write ('Purchase (y/n)? : '); ReadLn (purchase);
              End;
          Until (purchase = 'N') Or (purchase = 'Y');
          If purchase = 'Y' Then
            Delrecord (currentpointer) {This currentpointer record will be}
          Else                          {pass to the delrecord procedure   }
            CurrentPointer := CurrentPointer^. NextField;
        End;
      Write ('View the next (y/n)? : '); ReadLn (viewnext);
      Repeat
        viewnext := UpCase (viewnext);
        If Not (viewnext In ['Y', 'N'] ) Then
          Begin
            WriteLn ('Invalid! Accept Y/N only');
            Write ('View the next (y/n)? : '); ReadLn (viewnext);
          End;
      Until (viewnext = 'N') Or (viewnext = 'Y');
      If viewnext = 'Y' Then
        Begin
          If currentpointer = Nil Then
            currentpointer := firstpointer;
          Continue;
        End
      Else
        If viewnext = 'N' Then
          CurrentPointer := FirstPointer;
          Exit;
    End;
End;

{************************************************************************
Procedure Name : Sold
Input : Invoke by main menu of the program.
Task  : It keep track of all the book purchased during the view book
        procedure where user have the option to purchase the book.
Output: Display all the book purchased by the user.
************************************************************************* }
Procedure Sold;
Begin
End;

{************************************************************************
Procedure Name : Search
Input : Invoke by main menu of the program.
Task  : Using year field in the record, the program will search through
        all the records and display results that match the query.
Output: Display all the book based on the year input by the user.
************************************************************************* }
Procedure Search;
Var
  found          : Boolean;
  bk_year        : Integer;
  PreviousPointer: ListPointer;
  CurrentPointer : ListPointer;
  Again          : Char;
  Input          : Char;
Begin
  Repeat
    Repeat
      Found := False;
      Write ('Please input the year of the book (1900-2000) > ');
      ReadLn (bk_year);
      PreviousPointer := Nil;
      CurrentPointer := FirstPointer;
      While (CurrentPointer <> Nil) And (Not Found) Do
        If CurrentPointer^. DataField. Year = bk_year Then
          Found := True
        Else
          Begin
            PreviousPointer := CurrentPointer;
            CurrentPointer := CurrentPointer^. NextField
          End;
      If Not Found Then
        Begin
          WriteLn ('Sorry no book published in ', bk_year, ' is for sale');
          Repeat
            Write ('Press "y" to try again : ');     ReadLn (again);
            If Not (again  In ['Y', 'y'] ) Then
              WriteLn ('Press "y" to try again : ');
          Until (again In ['y', 'Y'] );
        End
      Else
        With CurrentPointer^. DataField Do
          Begin
            WriteLn;
            Write ('Bookname             : '); WriteLn (bookname);
            Write ('Author               : '); WriteLn (author);
            Write ('Publisher            : '); WriteLn (publisher);
            Write ('Publication year     : '); WriteLn (Year);
            Write ('Size                 : '); WriteLn (Size);
            Write ('Pages                : '); WriteLn (pages);
            Write ('Sale price           : '); WriteLn ('$', price : 4 : 2);
            Write ('Brief introduction   : '); WriteLn (intro);
            Write ('Press "m" to return to Main Menu > ');
            ReadLn (Input);
            Input := UpCase (Input);  {allow m or M to be accepted}
          End;
    Until found = True;
  Until (Input = 'M');
End;

{************************************************************************
Procedure Name : Main_Menu
Input : Invoke by main body of the program.
Task  : It display to use the choices he can do, input books records,
        reset book records or view and purchase the books.
Output: Display the main menu of the program and awaits user inputs.
************************************************************************* }
Procedure Main_Menu;
Var
  Option : Char ;
Begin
  Repeat
    ClrScr;
    WriteLn ('Books for Sale');
    WriteLn ('--------------');
    WriteLn ('1. View books');
    WriteLn ('2. Initialise bookcase');
    WriteLn ('3. Add Books');
    WriteLn ('4. Display the books sold');
    WriteLn ('5. Search a book');
    WriteLn ('6. Sort_List');
    WriteLn ('7. View all Records');
    WriteLn ('0. Quit');
    Write ('Enter your choice > '); ReadLn (Option);
    Case Option Of
      '1': Readlist;
      '2': Initialise;
      '3': Addbook;
      '4': Sold;
      '5': Search;
      '6': Sort_List;
      '7': ViewAll;
      '0': Exit
    Else
      Write ('Invalid Choice, Please enter 1, 2, 3 or 0');
      Delay (300);
      ClrScr;
    End;
  Until Option = '0';
End;

{*********************************************************************}
{Main Body of the Program}
{*********************************************************************}
Begin
  ClrScr;     {Ensure the program start in a fresh new screen}
  Main_menu
End.
ASKER CERTIFIED SOLUTION
Avatar of My name is Mud
My name is Mud

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial