深夜爆肝:万字长文3种语言实现Huffman树(强烈建议三连)

一、C语言能干大事

在这里插入图片描述

1. C语言下Huffman树的计算过程分析

例1 有权重集合分别是:5、29、7、8、14、23、3、11,计算Huffman树。

这个题目的计算过程如下:

(1)首先是把数据填写在以下表格里:

在这里插入图片描述
这个在编程中一定注意:空白格子里是NULL,这点不要搞错。

首先是寻找到两个最小权重的结点,找到的是第7、1号结点,权重合计是8,我们先标记这两个结点s=1(代表已经处理过了),并生成第9号结点,权重是8,并让第7、1号结点的父结点是9,第9号结点的左、右孩子分别是第7、1结点,就是如下表:

在这里插入图片描述
重复上面的过程,从头寻找s=0的结点里、权重最小的两个结点、就是第3、4号结点,权重合计是15,这样,标记这两个结点s=1,并生成第10号结点,权重是15,而第7、8的父结点是第10号结点,第10号结点的左右孩子是第3、4号结点,就是下表:

在这里插入图片描述
重复这个过程,处理到第15个结点,使其权重合计为100,就是:

在这里插入图片描述
最终这个树的计算到此结束,在这样的表中计算出的过程以及结果,就是我们下面编程的主要依据。

2. C语言下Huffman树的编程

针对前面介绍的表格,用C语言描述这样的表就是:

struct Huffman 
{
	int W,Parent,lChild,rChild,S;
};

对Huffman树,由于它是正则二叉树,所以有n个权重数据则必然有2*n-1个树结点。

有了表的C语言定义,则首先是寻找未标记的、权重最小的结点,如果这个表是H,则全部代码就是:

int FindMinNode(struct Huffman *H,int N)
{
	int i,W,Node;
	W=100;Node=0;
	if(H==NULL) return -1;
	for(i=0;i<N;i++)
	{
		if(H[i].W>0&&H[i].W<W&&H[i].S==0)
		{
			W=H[i].W;Node=i;
		}
	}
	H[Node].S=1;
	return Node;
}

第6至第12行,是一个典型的数组中求最小值的算法,在第13行,则必须标记这个结点的S=1,说明该结点已经使用过,最后则返回这个结点的编号。

有了这个函数后,首先要对H表进行两次求最小值的操作,就是:

min1=FindMinNode(H,N);	min2=FindMinNode(H,N);

如第i行是新增的一个结点,则让该表第i行的权重为:

H[i].W=H[min1].W+H[min2].W;

然后,就是设置这个结点的左右孩子结点为min1、min2,就是:

H[i].Parent=-1; 	H[i].lChild=min1;		H[i].rChild=min2;

最后,就是设置编号min1、min2的结点的父结点是第i个结点。

H[min1].Parent=i;	H[min2].Parent=i;

全部就是:

int ConstructHuffmanTree(struct Huffman *H,int n)
{
	int i;
	int min1,min2,N;
	if(n==0) return -1;
	if(H==NULL) return -2;
	N=2*n-1;
	for(i=n;i<N;i++)
	{
		min1=FindMinNode(H,N);min2=FindMinNode(H,N);
		H[i].W=H[min1].W+H[min2].W;
		H[min1].Parent=i;H[min2].Parent=i;
		H[i].Parent=-1;
		H[i].lChild=min1;H[i].rChild=min2;
	}
	return 0;
}

注意这个函数第8行,它是从第n个结点开始循环的。

有了这两个函数后,用一个测试的main()来测试它们:

