日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深夜爆肝:万字长文3种语言实现Huffman树(强烈建议三连) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、C語言能干大事
    • 1. C語言下Huffman樹的計算過程分析
    • 2. C語言下Huffman樹的編程
  • 二、C#語言也不賴
    • 1. C#下Huffman類的設(shè)計
    • 2. C#中界面設(shè)計
    • 3. 建立測試數(shù)據(jù)并顯示Huffman樹
    • 4. 輸入任意一組數(shù)據(jù),完成構(gòu)造Huffman樹
  • 三、JavaScript語言不愛聽了
    • 1. JavaScript下Huffman類的設(shè)計
    • 2. 把權(quán)重數(shù)據(jù)顯示在一個表格里
    • 3. 為表格添加命令按鈕
    • 4. 編寫添加一行的程序
    • 5. 編寫刪除一行的程序
    • 6. 用表格中的數(shù)據(jù)生成Huffman樹表
    • 7. 顯示Huffman樹表中的樹

一、C語言能干大事

1. C語言下Huffman樹的計算過程分析

例1 有權(quán)重集合分別是:5、29、7、8、14、23、3、11,計算Huffman樹。

這個題目的計算過程如下:

(1)首先是把數(shù)據(jù)填寫在以下表格里:


這個在編程中一定注意:空白格子里是NULL,這點不要搞錯。

首先是尋找到兩個最小權(quán)重的結(jié)點,找到的是第7、1號結(jié)點,權(quán)重合計是8,我們先標(biāo)記這兩個結(jié)點s=1(代表已經(jīng)處理過了),并生成第9號結(jié)點,權(quán)重是8,并讓第7、1號結(jié)點的父結(jié)點是9,第9號結(jié)點的左、右孩子分別是第7、1結(jié)點,就是如下表:


重復(fù)上面的過程,從頭尋找s=0的結(jié)點里、權(quán)重最小的兩個結(jié)點、就是第3、4號結(jié)點,權(quán)重合計是15,這樣,標(biāo)記這兩個結(jié)點s=1,并生成第10號結(jié)點,權(quán)重是15,而第7、8的父結(jié)點是第10號結(jié)點,第10號結(jié)點的左右孩子是第3、4號結(jié)點,就是下表:


重復(fù)這個過程,處理到第15個結(jié)點,使其權(quán)重合計為100,就是:


最終這個樹的計算到此結(jié)束,在這樣的表中計算出的過程以及結(jié)果,就是我們下面編程的主要依據(jù)。

2. C語言下Huffman樹的編程

針對前面介紹的表格,用C語言描述這樣的表就是:

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

對Huffman樹,由于它是正則二叉樹,所以有n個權(quán)重數(shù)據(jù)則必然有2*n-1個樹結(jié)點。

有了表的C語言定義,則首先是尋找未標(biāo)記的、權(quán)重最小的結(jié)點,如果這個表是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行,是一個典型的數(shù)組中求最小值的算法,在第13行,則必須標(biāo)記這個結(jié)點的S=1,說明該結(jié)點已經(jīng)使用過,最后則返回這個結(jié)點的編號。

有了這個函數(shù)后,首先要對H表進(jìn)行兩次求最小值的操作,就是:

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

如第i行是新增的一個結(jié)點,則讓該表第i行的權(quán)重為:

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

然后,就是設(shè)置這個結(jié)點的左右孩子結(jié)點為min1、min2,就是:

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

最后,就是設(shè)置編號min1、min2的結(jié)點的父結(jié)點是第i個結(jié)點。

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; }

注意這個函數(shù)第8行,它是從第n個結(jié)點開始循環(huán)的。

有了這兩個函數(shù)后,用一個測試的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); }

運行結(jié)果如下圖所示:

Huffman樹的C語言程序到此為止。

二、C#語言也不賴

1. C#下Huffman類的設(shè)計

僅僅針對前面C語言中的計算方法,設(shè)計一個類來完成計算過程,這個類就是:

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#中界面設(shè)計

