★★★书上的一道关于链表的例题,请大家看一看,谢谢了。我给100分!不来后悔!!(100分)

B

bcfans

Unregistered / Unconfirmed
GUEST, unregistred user!
★★★书上的一道关于链表的例题,请大家看一看,谢谢了。我给100分!不来后悔!!
这个程序用到了一个edit1,一个listbox1和三个按钮,分别是:显示(btnlist)、删除(btndel)、退出(btnquit)。//后面的注释是书上的 {}里的是我写的。为什么只有new 没有dispose,这样可以吗?另外指针这块我没太明白,请您把这个程序解释一下可以吗?给我上上指针的课!!我的电邮是:onlydelphi@hotmail.com MSN是:onlydelphi@hotmail.com


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
ListBox1: TListBox;
Edit1: TEdit;
Btnlist: TButton;
Btndel: TButton;
Btnquit: TButton;
procedure FormCreate(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject
var Key: Char);
procedure BtnlistClick(Sender: TObject);
procedure BtndelClick(Sender: TObject);
procedure BtnquitClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
type
plink=^node;
node=record
data:string[30]
{!!是不是长度为30的字符串类型?}
next:plink;
end;
var
dtrec:plink;
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
dtrec:=nil;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject
var Key: Char);
var
tempp,p:plink;
begin
if key=#13 then //如果按下回车键
begin
new(tempp)
//创建一个节点
tempp^.data:=edit1.text;
tempp^.next:=nil;
if dtrec=nil then //如果链表为空表
begin
new(dtrec)
//创建链表 {!!这句省略可以吗?}
dtrec:=tempp
{!!传的是地址还是值呢?}
end
else //如果链表不为空
begin
p:=dtrec
{!!p怎么没用new过程呢?}
while p^.next<>nil do //找表尾
p:=p^.next
{!!dtrec改变了吗?}
p^.next:=tempp
//将新节点添加到表尾
end;
edit1.Clear
//清编辑框
edit1.SetFocus
//当前活动焦点置回到编辑框上
end;
end;

procedure TForm1.BtnlistClick(Sender: TObject);
var
p:plink;
begin
listbox1.Clear
//清列表框
p:=dtrec;
repeat //遍历列表,将所有节点数据域中的数据赋给listbox1的items属性
listbox1.Items.Add(p^.data);
p:=p^.next;
until p=nil;
end;

procedure TForm1.BtndelClick(Sender: TObject);
var
p,p1:plink;
i:integer;
begin
i:=0;
p:=dtrec;
if p=nil then //如果链表为空表
showmessage('链表为空表')
else
if p^.data=edit1.Text then //如果链表的第一个节点为要删的节点
begin
dtrec:=p^.next;
p^.next:=nil;
p:=dtrec
{!!编译时提示这个p没有用上,怎么回事?}
end
else
begin //如果第一个节点不是要删的节点
p1:=p^.next;
if p1<>nil then
repeat
if p1.data=edit1.Text then //如果找到一个要删的节点
begin
p^.next:=p1^.next;
p1:=p;
i:=i+1;
end
else
begin
p:=p1;
p1:=p1^.next;
end
until p1=nil;
if i=0 then //如果链表不存在要删的节点
showmessage('无匹配的数据');
end;
end;

procedure TForm1.BtnquitClick(Sender: TObject);
begin
close;
end;

end.
 
new(dtrec)
//创建链表 {!!这句省略可以吗?}这句不需要,也不能要!根据不需要再分配空间
dtrec:=tempp
{!!传的是地址还是值呢?}地址
///////////


dtrec:=p^.next;
p^.next:=nil;
dispose(p)
//应该释放空间
p:=dtrec
{!!编译时提示这个p没有用上,怎么回事?}

////////////
if p1.data=edit1.Text then //如果找到一个要删的节点
begin
p^.next:=p1^.next;
p1.next:=nil
//////////
dispose(p1)
////////////
p1:=p;
i:=i+1;
end
以上是明显的问题,先试试吧!!!!!!!
 