main()
{
	int n,N,i,*D;
	struct Huffman *H;
	n=8;//组织scanf()输入
	N=2*n-1;
	D=(int *)malloc(sizeof(int)*n);
	//组织scanf()输入。
	D[0]=5;
	D[1]=29;
	D[2]=7;
	D[3]=8;
	D[4]=14;
	D[5]=23;
	D[6]=3;
	D[7]=11;
	H=(struct Huffman *)malloc(sizeof(struct Huffman)*N);
	for(i=0;i<N;i++) 
	{
		H[i].W=0;
		H[i].Parent=0;
		H[i].lChild=0;
		H[i].rChild=0;
		H[i].S =0;
	}
	for(i=0;i<n;i++)
		H[i].W =D[i];
	ConstructHuffmanTree(H,n);
 	printf("ID\tW\tP\tL\tR\n");
	for(i=0;i<N;i++)
	printf("%d\t%d\t%d\t%d\t%d\n",i,H[i].W,H[i].Parent,H[i].lChild,H[i].rChild);
}

运行结果如下图所示:

在这里插入图片描述

Huffman树的C语言程序到此为止。

二、C#语言也不赖

在这里插入图片描述

1. C#下Huffman类的设计

仅仅针对前面C语言中的计算方法,设计一个类来完成计算过程,这个类就是:

 class Huffman
    {
        public int W, pChild, lChild, rChild, s;
        public Huffman()
        {
            W = pChild = lChild = rChild = -1;
            s =0;  
        }
        public Huffman(int Weight, int PChild, int LChild, int RChild, int Select)
        {
            W = Weight; PChild = pChild; lChild = LChild; rChild = RChild; s = Select;    
        }
    }

2. C#中界面设计

有了这个类以后,我们可以在界面设计上拖进两个命令按钮button1,button2,然后再拖进一个treeView1控件和imageList1控件,然后开始以下设置:

(1) 选择imageList1控件,找到属性images,加入文件夹MyIcon中的两个小图标;

(2) 选择treeView1控件,让imageList属性选中imageList1控件;

(3) 选择treeView1控件,让SelectImageIndex=1(打开书的图标);

(4) 选择treeView1控件,让ImageIndex=0(关闭书的图标);

(5) 选择button1控件,修改text属性为:”简单测试”;

(6) 选择button2控件,修改text属性为:”结束”

3. 建立测试数据并显示Huffman树

设有权重数据为:5,29,7,8,14.23.3.11,注意权重数据和必须是100。首先是编写从Huffman类数组中取得最小权重结点的函数,这个函数编写在Form1程序中,鼠标双击button1,注意在button1_click()前面补充这样的函数,就是:

在这里插入图片描述
在这个函数中,H是Huffman结点对象数组,而N是这个数组的数据个数,如果是上例,则N=15。
现在开始补充代码如下:

int FindMinNode(Huffman[] H,int N)
        {   
        	int i,W,Node;
	        W=100;Node=0;
	        if(H==null) return -1;
	        for(i=0;i<N;i++)
	        {
		        if(H[i].W>0&&H[i].W<W&&H[i].s==0)
		            {
			        W=H[i].W;Node=i;
		            }
	        }
	        H[Node].s=1;
	        return Node;
        }

这个函数同C的几乎没什么差别,同样返回这个结点的下标。有这个函数后,就可以构造Huffman树,跟随着上面的函数,继续输入就是:

int ConstructHuffmanTree(Huffman[] H,int n)
        {
	        int i;
	        int min1,min2,N;
	        if(n==0) return -1;
	        if(H==null) return -2;
	        N=2*n-1;
	        for(i=n;i<N;i++)
	        {
		        min1=FindMinNode(H,N);
		        min2=FindMinNode(H,N);
		        H[i].W=H[min1].W+H[min2].W;
		        H[min1].pChild=i;
		        H[min2].pChild=i;
		        H[i].pChild=-1;
		        H[i].lChild=min1;
		        H[i].rChild=min2;
	        }
	    return 0;
        }

其基本算法和C语言的也没什么差别。

但这个Huffman类的树是不能显示在treeView1中的,控件treeView1只能显示TreeNode类型的树,所以要按这个表格的内容构造TreeNode类对象的树。