有了這個類以后,我們可以在界面設(shè)計上拖進(jìn)兩個命令按鈕button1,button2,然后再拖進(jìn)一個treeView1控件和imageList1控件,然后開始以下設(shè)置:

(1) 選擇imageList1控件,找到屬性images,加入文件夾MyIcon中的兩個小圖標(biāo);

(2) 選擇treeView1控件,讓imageList屬性選中imageList1控件;

(3) 選擇treeView1控件,讓SelectImageIndex=1(打開書的圖標(biāo));

(4) 選擇treeView1控件,讓ImageIndex=0(關(guān)閉書的圖標(biāo));

(5) 選擇button1控件,修改text屬性為:”簡單測試”;

(6) 選擇button2控件,修改text屬性為:”結(jié)束”

3. 建立測試數(shù)據(jù)并顯示Huffman樹

設(shè)有權(quán)重數(shù)據(jù)為:5,29,7,8,14.23.3.11,注意權(quán)重數(shù)據(jù)和必須是100。首先是編寫從Huffman類數(shù)組中取得最小權(quán)重結(jié)點的函數(shù),這個函數(shù)編寫在Form1程序中,鼠標(biāo)雙擊button1,注意在button1_click()前面補充這樣的函數(shù),就是:


在這個函數(shù)中,H是Huffman結(jié)點對象數(shù)組,而N是這個數(shù)組的數(shù)據(jù)個數(shù),如果是上例,則N=15。
現(xiàn)在開始補充代碼如下:

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;}

這個函數(shù)同C的幾乎沒什么差別,同樣返回這個結(jié)點的下標(biāo)。有這個函數(shù)后,就可以構(gòu)造Huffman樹,跟隨著上面的函數(shù),繼續(xù)輸入就是:

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類型的樹,所以要按這個表格的內(nèi)容構(gòu)造TreeNode類對象的樹。

在treeView1控件中,顯示的結(jié)點個數(shù)同Huffman類的結(jié)點個數(shù)是一致的,而每個TreeNode類結(jié)點的Text內(nèi)容則是權(quán)重,于是緊跟著上面的函數(shù),寫以下函數(shù)就是:

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下的程序,按實驗數(shù)據(jù)有:

這組數(shù)據(jù)一共8個,所以Humman樹一共將有2*8-1=15個結(jié)點,鼠標(biāo)雙擊button1,寫進(jìn)以下程序:

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樹的測試程序設(shè)計完成。最后在button2_click()中補充代碼:this.close();讓程序能正常結(jié)束。

4. 輸入任意一組數(shù)據(jù),完成構(gòu)造Huffman樹

為完成這個要求,首先要在界面設(shè)計中再補充控件,有:

(1) 補充listBox1控件;

(2) 補充button3控件,修改Text屬性為:“輸入確認(rèn)”;

(3) 補充button4控件,修改Text屬性為:”生成Huffman樹”;

(4) 補充button5控件,修改Text屬性為:”清除”;

(5) 補充textBox1控件;

有了上述控件后,我們首先設(shè)計操作過程是:

在textBox1控件中輸入數(shù)據(jù),按下button3按鈕“輸入確認(rèn)”,則輸入的數(shù)據(jù)顯示在listBox1控件中,直到所有數(shù)據(jù)輸入完成,于是這樣的操作要求的程序就是:

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

listBox1控件是個數(shù)據(jù)容器,你可以不斷追加進(jìn)很多數(shù)據(jù),這些數(shù)據(jù)全部可以保存在這個控件中。直到按下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行,相當(dāng)于從listBox1控件中獲得數(shù)據(jù)項的個數(shù),在第9行,就是逐個取得每個數(shù)據(jù)項,并轉(zhuǎn)換成int類型、賦值給Huffman類對象數(shù)組中每個對象的權(quán)重W。最后按同樣的方式計算并顯示在treeView1中。

注意這個程序?qū)嶋H很不理想,沒判斷輸入的數(shù)據(jù)是否有負(fù)值、是否是非數(shù)字的字符串、是否和為100等等,這些詳細(xì)的判斷留給同學(xué)們自己去完成。