unit Unit1;
{以下是我对这段代码的注释,
这段代码结构尚且比较清晰,
如果仍旧有什么不明白的地方,
Email: aliucc@163.com,和我联系。
呵呵。祝你学的愉快!希望对你有所帮助}
interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Btnlist: TButton;
Edit1: TEdit;
ListBox1: TListBox;
Btndel: TButton;
Btnquit: TButton;
procedure FormCreate(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject
var Key: Char);
procedure BtnlistClick(Sender: TObject);
procedure BtndelClick(Sender: TObject);
procedure BtnquitClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
type
plink=^node;
node=record
data:string[30]
{每个节点的内容:长度为30的字符串类型} {!!是不是长度为30的字符串类型?}
next:plink
{指向下一个节点的指针,相当于C语言中的struct结构}
end;
var
dtrec:plink
{dtrec为程序中使用的链表的名称,要对链表进行
任何的操作必须从dtrec出发,依次扫描整个链表结构}

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
dtrec:=nil
{在窗口初始化的时候,将链表的内容置空}
end;

procedure TForm1.Edit1KeyPress(Sender: TObject
var Key: Char);
var
tempp,p:plink;
begin
if key=#13 then //如果按下回车键
begin
new(tempp)
//创建一个节点

tempp^.data:=edit1.text
{将链表的内容置为Edit1.Text的内容,
在这里表明:Edit1.Text的数值不能超过30位}
tempp^.next:=nil
{将该节点指向下一个节点的指针置空}

if dtrec=nil then //如果链表为空表
begin
new(dtrec)
//创建链表 {不可以省略,如果}
{不这么做,那么dtrec就有可能指向内存中的任何一个地址,从而
造成无法预知的错误}
dtrec:=tempp
{将tempp的地址赋值给dtrec,也就是说,dtrec
中保存的是tempp单元的地址}
end
else //如果链表不为空
begin
p:=dtrec
{无需使用new过程,这个指针指向dtrec,也就是链表的
表头,这个时候p的地址就是dtrec的地址,无需在内存中重新开辟一个
存储单元}
while p^.next<>nil do //找表尾
p:=p^.next
{dtrec没有改变,改变的是
p指针,p指针沿着链表顺序查找}
p^.next:=tempp
//将新节点添加到表尾
end;
edit1.Clear
//清编辑框
edit1.SetFocus
//当前活动焦点置回到编辑框上
end;
end;

procedure TForm1.BtnlistClick(Sender: TObject);
var
p:plink;
begin
listbox1.Clear
//清列表框
p:=dtrec
//同上
repeat //遍历列表,将所有节点数据域中的数据赋给listbox1的items属性
listbox1.Items.Add(p^.data);
p:=p^.next;
until p=nil;
end;

procedure TForm1.BtndelClick(Sender: TObject);
var
p,p1:plink;
i:integer;
begin
i:=0
{计数器初始化}
p:=dtrec
//同上
if p=nil then //如果链表为空表
showmessage('链表为空表')
else //如果链表不为空
if p^.data=edit1.Text then //如果链表的第一个节点为要删的节点
begin
dtrec:=p^.next;
p^.next:=nil;
p:=dtrec
{多此一举,p是一个局部变量,
如果执行了if 的程序段,那么在以后的程序中不会
再次使用p指针,而在这个过程结束以后,局部变量
的作用范围已经失去了效用}
end
else //如果等待删除的节点不是链表的头节点的话
begin
p1:=p^.next
{p1节点指向p节点后面的那个节点,同样的,p1节点
指向内存中存在的单元,无需使用new的过程}
if p1<>nil then //如果p1指向的节点没有到达链表的尾部
repeat
if p1.data=edit1.Text then //如果找到一个要删的节点
begin
p^.next:=p1^.next
//将p1所指向的节点从链表中删去
p1:=p;
i:=i+1
{记数器++,表明已经找到并删除了等待删除
的数据}
end
else //如果没有找到等待删除的节点
begin
p:=p1;
p1:=p1^.next
//p和p1指针同时向链表的尾部滑动一格
end
until p1=nil
//直到到达链表的尾部
if i=0 then //如果链表不存在要删的节点
showmessage('无匹配的数据');
end;
end;

procedure TForm1.BtnquitClick(Sender: TObject);
begin
close
//关闭窗口
end;

end.
 
多人接受答案了。
 
顶部