在treeView1控件中,显示的结点个数同Huffman类的结点个数是一致的,而每个TreeNode类结点的Text内容则是权重,于是紧跟着上面的函数,写以下函数就是:

        void dTree(Huffman[] H)
        {
            int i,n,a,b;
            n = H.Count();
            TreeNode[] T = new TreeNode[n];
            for(i=0;i<n;i++)
                T[i]=new TreeNode(H[i].W.ToString());
            for (i = 0; i <n; i++)
            {
                a = H[i].lChild; 
b = H[i].rChild;
                if (a >= 0) T[i].Nodes.Add(T[a]);
                if (b >= 0) T[i].Nodes.Add(T[b]);
            }
            treeView1.Nodes.Add(T[n-1]);  
        }

最后,就是补充button1下的程序,按实验数据有:

这组数据一共8个,所以Humman树一共将有2*8-1=15个结点,鼠标双击button1,写进以下程序:

private void button1_Click(object sender, EventArgs e)
        {
            Huffman[] H = new Huffman[15];
            H[0] = new Huffman(5, -1, -1, -1, 0);
            H[1] = new Huffman(29, -1, -1, -1, 0);
            H[2] = new Huffman(7, -1, -1, -1, 0);
            H[3] = new Huffman(8, -1, -1, -1, 0);
            H[4] = new Huffman(14, -1, -1, -1, 0);
            H[5] = new Huffman(23, -1, -1, -1, 0);
            H[6] = new Huffman(3, -1, -1, -1, 0);
            H[7] = new Huffman(11, -1, -1, -1, 0);
            for (int i = 8; i < 15; i++) H[i] = new Huffman();
            ConstructHuffmanTree(H, 8);
            dTree(H);
        }

到此,简单的Huffman树的测试程序设计完成。最后在button2_click()中补充代码:this.close();让程序能正常结束。

4. 输入任意一组数据,完成构造Huffman树

为完成这个要求,首先要在界面设计中再补充控件,有:

(1) 补充listBox1控件;

(2) 补充button3控件,修改Text属性为:“输入确认”;

(3) 补充button4控件,修改Text属性为:”生成Huffman树”;

(4) 补充button5控件,修改Text属性为:”清除”;

(5) 补充textBox1控件;

有了上述控件后,我们首先设计操作过程是:

在textBox1控件中输入数据,按下button3按钮“输入确认”,则输入的数据显示在listBox1控件中,直到所有数据输入完成,于是这样的操作要求的程序就是:

private void button3_Click(object sender, EventArgs e)
        {
            listBox1.Items.Add(textBox1.Text); 
        }

listBox1控件是个数据容器,你可以不断追加进很多数据,这些数据全部可以保存在这个控件中。直到按下button4”生成Huffman树”,才开始计算。所以button4的程序就是:

  private void button4_Click(object sender, EventArgs e)
        {
            int n = listBox1.Items.Count;
            Huffman[] H = new Huffman[2*n-1];
            for (int i = 0; i < 2 * n - 1; i++)
                H[i] = new Huffman();
            for(int i=0;i<n;i++)
            {
                int w=int.Parse( listBox1.Items[i].ToString()) ;
                H[i].W = w; 
            }
            ConstructHuffmanTree(H, n);
            dTree(H);
        }

表7中第3行,相当于从listBox1控件中获得数据项的个数,在第9行,就是逐个取得每个数据项,并转换成int类型、赋值给Huffman类对象数组中每个对象的权重W。最后按同样的方式计算并显示在treeView1中。

注意这个程序实际很不理想,没判断输入的数据是否有负值、是否是非数字的字符串、是否和为100等等,这些详细的判断留给同学们自己去完成。

对于button5”清除”的编程非常简单,就是:

private void button5_Click(object sender, EventArgs e)
{
     listBox1.Items.Clear();
     treeView1.Nodes.Clear();
     textBox1.Text = "";
}	