對于button5”清除”的編程非常簡單,就是:

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

程序運行效果:

三、JavaScript語言不愛聽了

1. JavaScript下Huffman類的設(shè)計

針對前面C語言中的計算方法,設(shè)計一個類來存儲數(shù)據(jù),如果你使用的Ext系統(tǒng),則強烈建議直接使用Ext.data.ArrayStore類對象直接構(gòu)造它,這樣的好處是顯示在表格里非常方便,于是說明對象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下說明了數(shù)據(jù),在field下說明了各個列的名稱、分別是id,w,pChild,lChild,rChild,s這樣的6列,如同下表:

2. 把權(quán)重數(shù)據(jù)顯示在一個表格里

但這個表用來顯示在界面上則非常不好看,我們需要一個友好的界面,所謂友好的界面就是說用漢字顯示、而不是奇怪符號顯示的界面,如:

我們一般把表2成為邏輯表,表3稱為顯示表,它們兩者之間的關(guān)系應(yīng)該是一一對應(yīng)的,唯獨列名稱不一樣。造成這樣的結(jié)果,主要原因是程序計算過程中,我們期望變量名都是英語字符,這樣非常方便編程,但顯示,則必須是漢字的表頭。

把這兩者統(tǒng)一起來:就是說讓“結(jié)點編號”指向邏輯表的“id”列,要用到Ext.grid.ColumnModel類型的對象,如該對象的名稱是colM,則定義如下:

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

注意JavaScript中、一旦出現(xiàn)[ ]則代表是數(shù)組,所以這些個列對象也就相當(dāng)于數(shù)組中的各個元素。

一個典型的設(shè)置就是:如將表格第1列顯示為“結(jié)點編號”、并和數(shù)據(jù)邏輯表tstore中的id關(guān)聯(lián)起來、并在該列上提供排序、而且該列可以編輯,則就是:

{header:"結(jié)點編號",dataIndex:'id',sortable:true,editor:new Ext.form.TextField() }

實際就是設(shè)置了列對象的4個屬性。這僅僅是為第一列,如果是所有列,則:

var colM=new Ext.grid.ColumnModel([{header:"結(jié)點編號",dataIndex:'id',sortable:true,editor:new Ext.form.TextField()},{header:"結(jié)點權(quán)重",dataIndex:'w',sortable:true,editor:new Ext.form.TextField()},{header:"父結(jié)點編號",dataIndex:'pChild',sortable:true,editor:new Ext.form.TextField()},{header:"左結(jié)點編號",dataIndex:'lChild',sortable:true,editor:new Ext.form.TextField()},{header:"右孩子編號",dataIndex:'rChild',sortable:true,editor:new Ext.form.TextField()},{header:"選擇狀態(tài)",dataIndex:'s',sortable:true,editor:new Ext.form.TextField()}]);

注意在最后一個列對象定義完后、第37行后沒有”,”,這點初學(xué)者一定要記著。

有了數(shù)據(jù)、有了列定義以后,就可以顯示表格了,顯示表格用的是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語言定義的一個分區(qū),就是,有了這個分區(qū),grid就將顯示在該區(qū)域里;
  • title:表示該表格的標(biāo)題;
  • height:表示該表格的高度;
  • width:表示該表格的寬度;
  • cm:表的列定義,需要一個列對象來說明各個列,如表4;
  • store:表示該表顯示的數(shù)據(jù)來自哪里,在我們的程序中,數(shù)據(jù)來自表1定義的tstore。
    將上述程序代碼合并到一個函數(shù)里就是:
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'}]});//表格上列名稱顯示、以及表格上數(shù)據(jù)處理方式。var colM=new Ext.grid.ColumnModel([{header:"結(jié)點編號",dataIndex:'id',sortable:true,editor:new Ext.form.TextField()},{header:"結(jié)點權(quán)重",dataIndex:'w',sortable:true,editor:new Ext.form.TextField()},{header:"父結(jié)點編號",dataIndex:'pChild',sortable:true,editor:new Ext.form.TextField()},{header:"左結(jié)點編號",dataIndex:'lChild',sortable:true,editor:new Ext.form.TextField()},{header:"右孩子編號",dataIndex:'rChild',sortable:true,editor:new Ext.form.TextField()},{header:"選擇狀態(tài)",dataIndex:'s',sortable:true,editor:new Ext.form.TextField()}]);//表格開始顯示數(shù)據(jù)。var grid=new Ext.grid.EditorGridPanel({renderTo:"hello",title:"Huffman樹",height:400,width:620,cm:colM,store:tstore});} Ext.onReady(fun);

