| 
 
 
unit Unit1;
 interface
 
 uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;
 
 type
 TMyObjectPtr = ^TMyObject;
 TMyObject = record
 First_Name: String[20];
 Last_Name: String[20];
 Next: TMyObjectPtr;
 end;
 
 type
 TForm1 = class(TForm)
 bSortByLastName: TButton;
 bDisplay: TButton;
 bPopulate: TButton;
 ListBox1: TListBox;
 bClear: TButton;
 procedure bSortByLastNameClick(Sender: TObject);
 procedure bPopulateClick(Sender: TObject);
 procedure bDisplayClick(Sender: TObject);
 procedure bClearClick(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
 
 var
 Form1: TForm1;
 pStartOfList: TMyObjectPtr = nil;
 
 {List manipulation routines}
 procedure SortMyObjectListByLastName(var aStartOfList: TMyObjectPtr);
 function CreateMyObject(aFirstName, aLastName: String): TMyObjectPtr;
 procedure AppendMyObject(var aCurrentItem, aNewItem: TMyObjectPtr);
 procedure ClearMyObjectList(var aMyObject: TMyObjectPtr);
 procedure RemoveMyObject(var aStartOfList, aRemoveMe: TMyObjectPtr);
 function AreInAlphaOrder(aString1, aString2: String): Boolean;
 
 
 implementation
 
 {$R *.DFM}
 
 
 procedure TForm1.bClearClick(Sender: TObject);
 begin
 ClearMyObjectList(pStartOfList);
 end;
 
 procedure TForm1.bPopulateClick(Sender: TObject);
 var
 pNew: TMyObjectPtr;
 begin
 {Initialize the list with some static data}
 pNew := CreateMyObject('Suzy','Martinez');
 AppendMyObject(pStartOfList, pNew);
 pNew := CreateMyObject('John','Sanchez');
 AppendMyObject(pStartOfList, pNew);
 pNew := CreateMyObject('Mike','Rodriguez');
 AppendMyObject(pStartOfList, pNew);
 pNew := CreateMyObject('Mary','Sosa');
 AppendMyObject(pStartOfList, pNew);
 pNew := CreateMyObject('Betty','Hayek');
 AppendMyObject(pStartOfList, pNew);
 pNew := CreateMyObject('Luke','Smith');
 AppendMyObject(pStartOfList, pNew);
 pNew := CreateMyObject('John','Sosa');
 AppendMyObject(pStartOfList, pNew);
 end;
 
 procedure TForm1.bSortByLastNameClick(Sender: TObject);
 begin
 SortMyObjectListByLastName(pStartOfList);
 end;
 
 procedure TForm1.bDisplayClick(Sender: TObject);
 var
 pTemp: TMyObjectPtr;
 begin
 {Display the list items}
 ListBox1.Items.Clear;
 pTemp := pStartOfList;
 while pTemp <> nil do
 begin
 ListBox1.Items.Add(pTemp^.Last_Name + ', ' + pTemp.First_Name);
 pTemp := pTemp^.Next;
 end;
 end;
 
 procedure ClearMyObjectList(var aMyObject: TMyObjectPtr);
 var
 TempMyObject: TMyObjectPtr;
 begin
 {Free the memory used by the list items}
 TempMyObject := aMyObject;
 while aMyObject <> nil do
 begin
 aMyObject := aMyObject^.Next;
 Dispose(TempMyObject);
 TempMyObject := aMyObject;
 end;
 end;
 
 function CreateMyObject(aFirstName, aLastName: String): TMyObjectPtr;
 begin
 {Instantiate a new list item}
 new(result);
 result^.First_Name := aFirstName;
 result^.Last_Name := aLastName;
 result^.Next := nil;
 end;
 
 procedure SortMyObjectListByLastName(var aStartOfList: TMyObjectPtr);
 var
 aSortedListStart, aSearch, aBest: TMyObjectPtr;
 begin
 {Sort the list by the Last_Name "field"}
 aSortedListStart := nil;
 while (aStartOfList <> nil) do
 begin
 aSearch := aStartOfList;
 aBest := aSearch;
 while aSearch^.Next <> nil do
 begin
 if not AreInAlphaOrder(aBest^.Last_Name, aSearch^.Last_Name) then
 aBest := aSearch;
 aSearch := aSearch^.Next;
 end;
 RemoveMyObject(aStartOfList, aBest);
 AppendMyObject(aSortedListStart, aBest);
 end;
 aStartOfList := aSortedListStart;
 end;
 
 procedure AppendMyObject(var aCurrentItem, aNewItem: TMyObjectPtr);
 begin
 {Recursive function that appends the new item to the end of the list}
 if aCurrentItem = nil then
 aCurrentItem := aNewItem
 else
 AppendMyObject(aCurrentItem^.Next, aNewItem);
 end;
 
 procedure RemoveMyObject(var aStartOfList, aRemoveMe: TMyObjectPtr);
 var
 pTemp: TMyObjectPtr;
 begin
 {Removes a specific item from the list and collapses the empty spot.}
 pTemp := aStartOfList;
 if pTemp = aRemoveMe then
 aStartOfList := aStartOfList^.Next
 else
 begin
 while (pTemp^.Next <> aRemoveMe) and (pTemp^.Next <> nil) do
 pTemp := pTemp^.Next;
 if pTemp = nil then Exit; //Shouldn't ever happen
 if pTemp^.Next = nil then Exit; //Shouldn't ever happen
 pTemp^.Next := aRemoveMe^.Next;
 end;
 aRemoveMe^.Next := nil;
 end;
 
 function AreInAlphaOrder(aString1, aString2: String): Boolean;
 var
 i: Integer;
 begin
 {Returns True if aString1 should come before aString2 in an alphabetic ascending sort}
 Result := True;
 
 while Length(aString2) < Length(aString1) do  aString2 := aString2 + '!';
 while Length(aString1) < Length(aString2) do  aString1 := aString1 + '!';
 
 for i := 1 to Length(aString1) do
 begin
 if aString1[i] > aString2[i] then Result := False;
 if aString1[i] <> aString2[i] then break;
 end;
 end;
 
 end.
 
 
   |