Computer Science Canada

Pointer Help for deleting from a list

Author:  ChaoticOne [ Thu Mar 30, 2006 10:25 am ]
Post subject:  Pointer Help for deleting from a list

Okay, we have this assignment in class to use pointers to create a manipulate a list. The last part is delete, I've been working on it for a week now and just can't seem to figure it out. Any help is appreciated.

code:
%Display Menu
procedure displayMenu
    put "1. Add a new student to the tree"
    put "2. Load tree from record file"
    put "3. List all records in the tree"
    put "4. List a specific student"
    put "5. Delete a student"
    put "9. Exit"
end displayMenu

%Make the record
type StudentRecType :
    record
        StudentNum : int
        SurName : string (10)
        FirstName : string (10)
        Average : real
    end record

%Pointer Record
type StudentLinkRecType :
    record
        StudentNum : int
        SurName : string (10)
        FirstName : string (10)
        Average : real
        %Greater than Side pointer and Less than Side pointer
        LT : ^StudentLinkRecType
        GT : ^StudentLinkRecType
    end record

%add proc for loading which will set root to the lowest rLinked
proc add (var root, nr : ^StudentLinkRecType)
    %Recursive until root = nil, which will then be set to nr
    if root = nil then
        root := nr
    elsif (root -> StudentNum) < (nr -> StudentNum) then
        add (root -> GT, nr)
    else
        add (root -> LT, nr)
    end if
end add

%Load Students
procedure loadStudents (var root : ^StudentLinkRecType)
    %Point root at empty
    root := nil
    var stream : int := 0
    %Open the record file
    open : stream, "i:/Ics4/Turing/students.rec", read
    var r : StudentRecType
    var rLinked : ^StudentLinkRecType
    var FileIsEmpty : boolean := true
    loop
        exit when eof (stream)
        read : stream, r
        FileIsEmpty := false
        %Add to list
        new rLinked
        rLinked -> StudentNum := r.StudentNum
        rLinked -> SurName := r.SurName
        rLinked -> FirstName := r.FirstName
        rLinked -> Average := r.Average
        rLinked -> LT := nil
        rLinked -> GT := nil
        add (root, rLinked)
    end loop
    close : stream
    if FileIsEmpty = true then
        put "File is Empty"
    end if
end loadStudents

%Display the tree in order according to student number
proc displayStudents (root : ^StudentLinkRecType)
    %If the less than is not nil there is another rec smaller
    if (root -> LT not= nil) then
        %recall display pointing root at the smaller rec
        displayStudents (root -> LT)
    end if
    %Display Student, note it will be the smallest from above call
    put root -> StudentNum : 10, " " : 10, root -> SurName + ", " + root -> FirstName : 25, root -> Average : 5 : 1
    %Now checking right side of tree, check if there is anything greater
    if (root -> GT not= nil) then
        displayStudents (root -> GT)
    end if
end displayStudents

%Add Student to List
proc addStudent (var root, adding : ^StudentLinkRecType)
    %%% RECURSIVE PRODECDURE%%%
    %Send pointer data to list, add student in
    add (root, adding)
end addStudent

%List Specific Student
proc listStudent (root : ^StudentLinkRecType, num : int, var exist : boolean)
    %Search for left side of tree
    if (root -> LT not= nil) then
        %recall listStudent pointing root at the smaller data
        listStudent (root -> LT, num, exist)
    end if
    %List the student if numbers match
    if (root -> StudentNum = num) then
        exist := false
        put root -> StudentNum : 10, " " : 10, root -> SurName + ", " + root -> FirstName : 25, root -> Average : 5 : 1
    end if
    %Now search right side of tree
    if (root -> GT not= nil) then
        listStudent (root -> GT, num, exist)
    end if
end listStudent

%Delete Student
proc delStudent (var root, delr,temp : ^StudentLinkRecType, var c : int)
    %Check if the student number is equal
    if (root -> StudentNum = delr -> StudentNum) then
        if (root -> LT = nil) and c not= 2 then
            root := delr -> GT
            c := 2
        else
            root := delr -> LT
            c := 1
        end if
    elsif (root -> StudentNum) > (delr -> StudentNum) and c = 0 then
        delStudent (root -> LT, delr,temp, c)
    elsif (root -> StudentNum) < (delr -> StudentNum) then
        delStudent (root -> GT, delr,temp, c)
    end if