有了表7的程序,我們打開m.html,這個程序是一個調(diào)用Ext類庫的模板程序,把表7的程序補充到這個程序里的fun()函數(shù)里即可執(zhí)行,結(jié)果將顯示一個表。

注意第72行不是這個函數(shù)中的語句,而是一條獨立的JavaScript語句。現(xiàn)在就可以以m.html為模板文件,加入表7的程序。

3. 為表格添加命令按鈕

如果一個程序僅僅能計算一組數(shù)據(jù),那么這個程序?qū)嶋H沒什么意義,為此,我們要給表格上加入三個命令按鈕,就是:添加、刪除、生成Huffman樹,使其能添加一行、刪除一行,并能根據(jù)新的數(shù)據(jù)生成Huffman樹。

給表格上添加三個命令按鈕,就是給grid對象上再說明一個工具條、并顯示出三個命令按鈕。也就是說給該對象的tbar屬性說明命令按鈕對象的屬性說明,就是:

tbar:[{按鈕對象1屬性},{按鈕對象2屬性},…{按鈕對象n屬性} ]

對一個命令按鈕屬性,比如產(chǎn)生一個叫”新增”的命令按鈕,則可以是這樣來說明:

{ text: "新增", iconCls: "add", handler: function(){ //以下寫進(jìn)新增加一行的代碼} }

text:表明這個按鈕上顯示的字符,如VB6中Command控件上的Caption屬性;

iconCls:這個按鈕上要顯示的圖標(biāo);

handler:function() { }:就是按下這個按鈕后的響應(yīng)程序;

同VB6的設(shè)計思路是一致的,但這里完全沒有VB6那樣的編程環(huán)境,所以逐個屬性只能自己在鍵盤上輸入。

現(xiàn)在,我們要在表格對象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(){ //以下寫進(jìn)新增加一行的代碼} }, { text: "生成Huffman樹", //iconCls: "refresh", handler: function(){ //以下寫進(jìn)生成新Huffman樹的代碼} }, { text: "刪除一行", //iconCls: "delete", handler: function(){ //以下寫進(jìn)表格中刪除一行的代碼} } ]});

注意同表5的對比。新增加的三個命令按鈕,在執(zhí)行h1.html的時候則就會看到。當(dāng)然,它們目前是什么都不會執(zhí)行,僅僅是有三個命令按鈕。

運行效果:

執(zhí)行h0.html和h1.html,看看這兩個網(wǎng)頁的差異。

4. 編寫添加一行的程序

編寫這個程序,實際就是為表8的第15行處補充代碼,補充這樣的代碼,首先要獲得表格中當(dāng)前有幾行,這個數(shù)據(jù)要從tstore中去獲得,就是:

var n=tstore.getCount();

然后構(gòu)造一個默認(rèn)的數(shù)據(jù)行,用的是:

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

就是說id的值是n,pChild=lChild=rChild=-1,s=0,讓權(quán)重w為空白。

最后,構(gòu)造一個第n行的記錄,并插入到tstore中去,就是:

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

一旦數(shù)據(jù)插入tstore,則在grid中會自動顯示結(jié)果。完整的函數(shù)就是:

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. 編寫刪除一行的程序

刪除一行數(shù)據(jù),首先要選中表中的一行,如果沒有選中,則要給出提示。

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

如果正常獲得了選中的行,則要找到這一行數(shù)據(jù)是在tstore中的哪一行,就是在對象tstore中按record來查找:

var index = tstore.indexOf(record);

這樣,index就是表格中對應(yīng)的行號,有了行號,就可以:

tstore.removeAt(index);

來刪除這一行。

但一定要注意:假如你沒有選中表格中的任何一行,執(zhí)行上面的過程則會發(fā)生錯誤,這個是非常重要的事情,否則刪除操作會讓程序經(jīng)常崩潰。為此,這段程序要加入到JavaScript語言的try過程中,就是

try
{
//這里加入要嘗試著做的程序段落
}
catch(err)
{
//如果嘗試著做的程序段無法正常執(zhí)行,則在這里給出錯誤的提示, err對象中有
//錯誤的描述。
}

注意這個語句,在C#中也有同樣的語句,這個語句非常重要,經(jīng)常會出現(xiàn)在一些需要嘗試著做的工作中,諸如在涉及到硬件訪問、用戶操作不確定的場合下,按這個語句的過程來執(zhí)行程序,則是必須的。有了這個過程,則完整的刪除程序就是:

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說明的一個組成部分。

現(xiàn)在運行h2.html,則可以測試加入一行數(shù)據(jù)、并刪除一行數(shù)據(jù)了。

6. 用表格中的數(shù)據(jù)生成Huffman樹表

要生成一個Huffman樹,則首先要從表格中計算各個結(jié)點的權(quán)重值,為此,又首先要獲得表格中未用過結(jié)點的最小權(quán)重結(jié)點,為此,編寫函數(shù)如下:

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;}

這個函數(shù)的參數(shù)是astore,函數(shù)是逐行讀這個對象中s=0的那些行,找到最小權(quán)重行的下標(biāo)值、并存在m中,查找完后,在第12行,把該行的s列修改為1,然后返回這個下標(biāo)值。這個算法的原理和C#是一致的。

有這個函數(shù)后,就可以在“生成Huffman樹”按鈕下的響應(yīng)程序里補充這些代碼,構(gòu)造一個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中兩個最小權(quán)重結(jié)點;

在第8、9行,修改tstore表中第min1、min2兩行的pChild列,使這兩個行的父結(jié)點等于新的這一行(第i行);

在第10行,則是讀第min1、min2行的權(quán)重求和、結(jié)果在nw中;

在第11行,按新的權(quán)重nw構(gòu)造一個結(jié)點,其左孩子是min1,右孩子是min2,s=0;

在第12、13行,則是把這一行新的記錄插入到tstore中,同時也會顯示在grid對象中;

最后,在第15行調(diào)用dTree(tstore)函數(shù),顯示在一個treeView對象中。

注意這個函數(shù)實際是在表9的第23行處補充的。

7. 顯示Huffman樹表中的樹

顯示一個樹,在Ext系統(tǒng)中首先要構(gòu)造Ext.tree.TreeNode類型的結(jié)點,這里和C#中的概念是一樣的,Ext.tree.TreeNode類型的結(jié)點個數(shù)和Huffman表tstore中的行數(shù)是一致的,為此,就是這樣的過程來構(gòu)造這些Ext.tree.TreeNode類型的結(jié)點并顯示出來:

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}); }

