例1.用顺序存储方式建立一棵有31个结点的满二叉树,并对其进行先序遍历。 program erchashu1; var b:array[1..31] of char; e:array[1..63] of byte; n,h,i,k:integer; procedure tree(t:integer); begin if e[t]=0 then exit else begin write(b[t]);e[t]:=0; t:=2*t;tree(t); t:=t+1;tree(t); end; end; begin repeat write('n=');readln(n); until (n>0) and (n<6); fillchar(e,sizeof(e),0); k:=trunc(exp(n*ln(2)))-1; for i:=1 to k do e[i]:=1; for i:=1 to 26 do b[i]:=chr(64+i); for i:=1 to 5 do b[26+i]:=chr(48+i); h:=1 ;tree(h); writeln; end.
例2.用顺序存储方式建立一棵如图所示的二叉树,并对其进行先序遍历。
program tree1; const n=15; type node=record data:char; l,r:0..n; end; var tr:array[1..n] of node; e:array[1..n] of 0..1; i,j:integer;
procedure jtr; var i:integer; begin for i:=1 to n do with tr[i] do readln(data,l,r); end; procedure search(m:integer); begin with tr[m] do begin write(data); if l<>0 then search(l); if r<>0 then search(r); end; end; begin jtr;search(1);writeln; end.
例3 用链表存储方式生成上述二叉树,中序遍历之。
1.将上述二叉树用广义表表示为A(B(D,E(G)),C(F(,H)))
2.根据广义表串(以#结束)生成二叉树。
program ltree; const n=8; type trlist=^node; node=record da:char; l,r:trlist; end; var s:array[1..n] of trlist; p,root:trlist; ch:char; top,k:integer; procedure creat(var head:trlist); begin read(ch); top:=0; while ch<>'#' do begin case ch of 'A'..'Z':begin new(p);p^.da:=ch;p^.l:=nil;p^.r:=nil; if top<>0 then case k of 1:s[top]^.l:=p; 2:s[top]^.r:=p; end end; '(':begin top:=top+1;s[top]:=p;k:=1;end; ')': top:=top-1; ',': k:=2; end; read(ch); end; head:=s[1]; end; procedure inorder(head:trlist); begin if head^.l<>nil then inorder(head^.l); write(head^.da); if head^.r<>nil then inorder(head^.r); end; begin write('Input tree string:'); creat(root); inorder(root); end.
5.3 二叉树的应用 1. 哈夫曼树与哈夫曼码
树的路径长度:一棵树的每一个叶结点到根结点的路径长度的和。
带权二叉树:给树的叶结点赋上某个实数值(称叶结点的权)。
带权路径长度:各叶结点的路径长度与其权值的积的总和。
哈夫曼树(最优二叉树):带权路径长度最小的二叉树。
如何构建哈夫树:(思想是:权越大离跟越近)
program gojiantree; const n=4;m=7; type node=record w:real; parent,lchild,rchild:0..m end; htree=array[1..m] of node; var htree1:htree; procedure gjtree(var ht:htree); var i,j:integer; small1,small2:real; p1,p2:0..m; begin for i:=1 to m do with ht[i] do begin w:=0;lchild:=0;rchild:=0;parent:=0; end; for i:=1 to n do read(ht[i].w); for i:=n+1 to m do begin p1:=0;p2:=0; small1:=1000;small2:=1000; for j:=1 to i-1 do if ht[j].parent=0 then if ht[j].w<small1 then begin small2:=small1;small1:=ht[j].w;p2:=p1;p1:=j end else if ht[j].w<small2 then begin small2:=ht[j].w;p2:=j end; ht[p1].parent:=i; ht[p2].parent:=i; ht[i].lchild:=p1; ht[i].rchild:=p2; ht[i].w:=ht[p1].w+ht[p2].w; end; end; begin gjtree(htree1); end.
program pxtree; const a:array[1..8] of integer=(10,18,3,8,12,2,7,3); type point=^nod; nod=record w:integer; right,left:point ; end; var root,first:point;k:boolean;i:integer; procedure hyt(d:integer;var p:point); begin if p=nil then begin new(p); with p^ do begin w:=d;right:=nil;left:=nil end; if k then begin root:=p; k:=false end; end else with p^ do if d>=w then hyt(d,right) else hyt(d,left); end; procedure hyt1(p:point); begin with p^ do begin if left<>nil then hyt1(left); write(w:4); if right<>nil then hyt1(right); end end; begin first:=nil;k:=true; for i:=1 to 8 do hyt(a[i],first); hyt1(root);writeln; end.
3.堆排序
堆:设有数据元素的集合(R1,R2,R3,...Rn)它们是一棵顺序二叉树的结点且有
Ri<=R2i 和Ri<=R2i+1(或>=)
堆的性质:堆的根结点上的元素是堆中的最小元素,且堆的每一条路径上的元素都是有序的。
堆排序的思想是:
1)建初始堆(将结点[n/2],[ n/2]-1,...3,2,1分别调成堆)
2)当未排序完时
输出堆顶元素,删除堆顶元素,将剩余的元素重新建堆。
程序如下:
program duipx; const n=8; type arr=array[1..n] of integer; var a:arr;i:integer; procedure sift(var a:arr;l,m:integer); var i,j, t:integer; begin i:=l;j:=2*i;t:=a[i]; while j<=m do begin if (j<m) and (a[j]>a[j+1]) then j:=j+1; if t>a[j] then begin a[i]:=a[j];i:=j;j:=2*i; end else exit; end; a[i]:=t; end; begin for i:=1 to n do read(a[i]); for i:=(n div 2) downto 1 do sift(a,i,n); for i:=n downto 2 do begin write(a[1]:4); a[1]:=a[i]; sift(a,1,i-1); end; writeln(a[1]:4); end