程序运行效果:

在这里插入图片描述

三、JavaScript语言不爱听了

在这里插入图片描述

1. JavaScript下Huffman类的设计

针对前面C语言中的计算方法,设计一个类来存储数据,如果你使用的Ext系统,则强烈建议直接使用Ext.data.ArrayStore类对象直接构造它,这样的好处是显示在表格里非常方便,于是说明对象tstore为:

var tstore = new Ext.data.ArrayStore({
		data:[
			[0,5 ,-1, -1,-1,0],
			[1,29,-1, -1,-1,0],
			[2,7 ,-1, -1,-1,0],
			[3,8 ,-1, -1,-1,0],
			[4,14,-1, -1,-1,0],
			[5,23,-1, -1,-1,0],
			[6,3 ,-1, -1,-1,0],
			[7,11,-1, -1,-1,0]
		     ],
 	       fields: [
	           {name: 'id'    ,type:'int'},
	           {name: 'w'     ,type:'int'},
	           {name: 'pChild',type:'int'},
	           {name: 'lChild',type:'int'},
	           {name: 'rChild',type:'int'},
	           {name: 's'     ,type:'int'}
	           ]
		   });

运行效果:

在这里插入图片描述

这个程序非常直观,它说明有一个表名称是tstore,其中右6列,data下说明了数据,在field下说明了各个列的名称、分别是id,w,pChild,lChild,rChild,s这样的6列,如同下表:

在这里插入图片描述

2. 把权重数据显示在一个表格里

但这个表用来显示在界面上则非常不好看,我们需要一个友好的界面,所谓友好的界面就是说用汉字显示、而不是奇怪符号显示的界面,如:

在这里插入图片描述

我们一般把表2成为逻辑表,表3称为显示表,它们两者之间的关系应该是一一对应的,唯独列名称不一样。造成这样的结果,主要原因是程序计算过程中,我们期望变量名都是英语字符,这样非常方便编程,但显示,则必须是汉字的表头。

把这两者统一起来:就是说让“结点编号”指向逻辑表的“id”列,要用到Ext.grid.ColumnModel类型的对象,如该对象的名称是colM,则定义如下:

var colM=new Ext.grid.ColumnModel([
{列对象1属性},
{列对象2属性},{列对象n属性}
]);

注意JavaScript中、一旦出现[ ]则代表是数组,所以这些个列对象也就相当于数组中的各个元素。

一个典型的设置就是:如将表格第1列显示为“结点编号”、并和数据逻辑表tstore中的id关联起来、并在该列上提供排序、而且该列可以编辑,则就是:

{
	header:"结点编号",
	dataIndex:'id',
	sortable:true,
	editor:new Ext.form.TextField()
}

实际就是设置了列对象的4个属性。这仅仅是为第一列,如果是所有列,则:

var colM=new Ext.grid.ColumnModel([
		{
		header:"结点编号",
		dataIndex:'id',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"结点权重",
		dataIndex:'w',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"父结点编号",
		dataIndex:'pChild',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"左结点编号",
		dataIndex:'lChild',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"右孩子编号",
		dataIndex:'rChild',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"选择状态",
		dataIndex:'s',
		sortable:true,
		editor:new Ext.form.TextField()
		}
		]);

注意在最后一个列对象定义完后、第37行后没有”,”,这点初学者一定要记着。

有了数据、有了列定义以后,就可以显示表格了,显示表格用的是Ext.grid.EditorGridPanel类对象,就是按下面的语句:

var grid=new Ext.grid.EditorGridPanel({表对象属性});

含义是定义了一个表对象grid,而该表的显示属性则由表对象属性中说明。如:

var grid=new Ext.grid.EditorGridPanel({
							renderTo:"hello",
							title:"Huffman树",
							height:400,
							width:620,
							cm:colM,
							store:tstore
					          });