這個函數(shù)的算法和C#中的完全一致,沒有差別,只不過一些語句修改成JavaScript語句而已。
到這里,一個完整的Huffman樹生成、顯示程序完成了。

一定保留好這個程序的所有代碼,這樣的代碼在隨后的數(shù)據(jù)庫課程中使用的非常廣泛,它不僅僅是一個簡單的樹的問題,很多應(yīng)用都需要類似的界面。而這個程序里最關(guān)鍵的數(shù)據(jù)對象tstore,在數(shù)據(jù)庫中則要用Ajax技術(shù)來從數(shù)據(jù)庫服務(wù)器中、通過一種叫WebServices的程序系統(tǒng)來獲得,其中,相當(dāng)多數(shù)的WebServices程序是由C#來編寫的,由Ext執(zhí)行結(jié)果也要通過C#的WebServices作用到數(shù)據(jù)庫服務(wù)器中去。一個華麗的數(shù)據(jù)庫應(yīng)用系統(tǒng),必須是在華麗的外觀下實現(xiàn)的,而C#、Ext系統(tǒng)則是這個系統(tǒng)中最重要的組成部分。

隨后,在數(shù)據(jù)庫的課程中,我們將在VS2008中、使用C#、JavaScript Ext、SQLServer系統(tǒng)來完成這樣的開發(fā),所以這樣的基礎(chǔ)知識是非常關(guān)鍵的。

總結(jié)

以上是生活随笔為你收集整理的深夜爆肝:万字长文3种语言实现Huffman树(强烈建议三连)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本va在线观看 | 伊人首页 | 性久久久久久久久久 | 老司机在线永久免费观看 | 久久久久99精品成人片三人毛片 | 麻豆影视 | 亚洲成人手机在线 | 国产成人精品女人久久久 | 黄色av一区二区 | 国产精品久久久久久亚洲色 | 打屁股无遮挡网站 | 亚洲国产成人久久 | aa爱做片免费 | 夜色成人网 | 亚洲一区在线电影 | 一区二区三区不卡视频在线观看 | 蜜臀久久久久久999 大陆熟妇丰满多毛xxxⅹ | 天堂中文字幕在线 | 中文字幕精品三级久久久 | 国产三级伦理片 | 一级片一级 | 国产性―交一乱―色―情人 | 男女网站视频 | 亚洲中文一区二区 | 视频二区在线 | 无码少妇精品一区二区免费动态 | 夜夜骑天天干 | 麻豆乱码国产一区二区三区 | 国产视频三区 | 久久精品午夜 | 亚洲AV无码久久精品国产一区 | 美女诱惑一区二区 | 天天干天天操天天爱 | 黄色av网站免费在线观看 | 深夜影院深a | 成人一区二区精品 | 欧美一级免费黄色片 | 国产在线观看av | 欧美综合社区 | 欧美成人aa | 色窝窝无码一区二区三区成人网站 | 蜜乳av一区| 亚洲网站在线免费观看 | 依人久久 | 免费成人在线播放 | h视频在线观看网站 | 91精品国产乱码久久久张津瑜 | 国产又黄又粗又猛又爽 | 性猛交富婆╳xxx乱大交天津 | 中文精品无码中文字幕无码专区 | ,午夜性刺激免费看视频 | 亚洲综合精品 | 日韩成人在线网站 | 污片免费观看 | 日韩欧美猛交xxxxx无码 | 人妻饥渴偷公乱中文字幕 | 久久久久久香蕉 | 色吟av| 丰满少妇被猛烈进入一区二区 | 国内偷拍第一页 | 波多一区二区 | 日韩精品一| 五月天婷婷激情视频 | 天天干天天爱天天操 | 琪琪色影音先锋 | 无码人妻h动漫 | 韩日午夜在线资源一区二区 | 欧美一级在线免费观看 | 欧美一区二区区 | 亚洲少妇一区二区三区 | 欧美日韩一区二区三区国产精品成人 | 久久七| 中文字幕韩日 | 久久伊人五月天 | 亚洲精品高清视频在线观看 | 午夜小视频在线 | 久章草在线观看 | 国产精品刺激 | 国产精品无码永久免费不卡 | 一本一道久久综合 | 精品国产乱码一区二区三区99 | 欧美区国产区 | 激情六月天 | 国产日韩欧美91 | 在线中文视频 | 福利在线视频观看 | 国产精品欧美一区二区三区 | 精品视频一区二区三区四区五区 | 国产日产精品一区二区三区四区 | 亚洲网站一区 | 亚洲久久久 | 成人免费无码大片a毛片抽搐色欲 | 最污的网站 | 人人射视频 | 在线观看免费高清 | 欧美暧暧视频 | 黄色片欧美 | 天降女子在线 | 国产精品99无码一区二区 |