end delStudent

%Main Program
var root : ^StudentLinkRecType
root := nil
var SearchNum : int
loop
    var choice : string (1)
    displayMenu
    put "Enter choice: " ..
    getch (choice)
    put ""
    put ""
    case (choice) of
        label "1" :
            %Create a new temporary pointer to store data
            var temproot : ^StudentLinkRecType
            new temproot
            %Store the data into the pointer, student information
            put "Enter the student's number: " ..
            get temproot -> StudentNum
            put "Enter the student's last name: " ..
            get temproot -> SurName
            put "Enter the student's first name: " ..
            get temproot -> FirstName
            put "Enter the student's average: " ..
            get temproot -> Average
            %Set greater and less to nil
            temproot -> GT := nil
            temproot -> LT := nil
            %add student procedure, using root from original program and temporary pointer's data
            addStudent (root, temproot)
            put "Student has been added."
        label "2" :
            loadStudents (root)
            put "Students loaded."
        label "3" :
            if root = nil then
                put "No students in list."
            else
                displayStudents (root)
            end if
        label "4" :
            if root = nil then
                put "No students in list."
            else
                put "Enter the student's number"
                var exist : boolean := true
                get SearchNum
                listStudent (root, SearchNum, exist)
                if exist = true then
                    put "Student does not exist"
                end if
            end if
        label "5" :
            %Create a new temporary pointer to store data and the data to delete
            var delr,temp : ^StudentLinkRecType
            new delr
            new temp
            %Store the data into the pointer, student information
            put "Enter the student's number: " ..
            get delr -> StudentNum
            %Set greater and less to nil
            delr -> GT := nil
            delr -> LT := nil
            temp -> LT := nil
            temp -> GT := nil
            var check : int := 0
            delStudent (root, delr, temp,check)           
        label "9" :
        label :
            put "Invalid choice"
    end case
    exit when choice = "9"
    put ""
    put "Press any key to continue"
    getch (choice)
    cls
end loop
put ""
put "Program ended"

The part I need help with is the delStudent procedure, it works if no other students located in the LT or GT. Soo anyone have any ideas Shocked ?

Author:  Delos [ Thu Mar 30, 2006 3:04 pm ]
Post subject: 

Well, I tested it a few times, and I may have gotten some form of error on the first run. Subsequently, it has been working fine. So I probably am not repeating the correct steps to produce the error.
On the first run I believe I added 2 records, deleted one, but the programme delete both. I've tried replicating but each time it works perfectly fine.

Could you explain how you got your error a bit clearer?

Anyhow, some general comments on the code (which is pretty awsome by the way. I'm surprised you're being taught this stuff at school, these are some very powerful concepts).

code:

type StudentRecType :
    record
        StudentNum : int
        SurName : string (10)
        FirstName : string (10)
        Average : real
    end record

%Pointer Record
type StudentLinkRecType :
    record
        StudentNum : int
        SurName : string (10)
        FirstName : string (10)
        Average : real
        %Greater than Side pointer and Less than Side pointer
        LT : ^StudentLinkRecType
        GT : ^StudentLinkRecType
    end record


This little ditty would be a little easier on the eyes as:

code:

%Pointer Record
type StudentLinkRecType :
    record
        this : ^StudentLinkRecType
        %Greater than Side pointer and Less than Side pointer
        LT : ^StudentLinkRecType
        GT : ^StudentLinkRecType
    end record


Of course the 'this' is just a word that seemed to fit (and is used other languages too).

code:

if exist = true then
     put "Student does not exist"
end if

% Same as:

if exist then
   %...
   % A little counter-intuitive though?

It's a little odd that 'exist' is used to denote the lack of existance!

You need to error proof your Delete proc a little, if someone tries to run it when no records have been added, it will crash ("Reference through nil pointer" - Turing).
For the Load from File proc, why not allow the User to load from a specified file. I figure that you'll add that later, and this is just a pre-alpha copy you're working on...right?

Good job though. Try to replicate and describe your error a bit better and we'll see what we can do.


: