Hi, I'm trying to learn delphi. I'm writing a binary tree unit and so far I only have insert and check size. I'm having trouble with inserting a new node into a nonempty tree. Got access violation at runtime and while in debugging mode, the value of sRoot^.Data is in accessible. Can anyone help explain the problem and way to fix? Thanks

unit BST;

interface
  { Node Class }
  type
    NodePtr = ^binNode;
    binNode = class
      Data : Integer;
      Left : NodePtr;
      Right: NodePtr;
    constructor Create(nData : Integer); overload;
    constructor Create(nData : Integer; nLeft,nRight : NodePtr); overload;
    function isLeaf : boolean;
    end;
  { Tree Class }
  type
    binTree = class
      private
        root : NodePtr;
        sz : Integer;
        procedure insertHelper(nData : Integer;var sRoot : NodePtr);
      public
        property Size : Integer read sz;
        constructor Create; overload;
        constructor Create(nData : Integer); overload;
        function isEmpty : boolean;
        procedure Insert(nData : Integer);
    end;

implementation
{ Implementation for Node class }
constructor binNode.Create(nData:Integer);
begin
  Data := nData;
  Left := nil;
  Right:= nil;
end;
constructor binNode.Create(nData:Integer; nLeft,nRight: NodePtr);
begin
  Data := nData;
  Left := nLeft;
  Right:= nRight;
end;
function binNode.isLeaf : boolean;
begin
  if (Left = nil) and (Right = nil) then
    Result := True
  else
    Result := False;
end;
{ Implementation for BST class }
constructor binTree.Create;
begin
  root := nil;
  sz := 0;
end;
constructor binTree.Create(nData:Integer);
var
  bNde: binNode;
begin
  bNde := binNode.Create(nData);
  root := @bNde;
  sz := 1;
end;
// Check if the tree is empty
function binTree.isEmpty : boolean;
begin
  if (sz = 0) then
    Result := True
  else
    Result := False;
end;
// Public insertion method. No duplicate data
procedure binTree.Insert(nData : Integer);
var
  tNode : binNode;
begin
  if (isEmpty) then
  begin
    tNode := binNode.Create(nData);
    root := @tNode;
    sz := sz + 1;
  end
  else
    insertHelper(nData, root);
end;
// Helper method for insertion
procedure binTree.insertHelper(nData : Integer;var sRoot : NodePtr);
var
  tNode : binNode;
begin
  if (sRoot = nil) then
  begin
    tNode := binNode.Create(nData);
    sRoot := @tNode;
    sz := sz + 1;
  end
  else
  begin
    if (nData < sRoot^.Data) then       // insert to left child
      insertHelper(nData,sRoot^.Left);
    if (nData > sRoot^.Data) then       // insert to right child
      insertHelper(nData,sRoot^.Right)
    else
      // do nothing since it's a duplicate
  end;
end;

end.
program dataStructures;

uses
  Forms,Dialogs,SysUtils,
  main in 'main.pas' {Form1},
  BST in 'BST.pas';

{$R *.res}

var
  myBST : binTree;
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);

  myBST := binTree.Create(1);
  if (myBST.isEmpty) then
    ShowMessage('Empty Tree created. Size is ' + IntToStr(myBST.Size))
  else
    ShowMessage('Tree created. Size is ' + IntToStr(myBST.Size));

  myBST.Insert(5);
  ShowMessage('Inserted. Size now is: ' + IntToStr(myBST.Size));
  //myBST.Insert(3);
  //ShowMessage('Inserted. Size now is: ' + IntToStr(myBST.Size));

  Application.Run;
end.

Solved.

Look like I had some errors in referencing and dereferencing pointers to the nodes. I fixed this by not using pointers but making reference to the nodes directly to binNode. So the line

NodePtr = ^binNode

is removed and all occurrences of NodePtr are replaced by binNode.

However, if you have any suggestions or comments on how to do this with pointers, feel free to add

Edited 5 Years Ago by mmhp: n/a

This question has already been answered. Start a new discussion instead.