其中属性:

  • renderTo:说明这个表格显示在哪里,在表5中是在”hello”中,这个hello实际是用HTML语言定义的一个分区,就是
    ,有了这个分区,grid就将显示在该区域里;
  • title:表示该表格的标题;
  • height:表示该表格的高度;
  • width:表示该表格的宽度;
  • cm:表的列定义,需要一个列对象来说明各个列,如表4;
  • store:表示该表显示的数据来自哪里,在我们的程序中,数据来自表1定义的tstore。
    将上述程序代码合并到一个函数里就是:
function fun()
		{
		var tstore = new Ext.data.ArrayStore({
		data:[
			[0,5 ,-1, -1,-1,0],
			[1,29,-1, -1,-1,0],
			[2,7 ,-1, -1,-1,0],
			[3,8 ,-1, -1,-1,0],
			[4,14,-1, -1,-1,0],
			[5,23,-1, -1,-1,0],
			[6,3 ,-1, -1,-1,0],
			[7,11,-1, -1,-1,0]
		     ],
 	       fields: [
	           {name: 'id'    ,type:'int'},
	           {name: 'w'     ,type:'int'},
	           {name: 'pChild',type:'int'},
	           {name: 'lChild',type:'int'},
	           {name: 'rChild',type:'int'},
	           {name: 's'     ,type:'int'}
	           ]
		   });
		//表格上列名称显示、以及表格上数据处理方式。
		var colM=new Ext.grid.ColumnModel([
		{
		header:"结点编号",
		dataIndex:'id',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"结点权重",
		dataIndex:'w',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"父结点编号",
		dataIndex:'pChild',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"左结点编号",
		dataIndex:'lChild',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"右孩子编号",
		dataIndex:'rChild',
		sortable:true,
		editor:new Ext.form.TextField()
		},
		{
		header:"选择状态",
		dataIndex:'s',
		sortable:true,
		editor:new Ext.form.TextField()
		}
		]);
		//表格开始显示数据。
		var grid=new Ext.grid.EditorGridPanel({
							renderTo:"hello",
							title:"Huffman树",
							height:400,
							width:620,
							cm:colM,
							store:tstore
						      });
     	}
Ext.onReady(fun);

有了表7的程序,我们打开m.html,这个程序是一个调用Ext类库的模板程序,把表7的程序补充到这个程序里的fun()函数里即可执行,结果将显示一个表。

注意第72行不是这个函数中的语句,而是一条独立的JavaScript语句。现在就可以以m.html为模板文件,加入表7的程序。

3. 为表格添加命令按钮

如果一个程序仅仅能计算一组数据,那么这个程序实际没什么意义,为此,我们要给表格上加入三个命令按钮,就是:添加、删除、生成Huffman树,使其能添加一行、删除一行,并能根据新的数据生成Huffman树。

给表格上添加三个命令按钮,就是给grid对象上再说明一个工具条、并显示出三个命令按钮。也就是说给该对象的tbar属性说明命令按钮对象的属性说明,就是:

tbar:[{按钮对象1属性},{按钮对象2属性},…{按钮对象n属性} ]

对一个命令按钮属性,比如产生一个叫”新增”的命令按钮,则可以是这样来说明:

{   
							text: "新增",   
							iconCls: "add",   
							handler: function()
									{   
									//以下写进新增加一行的代码

									}   
							}

text:表明这个按钮上显示的字符,如VB6中Command控件上的Caption属性;

iconCls:这个按钮上要显示的图标;

handler:function() { }:就是按下这个按钮后的响应程序;

同VB6的设计思路是一致的,但这里完全没有VB6那样的编程环境,所以逐个属性只能自己在键盘上输入。

现在,我们要在表格对象grid上的工具栏tbar中说明三个按钮,则就是一下的程序:

