{/*
Name: 二叉排序树
Copyright:始发于goal00001111的专栏;允许自由转载,但必须注明作者和出处
Author: goal00001111
Date: 02-12-08 20:23
Description: 二叉排序树
包括二叉排序树的创建;先序遍历,中序遍历,后序遍历的递归和非递归算法;
结点的插入,查找和删除,其中删除算法有两种和一个优化算法;还有层序遍历算法;
输出二叉树,分别使用先序和后序算法计算二叉树的深度等。
较为全面的介绍了二叉排序树的基本算法。
*/}
PROGRAM BinaryTree (input, output);
TYPE
element = char;
Btree = ^node;
node = record
data : element;
lc, rc : Btree;
end;
CONST
MAX = 1000; {最大结点数量}
WIDTH = 2; {输出元素值宽度}
ENDTAG = '#';
VAR
root, obj : Btree;
height, depth : integer;
data : element;
{向一个二叉排序树b中插入一个结点s}
FUNCTION InsertNode(var t : Btree; s : Btree) : boolean;
begin
if t = nil then
begin
t := s;
InsertNode := true;
end {if}
else if t^.data > s^.data then {把s所指结点插入到左子树中}
InsertNode := InsertNode(t^.lc, s)
else if t^.data < s^.data then {把s所指结点插入到右子树中}
InsertNode := InsertNode(t^.rc, s)
else {若s->data等于b的根结点的数据域之值,则什么也不做}
InsertNode := false;
end; {InsertNode}
{生成一棵二叉排序树(以ENDTAG为结束标志)}
PROCEDURE CreateTree(var t : Btree);
var
data : element;
s : Btree;
begin
t := nil;
read(data);
while data <> ENDTAG do
begin
new(s);
s^.data := data;
s^.lc := nil;
s^.rc := nil;
if not(InsertNode(t, s)) then
dispose(s);{插入一个结点s}
read(data);
end;
end;
{销毁一棵二叉排序树}
PROCEDURE DestroyTree(var t : Btree);
begin
if t <> nil then
begin
DestroyTree(t^.lc);
DestroyTree(t^.rc);
dispose(t);
t := nil;
end; {if}
end; {DestroyTree}
{递归算法:}
{先序遍历}
PROCEDURE Preorder_1(t : Btree);
begin
if t <> nil then
begin
write(t^.data:WIDTH); {输出该结点(根结点)}
Preorder_1(t^.lc); {遍历左子树}
Preorder_1(t^.rc); {遍历右子树}
end;
end;
{中序遍历}
PROCEDURE Inorder_1(t : Btree);
begin
if t <> nil then
begin
Inorder_1(t^.lc); {遍历左子树}
write(t^.data:WIDTH); {输出该结点(根结点)}
Inorder_1(t^.rc); {遍历右子树}
end;
end;
{后序遍历}
PROCEDURE Postorder_1(t : Btree);
begin
if t <> nil then
begin
Postorder_1(t^.lc); {遍历左子树}
Postorder_1(t^.rc); {遍历右子树}
write(t^.data:WIDTH); {输出该结点(根结点)}
end;
end;
{非递归算法(使用栈存储树)}
{先序遍历}
PROCEDURE Preorder_2(t : Btree);
var
p : Btree; {p表示当前结点}
stack : array [1..MAX] of Btree; {栈stack[]用来存储结点}
top : integer;
begin
top := 1;
if t <> nil then {先判断是否为空树}
begin
stack[top] := t; {根结点入栈}
while top >= 1 do {栈内还有元素}
begin
p := stack[top]; {栈顶元素出栈}
dec(top);
write(p^.data:WIDTH);
if p^.rc <> nil then {如果该结点有右孩子,将右孩子入栈}
begin
inc(top);
stack[top] := p^.rc;
end; {if}
if p^.lc <> nil then{如果该结点有左孩子,将左孩子入栈,按照后入先出原则,左孩子先出栈}
begin
inc(top);
stack[top] := p^.lc;
end; {if}
end; {while}
end;{if}
end;{Preorder_2}
{先序遍历}
PROCEDURE Preorder_3(t : Btree);
var
p : Btree; {p表示当前结点}
stack : array [1..MAX] of Btree; {栈stack[]用来存储结点}
top : integer;
begin
top := 1;
Name: 二叉排序树
Copyright:始发于goal00001111的专栏;允许自由转载,但必须注明作者和出处
Author: goal00001111
Date: 02-12-08 20:23
Description: 二叉排序树
包括二叉排序树的创建;先序遍历,中序遍历,后序遍历的递归和非递归算法;
结点的插入,查找和删除,其中删除算法有两种和一个优化算法;还有层序遍历算法;
输出二叉树,分别使用先序和后序算法计算二叉树的深度等。
较为全面的介绍了二叉排序树的基本算法。
*/}
PROGRAM BinaryTree (input, output);
TYPE
element = char;
Btree = ^node;
node = record
data : element;
lc, rc : Btree;
end;
CONST
MAX = 1000; {最大结点数量}
WIDTH = 2; {输出元素值宽度}
ENDTAG = '#';
VAR
root, obj : Btree;
height, depth : integer;
data : element;
{向一个二叉排序树b中插入一个结点s}
FUNCTION InsertNode(var t : Btree; s : Btree) : boolean;
begin
if t = nil then
begin
t := s;
InsertNode := true;
end {if}
else if t^.data > s^.data then {把s所指结点插入到左子树中}
InsertNode := InsertNode(t^.lc, s)
else if t^.data < s^.data then {把s所指结点插入到右子树中}
InsertNode := InsertNode(t^.rc, s)
else {若s->data等于b的根结点的数据域之值,则什么也不做}
InsertNode := false;
end; {InsertNode}
{生成一棵二叉排序树(以ENDTAG为结束标志)}
PROCEDURE CreateTree(var t : Btree);
var
data : element;
s : Btree;
begin
t := nil;
read(data);
while data <> ENDTAG do
begin
new(s);
s^.data := data;
s^.lc := nil;
s^.rc := nil;
if not(InsertNode(t, s)) then
dispose(s);{插入一个结点s}
read(data);
end;
end;
{销毁一棵二叉排序树}
PROCEDURE DestroyTree(var t : Btree);
begin
if t <> nil then
begin
DestroyTree(t^.lc);
DestroyTree(t^.rc);
dispose(t);
t := nil;
end; {if}
end; {DestroyTree}
{递归算法:}
{先序遍历}
PROCEDURE Preorder_1(t : Btree);
begin
if t <> nil then
begin
write(t^.data:WIDTH); {输出该结点(根结点)}
Preorder_1(t^.lc); {遍历左子树}
Preorder_1(t^.rc); {遍历右子树}
end;
end;
{中序遍历}
PROCEDURE Inorder_1(t : Btree);
begin
if t <> nil then
begin
Inorder_1(t^.lc); {遍历左子树}
write(t^.data:WIDTH); {输出该结点(根结点)}
Inorder_1(t^.rc); {遍历右子树}
end;
end;
{后序遍历}
PROCEDURE Postorder_1(t : Btree);
begin
if t <> nil then
begin
Postorder_1(t^.lc); {遍历左子树}
Postorder_1(t^.rc); {遍历右子树}
write(t^.data:WIDTH); {输出该结点(根结点)}
end;
end;
{非递归算法(使用栈存储树)}
{先序遍历}
PROCEDURE Preorder_2(t : Btree);
var
p : Btree; {p表示当前结点}
stack : array [1..MAX] of Btree; {栈stack[]用来存储结点}
top : integer;
begin
top := 1;
if t <> nil then {先判断是否为空树}
begin
stack[top] := t; {根结点入栈}
while top >= 1 do {栈内还有元素}
begin
p := stack[top]; {栈顶元素出栈}
dec(top);
write(p^.data:WIDTH);
if p^.rc <> nil then {如果该结点有右孩子,将右孩子入栈}
begin
inc(top);
stack[top] := p^.rc;
end; {if}
if p^.lc <> nil then{如果该结点有左孩子,将左孩子入栈,按照后入先出原则,左孩子先出栈}
begin
inc(top);
stack[top] := p^.lc;
end; {if}
end; {while}
end;{if}
end;{Preorder_2}
{先序遍历}
PROCEDURE Preorder_3(t : Btree);
var
p : Btree; {p表示当前结点}
stack : array [1..MAX] of Btree; {栈stack[]用来存储结点}
top : integer;
begin
top := 1;