您的位置:

二叉树golang,二叉树的度

本文目录一览:

Golang-基于TimeingWheel定时器

在linux下实现定时器主要有如下方式

在这当中 基于时间轮方式实现的定时器 时间复杂度最小,效率最高,然而我们可以通过 优先队列 实现时间轮定时器。

优先队列的实现可以使用最大堆和最小堆,因此在队列中所有的数据都可以定义排序规则自动排序。我们直接通过队列中 pop 函数获取数据,就是我们按照自定义排序规则想要的数据。

在 Golang 中实现一个优先队列异常简单,在 container/head 包中已经帮我们封装了,实现的细节,我们只需要实现特定的接口就可以。

下面是官方提供的例子

因为优先队列底层数据结构是由二叉树构建的,所以我们可以通过数组来保存二叉树上的每一个节点。

改数组需要实现 Go 预先定义的接口 Len , Less , Swap , Push , Pop 和 update 。

timerType结构是定时任务抽象结构

首先的 start 函数,当创建一个 TimeingWheel 时,通过一个 goroutine 来执行 start ,在start中for循环和select来监控不同的channel的状态

通过for循环从队列中取数据,直到该队列为空或者是遇见第一个当前时间比任务开始时间大的任务, append 到 expired 中。因为优先队列中是根据 expiration 来排序的,

所以当取到第一个定时任务未到的任务时,表示该定时任务以后的任务都未到时间。

当 getExpired 函数取出队列中要执行的任务时,当有的定时任务需要不断执行,所以就需要判断是否该定时任务需要重新放回优先队列中。 isRepeat 是通过判断任务中 interval 是否大于 0 判断,

如果大于0 则,表示永久就生效。

防止外部滥用,阻塞定时器协程,框架又一次封装了timer这个包,名为 timer_wapper 这个包,它提供了两种调用方式。

参数和上面的参数一样,只是在第三个参数中使用了任务池,将定时任务放入了任务池中。定时任务的本身执行就是一个 put 操作。

至于put以后,那就是 workers 这个包管理的了。在 worker 包中, 也就是维护了一个任务池,任务池中的任务会有序的执行,方便管理。

Golang数据结构-树

二叉树是n(n=0)个节点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根节点和两棵互不相交的、分别称为根节点的左子树和右子树的二叉树组成

二叉树的遍历

5.1树的概念

树的递归定义如下:(1)至少有一个结点(称为根)(2)其它是互不相交的子树

1.树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,如上图的树,其度为3;树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。

2.树的深度——组成该树各结点的最大层次,如上图,其深度为4;

3.森林——指若干棵互不相交的树的集合,如上图,去掉根结点A,其原来的二棵子树T1、T2、T3的集合{T1,T2,T3}就为森林;

4.有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树。

5.树的表示

树的表示方法有许多,常用的方法是用括号:先将根结点放入一对圆括号中,然后把它的子树由左至右的顺序放入括号中,而对子树也采用同样的方法处理;同层子树与它的根结点用圆括号括起来,同层子树之间用逗号隔开,最后用闭括号括起来。如上图可写成如下形式:

(A(B(E(K,L),F),C(G),D(H(M),I,J)))

5. 2 二叉树

1.二叉树的基本形态:

二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:

(1)空二叉树——(a);

(2)只有一个根结点的二叉树——(b);

(3)右子树为空的二叉树——(c);

(4)左子树为空的二叉树——(d);

(5)完全二叉树——(e)

注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。

2.两个重要的概念:

(1)完全二叉树——只有最下面的两层结点度小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树;

(2)满二叉树——除了叶结点外每一个结点都有左右子女且叶结点都处在最底层的二叉树,。

如下图:

完全二叉树

满二叉树

3.二叉树的性质

(1) 在二叉树中,第i层的结点总数不超过2^(i-1);

(2) 深度为h的二叉树最多有2h-1个结点(h=1),最少有h个结点;

(3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,

则N0=N2+1;

(4) 具有n个结点的完全二叉树的深度为int(log2n)+1

(5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:

若I为结点编号则 如果I1,则其父结点的编号为I/2;

如果2*I=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*IN,则无左儿子;

如果2*I+1=N,则其右儿子的结点编号为2*I+1;若2*I+1N,则无右儿子。

4.二叉树的存储结构:

(1)顺序存储方式

type node=record

data:datatype

l,r:integer;

end;

var tr:array[1..n] of node;

(2)链表存储方式,如:

type btree=^node;

node=record

data:datatye;

lchild,rchild:btree;

end;

5.普通树转换成二叉树:凡是兄弟就用线连起来,然后去掉父亲到儿子的连线,只留下父母到其第一个子女的连线。

6.二叉树的遍历运算(递归定义)

(1)先序遍历

访问根;按先序遍历左子树;按先序遍历右子树

(2)中序遍历

按中序遍历左子树;访问根;按中序遍历右子树

(3)后序遍历

按后序遍历左子树;按后序遍历右子树;访问根

例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 (n0) and (n6);

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 l0 then search(l);

if r0 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 top0 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^.lnil then inorder(head^.l);

write(head^.da);

if head^.rnil 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].wsmall1 then

begin small2:=small1;small1:=ht[j].w;p2:=p1;p1:=j end

else if ht[j].wsmall2 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.

哈夫曼码:哈夫曼树的非叶结点到左右孩子的路径分别用0,1 表示,从根到叶的路径序列即为哈夫曼码。

哈夫曼码是不会发生译码多义性的不等长编码,广泛应用实际中。

(原因是任何一字符的编码不是更长编码的前缀部分,为什么?)

2.排序二叉树

排序二叉树:每一个参加排列的数据对应二叉树的一个结点,且任一结点如果有左(右)子树,则左(右)子树各结点的数据必须小(大)于该结点的数据。中序遍历排序二叉树即得排序结果。程序如下:

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 leftnil then hyt1(left);

write(w:4);

if rightnil 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 (jm) and (a[j]a[j+1]) then j:=j+1;

if ta[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

二叉树golang,二叉树的度

2022-11-28
c语言二叉树的度,c++二叉树的深度

2023-01-05
c语言求二叉树最大深度,c语言求二叉树高度

2022-11-25
用c语言将二叉树转换为双向链表,二叉树转化为二叉链表

2022-11-29
二叉树java,二叉树java实现

2023-01-10
java二叉树测试(二叉查找树java)

2022-11-11
遍历线索化二叉树java(遍历二叉树和线索二叉树)

2022-11-15
c语言八叉树,二叉树构造c语言实现

2022-11-26
二叉树按层输出c语言,C语言二叉树怎么输入数据

2022-11-24
二叉树的c语言程序求教,c语言创建二叉树代码

2023-01-06
二叉树的前序遍历c语言,二叉树前序遍历c语言代码

2022-11-25
二叉树java,二叉树java打印中根

2022-12-02
golang创建树,golang 树

2022-11-27
java二叉树,java二叉树遍历算法

2023-01-09
c语言深度优先二叉树遍历,深度优先遍历类似于二叉树的层次遍历

本文目录一览: 1、急急急!求C语言的数据结构二叉树递归遍历程序! 2、C语言二叉树的遍历。 3、C语言数据结构“遍历二叉树” 4、二叉树的创建和遍历 急急急!求C语言的数据结构二叉树递归遍历程序!

2023-12-08
java遍历二叉树,java实现二叉树遍历

2023-01-05
层次遍历构建二叉树c语言,c语言二叉树的创建与遍历

2023-01-06
平衡二叉树

2023-05-16
c语言二叉排序,c语言创建排序二叉树

2022-12-02
java遍历二叉树,java遍历二叉树代码

2023-01-03