var grid=new Ext.grid.EditorGridPanel({
							renderTo:"hello",
							title:"Huffman树",
							height:400,
							width:620,
							cm:colM,
							store:tstore,
							tbar: [   
							{   
							text: "新增",   
							//iconCls: "add",   
							handler: function()
									{   
									//以下写进新增加一行的代码

									}   
							},   
 							{   
							text: "生成Huffman树",   
 							//iconCls: "refresh",   
							handler: function()
									{   
                  						//以下写进生成新Huffman树的代码

									}   
 							},   
 							{   
							text: "删除一行",   
 							//iconCls: "delete",   
							handler: function()
									{   
									//以下写进表格中删除一行的代码

									}   
 							}   
   							]
							});

注意同表5的对比。新增加的三个命令按钮,在执行h1.html的时候则就会看到。当然,它们目前是什么都不会执行,仅仅是有三个命令按钮。

运行效果:

在这里插入图片描述

执行h0.html和h1.html,看看这两个网页的差异。

4. 编写添加一行的程序

编写这个程序,实际就是为表8的第15行处补充代码,补充这样的代码,首先要获得表格中当前有几行,这个数据要从tstore中去获得,就是:

var n=tstore.getCount();

然后构造一个默认的数据行,用的是:

var defData={id:n,pChild:-1,lChild:-1,rChild:-1,s:0};

就是说id的值是n,pChild=lChild=rChild=-1,s=0,让权重w为空白。

最后,构造一个第n行的记录,并插入到tstore中去,就是:

var r=new tstore.recordType(defData,n);
tstore.insert(tstore.getCount(),r);

一旦数据插入tstore,则在grid中会自动显示结果。完整的函数就是:

Handler: function()
	{   
		var n=tstore.getCount();
		var defData={id:n,pChild:-1,lChild:-1,rChild:-1,s:0};
		var r=new tstore.recordType(defData,n);
		tstore.insert(tstore.getCount(),r);
	}   

运行效果:

在这里插入图片描述

5. 编写删除一行的程序

删除一行数据,首先要选中表中的一行,如果没有选中,则要给出提示。

var record = grid.getSelectionModel().selection.record;   

如果正常获得了选中的行,则要找到这一行数据是在tstore中的哪一行,就是在对象tstore中按record来查找:

var index = tstore.indexOf(record);   

这样,index就是表格中对应的行号,有了行号,就可以:

tstore.removeAt(index);

来删除这一行。

但一定要注意:假如你没有选中表格中的任何一行,执行上面的过程则会发生错误,这个是非常重要的事情,否则删除操作会让程序经常崩溃。为此,这段程序要加入到JavaScript语言的try过程中,就是

try
{
//这里加入要尝试着做的程序段落
}
catch(err)
{
//如果尝试着做的程序段无法正常执行,则在这里给出错误的提示, err对象中有
//错误的描述。
}

注意这个语句,在C#中也有同样的语句,这个语句非常重要,经常会出现在一些需要尝试着做的工作中,诸如在涉及到硬件访问、用户操作不确定的场合下,按这个语句的过程来执行程序,则是必须的。有了这个过程,则完整的删除程序就是:

handler: function()
	{   
	try
		{
		var record = grid.getSelectionModel().selection.record;   
		var index = tstore.indexOf(record);   
		tstore.removeAt(index);   
		}
	catch(err)
		{
	     Ext.MessageBox.alert("删除错误提示","未选中任何行,不能删除.");return;
		}
}  

注意表10的程序是添加在表8的第32行处,这个程序在这里是完整的,但它是对象grid说明的一个组成部分。

现在运行h2.html,则可以测试加入一行数据、并删除一行数据了。

在这里插入图片描述

6. 用表格中的数据生成Huffman树表

要生成一个Huffman树,则首先要从表格中计算各个结点的权重值,为此,又首先要获得表格中未用过结点的最小权重结点,为此,编写函数如下:

function FindMinNode(astore)
		{
		var i,n,w=100,m=-1;
		n=astore.getCount();
		for(i=0;i<n;i++)
			{
			if(astore.getAt(i).get('s')==0&&w>astore.getAt(i).get('w'))
				{
				w=astore.getAt(i).get('w');m=i;
				}
			}
		astore.getAt(m).set('s',1);
		return m;
		}

这个函数的参数是astore,函数是逐行读这个对象中s=0的那些行,找到最小权重行的下标值、并存在m中,查找完后,在第12行,把该行的s列修改为1,然后返回这个下标值。这个算法的原理和C#是一致的。

有这个函数后,就可以在“生成Huffman树”按钮下的响应程序里补充这些代码,构造一个Huffman树,就是:

handler: function()
	{   
	var n=tstore.getCount();
	for(i=n;i<2*n-1;i++)	
			{
			var min1=FindMinNode(tstore);
			var min2=FindMinNode(tstore);
			tstore.getAt(min1).set('pChild',i);
			tstore.getAt(min2).set('pChild',i);
			var nw=tstore.getAt(min1).get('w')+tstore.getAt(min2).get('w');
			var newNode={id:i,w:nw,pChild:-1,lChild:min1,rChild:min2,s:0};
			var r=new tstore.recordType(newNode,i);
			tstore.insert(tstore.getCount(),r);
			}
	dTree(tstore);
	}   

在第6、7行,每次获得对象tstore中两个最小权重结点;

在第8、9行,修改tstore表中第min1、min2两行的pChild列,使这两个行的父结点等于新的这一行(第i行);

在第10行,则是读第min1、min2行的权重求和、结果在nw中;

在第11行,按新的权重nw构造一个结点,其左孩子是min1,右孩子是min2,s=0;

在第12、13行,则是把这一行新的记录插入到tstore中,同时也会显示在grid对象中;

最后,在第15行调用dTree(tstore)函数,显示在一个treeView对象中。

注意这个函数实际是在表9的第23行处补充的。

7. 显示Huffman树表中的树

显示一个树,在Ext系统中首先要构造Ext.tree.TreeNode类型的结点,这里和C#中的概念是一样的,Ext.tree.TreeNode类型的结点个数和Huffman表tstore中的行数是一致的,为此,就是这样的过程来构造这些Ext.tree.TreeNode类型的结点并显示出来:

function dTree(astore)
{
	var i,n;
	var TA=new Array();
	n=astore.getCount();
	for(i=0;i<n;i++)
		TA[i]=new Ext.tree.TreeNode({id:astore.getAt(i).get('id'),text:astore.getAt(i).get('w')});		for(i=0;i<n;i++)
		{
		var a = astore.getAt(i).get('lChild'); 
		var b = astore.getAt(i).get('rChild');
		if (a >= 0) TA[i].appendChild(TA[a]);
		if (b >= 0) TA[i].appendChild(TA[b]);
    		}
	treeView1=new Ext.tree.TreePanel({renderTo:"Tree",root:TA[n-1],width:300,height:400});
} 

这个函数的算法和C#中的完全一致,没有差别,只不过一些语句修改成JavaScript语句而已。
到这里,一个完整的Huffman树生成、显示程序完成了。

一定保留好这个程序的所有代码,这样的代码在随后的数据库课程中使用的非常广泛,它不仅仅是一个简单的树的问题,很多应用都需要类似的界面。而这个程序里最关键的数据对象tstore,在数据库中则要用Ajax技术来从数据库服务器中、通过一种叫WebServices的程序系统来获得,其中,相当多数的WebServices程序是由C#来编写的,由Ext执行结果也要通过C#的WebServices作用到数据库服务器中去。一个华丽的数据库应用系统,必须是在华丽的外观下实现的,而C#、Ext系统则是这个系统中最重要的组成部分。

随后,在数据库的课程中,我们将在VS2008中、使用C#、JavaScript Ext、SQLServer系统来完成这样的开发,所以这样的基础知识是非常关键的。

评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘一哥GIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值