日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

信息论实验-信源编码算法 (Huffman and Shannonn Fano编码C++实现)

發布時間:2024/8/1 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信息论实验-信源编码算法 (Huffman and Shannonn Fano编码C++实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

實驗目的

1. 實現壓縮編碼算法——Huffman編碼 2. 實現壓縮編碼算法——Shannon Fano編碼 3. 實現壓縮編碼算法——LZ編碼 4. 實現壓縮編碼算法——算數編碼 5. 利用上述壓縮算法壓縮圖像、音頻、視頻文件,分析壓縮算法的性能。

** 先上源代碼,如果對實驗的源代碼感興趣的同學,請到小豬嘎嘎的倉庫下載**
信源編碼源代碼

第一章:Huffman編碼的實現

Huffman編碼原理

數據壓縮是一門通信原理里和計算機科學都會涉及到的學科,在通信中,一般稱為信源編碼,在計算機科學里,通常稱為數據壓縮,兩者沒有本質區別,從數學角度看,都是映射。壓縮可以分為有損壓縮和無損壓縮。有損壓縮,指的是壓縮之后無法還原原始信息,但是可以達到很高的壓縮率,主要應用于視頻、通話、圖像等信息的傳輸領域。無損壓縮則用于文本文件等必須完整還原信息的領域。
Huffman編碼是一種可變長編碼(VLC:ariable length coding)方式,于1952年由huffman提出。依據字符在需要編碼文件中出現的概率提供對字符的唯一編碼,并且保證了可變編碼的平均編碼最短,被稱為最優二叉樹,有時又稱為最佳編碼。

Huffman編碼過程

統計各個字符出現的頻率

當談到統計字符這里,經過了一番折騰后在這里我有很多想要總結的,對于數學專業的學生來講我覺得這里是一個很難跨越的坎,為什么呢?原因在于這里涉及到計算機的儲存原理,數據的讀取,存儲操作,這些操作都非常接近計算機底層,就拿數據的存儲來說,首先我們要搞明白什么是ASCII文件,什么是二進制文件,這兩類文件讀取有什么差別,在計算機里又是如何存儲的,這里參考網上博客的內容多多理解才好,這里我折騰了很久,首先搞明白ASCII和二進制文件這兩個概念(概念很重要),然后分析差別,最后學習C++提供的API,比較兩者的不同。而我們數學院的同學接觸計算機也不少,但是接觸底層的人很少,所以當談到一些數據結構、文件存儲、硬件編程等等就會趕腳很無助,因為平時大家最多的就是用Matlab實現一些算法,對底層的接觸的很少。當然Huffman算法也可以由Matlab來實現,我也看到網上有一些實例程序,但怎么說呢,如果用Matlab實現了Huffman我只能說,我學會了Huffman算法,但是不能說我學會了Huffman編碼。因為數據編碼這東西最直接聯系的就是數據傳輸,我們需要知道計算機是怎樣實現文件壓縮、傳輸的過程的,就必須深入底層了解它的本質。
數據的本質:0和1
在我弄不明白Huffman編碼的時候,我就問自己這樣一個問題:Huffman編碼是用來做什么的?信息論教科書上、數據結構教科書、各種Huffman編碼的解釋,Huffman 編碼是一種編碼方式,是一種用于無損數據壓縮的熵編碼(權編碼)算法等等各種解釋感覺很厲害的樣子。聽著好像懂了,但又好像沒懂。但是一邊看別人代碼,一邊寫自己代碼的過程,我變得有些心虛,心想我這是在做什么? 然后停下敲打鍵盤,想了一些問題。別擔心,絕對不是高大上的問題,都是特別特別弱智的問題,我說的是特別,對,老師您沒聽錯。
1. 什么是 ”編碼” ? 是的沒錯,就是這么弱智的問題,學了這么久信息論、C語言和數據結構我的確問了自己一個這么弱智的問題。似乎很簡單,但往往這么簡單的問題我們都忽略去思考了,最后發現:哦,原來我一直干的是這樣一件事。
2. 什么是ASCII編碼?什么是ASCII編碼,好像大家都知道到0的ASCII值是48,A打得ASCII值是65,即便不知道每一個字符的ASCII值,也知道在任何一本C語言教材的最后幾頁肯定有一張印有ASCII編碼的。具體什么是ASCII我在這里就不介紹了,網上有很多解釋,教科書也有很多,關鍵是理解。
3. Huffman為什么會出現?我覺的這個問題也弱智的很,但是這個問題在我寫Huffman編碼過程給了我很大的幫助。答案很簡單:為了壓縮數據。那么數據是什么?計算機里數據的本質就是0和1,那么怎么壓縮0和1?當然0和1不能壓縮,壓縮的是0和1的組合。0和1的組合代表的是什么? 組合代表的是信息,不同的組合代表不同的信息。回過頭去想ASCII編碼,ASCII是定長編碼,原來Huffman編碼實現的是傳輸同樣信息的情況下,盡量使平均碼長變得最小,這樣就實現了數據壓縮的目的。
回答完上面這些問題我才真正著手開始進行編程。
上面說道數據的讀取和存儲是一個很難繞過去的坎,那么到底怎么繞過去?剛開始我在糾結一個txt文檔和mp4文件在數據讀取時有什么不同嗎?答案是:有。txt文檔就是我們講的ASCII文件,每8bit一個字符,而mp4文件本質上又是圖像文件。這里真的很難繞過來,因為以前接觸過的C語言API大部分是讀取字符或字符串,很少用二進制的方式讀取。但是當這樣想后就明白了:所有文件在計算機里存儲的都是0和1。編碼的時候不用關心每個字符占多少bit,按照自己的編碼方式編,只要能恢復0和1數據即可。所以,所有數據都通過二進制的方式讀取,以二進制的方式存儲,這樣就沒有必要擔心文件類型所帶來的困惑了。
具體字符統計這部分我寫了一個count()函數。函數的輸入是一個文件的地址,輸出是文件中各個字符的統計向量。當然這個待壓縮文件不能過大,因為通過讀zip實現原理博客中我發現rar和zip等壓縮軟件之所以那么快是進行了很多優化,以我現在的時間和能力還搞不懂里面的一些東西,所以我寫的代碼運行很慢,但是結果是正確的,壓縮效果也很好。函數具體的實現在后面算法和性能分析部分講。
### 創建Huffman樹(核心)
根據字符的頻率按Huffman算法構建Huffman算法創建Huffman樹
步驟如下:

  • 為每個符號建立一個葉子節點,并加上其相應的發生頻率
  • 當有一個以上的節點存在時,進行下列循環:
    把這些節點作為帶權值的二叉樹的根節點,左右子樹為空
    選擇兩棵根結點權值最小的樹作為左右子樹構造一棵新的二叉樹,且至新的二叉樹的根結點的權值為其左右子樹上根結點的權值之和。
    把權值最小的兩個根節點移除
    將新的二叉樹加入隊列中。
  • 最后剩下的節點暨為根節點,存儲為root節點,用于后面壓縮編碼操作。
    樹的建立過程是從葉子節點往上走,直到根節點。
    建樹過程如下圖所示
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MmzD5hDX-1584452720736)(http://picture.piggygaga.top/InformationTheory/second/CreateTRee.png “CreateHuffmanTree”)]
    綠色橢圓表示葉子節點,棕色節點表示根節點,藍色橢圓表示中間節點,首先從最底層的葉子節點開始創建樹,然后向上走,建樹過程中每次建完樹的節點信息要從數組中刪除節點信息,方便后面的建樹操作。每次刪除兩個節點會建立一個新的合并節點,然后重新按頻率從小到大排序,執行同樣的操作直到最后剩下根節點,將根節點地址保存下來,在下一步壓縮數據時使用。
    經過此步驟,每個字符對應的Huffman編碼都可以得到。我們可以將編碼信息保存下來,類似ASCII編碼表一樣,我們把Huffman編碼表也保存下來。
  • Huffman編碼

    根據Huffman 樹實現編碼并將編碼結果和要編碼的數據建立映射關系,存儲的壓縮文件需要添加頭文件,用于解碼使用。
    重新從文件中讀取信息,此時不需要進行統計字符頻率,只需要在Huffman表中找到對應的Huffman編碼然后將編碼壓入壓縮文件中。
    壓縮文件包括兩部分:頭文件,數據部分。壓縮文件的結構見下圖
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1oeNATPi-1584452720737)(http://picture.piggygaga.top/InformationTheory/second/Huffmanfile.PNG “壓縮文件內容”)]
    壓縮數據首先以一個>開始表示這是一個Huffman壓縮數據,這樣做的目的是在解壓過程會判斷這是否是一個Huffman編碼文件,如果沒有這個標識,認定該文件不具備Huffman編碼文件的特性性,也就沒有辦法解壓。第二部分是頭文件,存儲著字符頻數,這樣做也是為了解壓方便,解壓過程和壓縮過程是兩個獨立的過程,將字符頻數存進頭文件,在解壓時需要利用頭文件字符頻數重新建立一棵Huffman樹,和壓縮過程的操作過程是一樣的。最后通過讀取源文件的字符,在Huffman編碼表中找到對應的字符編碼,將字符編碼壓進數據部分,因為Huffman編碼是異字頭碼,所以不需要做分隔,把所有數據壓進去即可。

    Huffman 解碼

    根據獲取的Huffman碼來逆向獲取編碼信息,而且從解壓文件中一次性獲取的數據是一個很長的字符串,這個串是壓縮后的huffman編碼,實際上是機器碼。
    解碼過程
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-G3OeNeIZ-1584452720738)(http://picture.piggygaga.top/InformationTheory/second/decode.png “解碼過程”)]
    解碼過程共分為3部分,首先程序讀取壓縮文件的頭部獲取字符頻數,并據此構建Huffman樹,其次讀取數據部分的Huffman編碼,并根據Huffman樹得到編碼的字符值,最后將字符壓入解壓文件中,如果讀到文件結尾,結束解碼過程。

    Huffman編碼算法C++實現和性能分析

    編程語言:C++
    編程環境:Visual studio 2015
    本次實驗我采用面向對象的編程思想,每種算法建立一個對象,Huffman編碼我建立了一個Huffman類。所有的編碼操作都是基于這個類。
    Huffman類如下所示

    class Huffman { public:struct HuffmanNode{unsigned char value; //節點值int frequency = 0; //節點頻數struct HuffmanNode *Lchild = NULL;struct HuffmanNode *Rchild = NULL;}; private:struct CountVector{unsigned char value; //字符int frequency = 0; //字符頻數struct HuffmanNode *nodeAddress = NULL;};struct HuffmanCode{unsigned char value;int frequency = 0;string code;int codelen;};//根節點static bool mysortfunction(CountVector A, CountVector B){ //用于sort排序算法return A.frequency < B.frequency;} public:HuffmanNode *root;string fileAddress;long int NumOfChar = 0;vector<CountVector> charCountFrequency; //用于存儲字符頻數vector<HuffmanCode> HuffmanCodeVec;Huffman(string sourcefile); //構造函數void count(); //統計各個字符的頻數函數void CreateHuffmanTree(vector<CountVector> charFrequency); //創建huffman樹void GetHuffmanCode(HuffmanNode *root, int len);void WriteCode(vector<HuffmanCode> hfCode);void Decode(string sourcefile, string dstfile); };

    程序調用過程中只會用到公有屬性和公有函數,所以下面依次介紹公有屬性和公有函數的功能。

  • root 是HuffmanNode類型的指針,用來存儲Huffman樹的根節點的地址。
  • fileAddress 是string類型字符串,用來存儲待壓縮文件的文件路徑。
  • NumOfCahr 是long int 類型的數據,表示文件中字符總數。
  • charCountFrequency 是CountVector 類型的數組,存儲每種字符的頻率。
  • HuffmanCodeVec 是HuffmanCode 類型的數組,存儲每種字符的Huffman編碼。
  • Huffman() 是構造函數,用來初始化對象。
  • count() 函數統計各個字符出現的頻數, 結果存在charCountFrequency中。
  • CreateHuffmanTree() 構造Huffman樹,結果存儲在root中。
  • GetHuffmanCode() 通過Huffman樹獲取Huffman編碼。
  • WriteCode() 文件壓縮函數,將原始文件的信息壓縮為拓展名為.dada的文件。
  • Decode() 文件解碼函數,輸入一個Huffman編碼后的.dada文件,輸出原始文件。
    主函數部分如下圖:
  • int main() {clock_t start, end, start1, end1;cout << "!-------------Huffman壓縮編碼---------!" << endl << endl;cout << "!--------------作者:小豬嘎嘎------------!" << endl << endl;cout << "!--------------壓縮程序----------------! " << endl << endl;cout << "!--------------csdn-------! " << endl << endl;string filePath;cout << "請輸入待編碼文件地址" << endl << endl;getline(cin, filePath);Huffman huf(filePath);start = clock();huf.count(); //獲取字符頻數存在charCountFrequency數組中cout << huf.charCountFrequency.size() << endl;//getchar();huf.CreateHuffmanTree(huf.charCountFrequency);huf.GetHuffmanCode(huf.root, 0);huf.WriteCode(huf.HuffmanCodeVec);end = clock();cout << "壓縮使用時間為 : " << double((end - start) / CLOCKS_PER_SEC) * 1000 << " /ms" << endl << endl;cout << "!--------------解碼程序------------!" << endl << endl;//cout << "!--------------請輸入待解碼的文件--------------!" << endl << endl;//string outfilePath;//getline(cin, outfilePath);//Huffman hufdecode(outfilePath);//huf.root = new Huffman::HuffmanNode;start1 = clock();Huffman hufde(filePath);hufde.Decode(filePath + ".dada", "./Out/" + filePath);end1 = clock();cout << "解碼使用時間為 : " << double((end1 - start1) / CLOCKS_PER_SEC) * 1000 << " /ms" << endl << endl;getchar(); }

    文件壓縮步驟:
    第一步:讀入待壓縮的文件名
    第二步:建立huf對象為Huffman類型
    第三步:cout()函數計算各個字符頻數
    第四步:CreatehuffmanTree()建立Huffman樹
    第五步:GetHuffmanCode()獲取Huffman編碼
    第六步:WriteCode()壓縮文件
    第七步:Decode() 解碼

  • 文本壓縮
    原始文本為一個名為haha.txt的文本文檔,該文檔大小為4096 bytes
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PgHukUKC-1584452720738)(http://picture.piggygaga.top/InformationTheory/second/hahaSource.PNG “文本文檔”)]
    壓縮后的文件為一個二進制文件,用二進制查看軟件打開后是亂碼文件
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Py35jVaH-1584452720739)(http://picture.piggygaga.top/InformationTheory/second/yasuo.PNG “二進制查看器查看”)]
    文件大小為10385Bytes,等等,10385Bytes,為啥變大了?不是壓縮么?
    這個現象后面解釋,下面繼續看解碼效果。
    解碼文件為out.txt文件
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4r9tvk5o-1584452720739)(http://picture.piggygaga.top/InformationTheory/second/hahaSource.PNG “解碼文件”)]
    我們可以看到解碼文件和原始文件一樣,所以正確性沒有任何問題。
    上面說道壓縮后的文件反而比原來的文件大,其實這并不奇怪,因為壓縮文件比原始文件多了數據頭部,head部分也是會占用一定的空間的,所以才會產生這種情況,所以Huffman編碼不適合文件很小的數據壓縮,數據要大一些才會有明顯差異。經過實驗測試文件大于1M后才會有壓縮效果。
  • 圖像壓縮
    測試圖片是功夫熊貓的一張圖片
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZBNkfDjh-1584452720740)(http://picture.piggygaga.top/InformationTheory/second/Abao.jpg “待壓縮圖像”)]
    圖片大小為47kb,壓縮后的圖像為48kb,因為圖片太小所以還是沒有明顯的壓縮效果。圖像文件之所以壓縮效果不好是因為圖像格式本身已經是經過壓縮后的文件,已經用Huffman壓縮算法或其他壓縮算法壓縮過了,不同的圖像格式有不同的壓縮算法,一般通常是集中算法混合使用,所以根據信息論理論,當壓縮的文件接近最佳壓縮比時此時無論怎樣做都無法進行更優的無損壓縮了,注意這里必須是無損壓縮,有損壓縮還是可以繼續進行的,這里Huffman是一種無損壓縮算法。
    壓縮用時:
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LAZnmIZJ-1584452720740)(http://picture.piggygaga.top/InformationTheory/second/KongFutime.PNG “壓縮用時”)]
    總共有256個字符被統計出來,壓縮數據耗時25000ms。解碼用時幾乎為0ms,所以可以看出解碼過程不需要統計字符頻數,速度相當快。
  • 視頻壓縮
    視頻壓縮的是《當愛已成往事》mv
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-x5vygBPR-1584452720741)(http://picture.piggygaga.top/InformationTheory/second/Love.PNG “love”)]
    文件大小為7.82kb,壓縮后的文件大小為:7.81壓縮率為99.8%
    綜上;程序可以對所有文件進行壓縮,當原始文件小于7M時,壓縮文件大于原始文件,并不能實現壓縮效果,當文件達到13M時壓縮比率可達到77%,且當文件越大壓縮效果越好
  • Huffman算法實現過程中的心得體會

    解碼過程出現了一些問題,開始出現文件錯誤的信息,后來調試發現root節點沒有賦予初始的空間,使得程序崩潰。后來解決這一問題后又出現了解碼文件亂碼的現象,這個問題真的是很坑,后來找到原因是:編碼和解碼過程中建的樹不一致,導致編碼和解碼的字符編碼不能對應產生了亂碼現象。現在程序可以完成獨立的編碼,獨立的解碼工作。總結一下Huffman編碼,通過程序實現的Huffman可以達到無損壓縮的目的,且文件越大壓縮的效果越好,當文件大于7M左右時可以達到壓縮的目的,文件小于7M左右時并不能達到壓縮目的。文件很大時可以達到很高的壓縮比例。但Huffman有一個很致命的缺點:很耗時。每次編碼都要統計字符頻數,在統計字符頻數的時候要遍歷一次文件,然后利用字符頻數向量建立Huffman樹,此后還要遍歷一次文件來壓縮文件,所以Huffman編碼非常耗時,主要時間花費在統計字符頻數那里。

    第二章:Shannon Fano編碼

    一. Shannon Fano編碼原理

    Fano編碼和Huffman編碼稍有不同,它不是最佳編碼方法,但有時也可以得到最佳的性能。Huffman是由葉子節點合并構建Huffman樹,利用的是合并的思想,而Fano編碼方法正好相反,Fano編碼是從整體進行分割,到最后葉子節點結束。
    首先,將信源符號以概率低賤的次序排列起來,將排列好的信源符號劃分成兩大組,使魅族的概率和近于相同,并各賦予一個二元嗎符號‘0’和‘1’.然后,將每一大組的信源符號再分成兩組,使同一組的兩個小組的概率近于相同,并分別賦予-個二元碼符號。依次下去,直至每個小組只剩一個心愿符號為止。最后,由前向后讀取碼符號序列。這樣,信源符號所對應的碼符號序列則為編得的碼字。

    二. Shannon Fano 編碼過程

  • 字符頻率統計
    和Huffman編碼類似Shannon Fano 編碼同樣也要經過字符統計。
  • 構建Fano樹
    這里是和Huffman編碼不一樣的地方,Huffman是由葉子節點向樹根的方向逐步構造Huffman編碼樹,而Shannon Fano 編碼是從樹根逐漸拆分執行遞歸操作,最后生成一顆編碼樹。
  • 獲取Fano編碼
  • 譯碼
  • 二. Shannon Fano 編碼的實現和性能分析

    Shannon Fano編碼通過建立一個Fano類實現。
    下面是Fano類的具體定義如下:

    class Fano { public:struct FanoNode{unsigned char value; // 字符struct FanoNode *Lchild = NULL; //左孩子struct FanoNode *Rchild = NULL; //右孩子}; private:struct CountVector{unsigned char value;int frequency = 0;struct FanoNode *nodeAddress = NULL;}; private:struct FanoCode{unsigned char value;int frequency;string code;int codelen;}; private:static bool mysortfunction(CountVector A, CountVector B){ //排序函數return A.frequency > B.frequency;} public:FanoNode *root; //存儲樹的結構string fileAddress;long int NumOfChar;vector<CountVector> charFrequency; //字符頻率vector<FanoCode> FanoCodeVec; //存儲Fano碼, 包括碼長,碼字Fano();void count();void open(string add);void CreateTree(vector<CountVector> charFrequency, FanoNode *rootNode);void GetFanoCode(FanoNode* root, int depth);void WriteCode(vector<FanoCode> HFCode); void Decode(string sourcefile, string dstfile); private:void splitVec(vector<CountVector> charFr, vector<CountVector> &charFr1, vector<CountVector> &charFr2); };

    關鍵屬性:

  • struct FanoNode : Shannon Fano樹的節點數據
  • struct CountVector : 用于存儲字符頻數的數據類型
  • FanoCode : 存儲Shannon Fano編碼的數據類型
  • FanoNode *root : 存儲Fano樹的根節點
  • string fileAddress : 待壓縮文件的路徑
  • vector charFrequency: 用于存儲所有字符頻數的向量
  • vector FanoCodeVec : 用于存儲所有字符的Shannon Fano編碼
    關鍵函數:
  • void open(string fileaddress) 打開待壓縮的文件
  • void cout() 獲取文件中所有字符的字符頻數。
  • void CreateTree(vector charFrequency, FanoNode *rootNode) 獲取Fano樹
  • void GetFanoCode(FanoNode* root, int depth) 獲取Fano編碼
  • void WriteCode(vector HFCode) 壓縮文件
  • void Decode(string sourcefile, string dstfile) 文件解壓。
    壓縮比例
    | | | | |
    |:-😐:-😐:-😐:-😐
    |原始文件 |890Bytes(文本)|46.7kb(圖片) |7.82M(視頻)|
    |壓縮文件| 1146Bytes| 47.9kb |7.81M|
    |壓縮率 |1.29 |1.025| 99.8%|
    |壓縮用時 |0/s |27/s| 6400/s|
    |解壓用時| 0/s |1/s |2400/s|
  • 由于程序設置問題,當文件大于13M后會堆棧溢出,這里后續需要調整程序進行優化。

    三. Shannon Fano編碼總結

    Shannon Fano編碼和Huffman編碼比較類似,編碼過程也沒有太大區別。唯一的區別在結果。Shannon Fano相比于Huffman編碼,其壓縮速率沒有差異,原因在于兩者都需要知道每種字符的概率信息,所以在編碼之前必須統計每種字符的頻數。另一方面,Shannon 平均壓縮比例要比Huffman的低一些,雖然有時Shannon Fano可以達到最優編碼,但是大部分情況是不能達到的,所以其平均壓縮比例要略低于Huffman編碼。
    由于篇幅有限,下一篇博客介紹LZ編碼和算數編碼,最后附上Huffman編碼和Fano編碼的源代碼

    HuffmanClass.h

    #include <iostream> #include <vector> #include <fstream> #include <algorithm> using namespace std; class Huffman { public:struct HuffmanNode{unsigned char value; //節點值int frequency = 0; //節點頻數struct HuffmanNode *Lchild = NULL;struct HuffmanNode *Rchild = NULL;}; private:struct CountVector{unsigned char value; //字符int frequency = 0; //字符頻數struct HuffmanNode *nodeAddress = NULL;};struct HuffmanCode{unsigned char value;int frequency = 0;string code;int codelen;};//根節點static bool mysortfunction(CountVector A, CountVector B){ //用于sort排序算法return A.frequency < B.frequency;} public:HuffmanNode *root;string fileAddress;long int NumOfChar = 0;vector<CountVector> charCountFrequency; //用于存儲字符頻數vector<HuffmanCode> HuffmanCodeVec;Huffman(string sourcefile); //構造函數void count(); //統計各個字符的頻數函數void CreateHuffmanTree(vector<CountVector> charFrequency); //創建huffman樹void GetHuffmanCode(HuffmanNode *root, int len);void WriteCode(vector<HuffmanCode> hfCode);void Decode(string sourcefile, string dstfile); };Huffman::Huffman(string sourcefile) {fileAddress = sourcefile; //初始化文件讀入地址 }void Huffman::count() {ifstream readfile;readfile.open(fileAddress, ios::in | ios::binary);unsigned char *now = new unsigned char; //存儲當前讀取到的字符while (!readfile.eof()){CountVector *presentChar = new CountVector; //讀取到的字符信息readfile.read((char*)now, sizeof(unsigned char));int flag = 0; //標志是否是新出現的字符for (int i = 0; i < charCountFrequency.size(); i++){if (*now == charCountFrequency[i].value){charCountFrequency[i].frequency++;NumOfChar++;flag = 1;}}if (flag == 0){presentChar->value = *now;presentChar->frequency++;NumOfChar++;charCountFrequency.push_back(*presentChar);}}readfile.close(); } void Huffman::CreateHuffmanTree(vector<CountVector> charFrequency) {vector<CountVector> buildtree;//HuffmanNode newNode;HuffmanNode *rootnode = new HuffmanNode;buildtree = charFrequency;sort(buildtree.begin(), buildtree.end(), mysortfunction);int treedepth = 0;while (buildtree.size() > 1){HuffmanNode *nodeLeft = new HuffmanNode,*nodeRight = new HuffmanNode,*newNode = new HuffmanNode;CountVector insertnew;if (buildtree[0].nodeAddress != NULL){ //如果是葉子節點的話 左右子樹的地址都為NULLnodeLeft->Lchild = buildtree[0].nodeAddress->Lchild;nodeLeft->Rchild = buildtree[0].nodeAddress->Rchild;}else{nodeLeft->Lchild = NULL;nodeLeft->Rchild = NULL;}if (buildtree[1].nodeAddress != NULL){nodeRight->Lchild = buildtree[1].nodeAddress->Lchild;nodeRight->Rchild = buildtree[1].nodeAddress->Rchild;}else{nodeRight->Lchild = NULL;nodeRight->Rchild = NULL;}nodeLeft->frequency = buildtree[0].frequency;nodeLeft->value = buildtree[0].value;nodeRight->frequency = buildtree[1].frequency;nodeRight->value = buildtree[1].value;newNode->frequency = nodeRight->frequency + nodeLeft->frequency;newNode->Lchild = nodeLeft;newNode->Rchild = nodeRight;insertnew.frequency = newNode->frequency;insertnew.value = 0;insertnew.nodeAddress = newNode;//vector<CountVector>::iterator it = buildtree.begin();buildtree.erase(buildtree.begin());//vector<CountVector>::iterator it = buildtree.begin();buildtree.erase(buildtree.begin());//vector<CountVector>::iterator it = buildtree.begin();buildtree.insert(buildtree.begin(), insertnew);sort(buildtree.begin(), buildtree.end(), mysortfunction); //每次更新完要排序rootnode = newNode;treedepth++;}//cout << treedepth;root = rootnode; } void Huffman::GetHuffmanCode(HuffmanNode* root, int depth) {static char code[512];//判斷左兒子if (root->Lchild != NULL){code[depth] = '0';code[depth + 1] = '\0';GetHuffmanCode(root->Lchild, depth + 1);}if (root->Rchild != NULL){code[depth] = '1';code[depth + 1] = '\0';GetHuffmanCode(root->Rchild, depth + 1);}else{HuffmanCode insertCode;int codelength = 0;for (int i = 0; i < charCountFrequency.size(); i++){if (root->value == charCountFrequency[i].value){insertCode.code = code;insertCode.value = charCountFrequency[i].value;insertCode.frequency = charCountFrequency[i].frequency;}}for (int j = 0; code[j] != '\0'; j++){codelength++;}insertCode.codelen = codelength;HuffmanCodeVec.push_back(insertCode);} } void Huffman::WriteCode(vector<HuffmanCode> HFCode) {//從文件總讀取字符并進行編碼int codeNum = HFCode.size();string address = fileAddress;ofstream writecode;ifstream read;read.open(address, ios::in | ios::binary); //讀入文件writecode.open(address + ".dada", ios::out | ios::binary); //以*.dada命名unsigned char *now = new unsigned char; //讀取的 當前字符unsigned char save = 0; //每一次保存一個字節的長度int len = 0;long int totalLen = 0; //文件編碼總長int last; //最后寫入時的位數for (int i = 0; i < HFCode.size(); i++){totalLen = totalLen + HFCode[i].codelen;}last = totalLen % 8;// 將Huffman編碼寫入頭部,當作頭文件方便譯碼操作。char head = '>';writecode.write((char*)&head, sizeof(char));writecode.write((char *)&codeNum, sizeof(int));writecode.write((char *)& last, sizeof(int)); //寫入最后一次寫入的位數for (int i = 0; i < codeNum; i++){ //寫入字符值和頻數writecode.write((char*)&charCountFrequency[i].value, sizeof(unsigned char));writecode.write((char*)&charCountFrequency[i].frequency, sizeof(int));}//read.read((char*)now, 1);read.read((char*)now, sizeof(unsigned char));while (!read.eof()){int flag = 0;for (int i = 0; i < HFCode.size(); i++){if (*now == HFCode[i].value){flag = 1;for (int j = 0; j < HFCode[i].codelen; j++){if (len != 0)save = save << 1;save = save | (HFCode[i].code[j] - '0');len++;if (len == 8){writecode.write((char *)&save, sizeof(unsigned char));save = 0;len = 0;}}}}if (flag == 0){cout << *now << "沒在表中找到" << endl;}read.read((char*)now, sizeof(unsigned char));//*now = read.get();}if (len != 0){writecode.write((char*)&save, sizeof(unsigned char));}read.close();writecode.close();} void Huffman::Decode(string sourcefile, string dstfile) {ifstream read;ofstream write;vector<CountVector> arr;unsigned char now; //讀取的當前字符int last = 0; //最后一次讀取的位數int n; //字符種數read.open(sourcefile, ios::in | ios::binary); //讀取解碼文件write.open(dstfile, ios::out | ios::binary); //打開解碼后的文件read.read((char*)&now, sizeof(now));if (!(now == '>')){cout << "該文件的Huffman編碼格式不正確" << endl << endl;read.close();return;}read.read((char*)&n, sizeof(int));read.read((char*)&last, sizeof(last));for (int i = 0; i < n; i++){CountVector *insert = new CountVector;read.read((char*)&(insert->value), sizeof(unsigned char));read.read((char*)&(insert->frequency), sizeof(int));arr.push_back(*insert);}this->root = new HuffmanNode;CreateHuffmanTree(arr);GetHuffmanCode(root, 0);HuffmanNode *pNow = root;unsigned char *temp = new unsigned char; //每次讀一個字節read.read((char*)temp, sizeof(unsigned char));while (!read.eof()){unsigned char *ifLast = new unsigned char; //用于判斷是否讀到文件末尾read.read((char*)ifLast, sizeof(unsigned char));int i;if (read.eof()){i = last - 1;}else{i = 7;}for (; i >= 0; i--){if ((*temp >> i & 1) == 0) //向右移動7位判斷讀出的是0 還是1 pNow = pNow->Lchild;elsepNow = pNow->Rchild;if (pNow->Lchild == NULL && pNow->Rchild == NULL){write.write((char*)&(pNow->value), sizeof(unsigned char));pNow = root;}}temp = ifLast;}read.close();write.close(); }

    HuffmanMain.cpp

    #include <string> #include "huffmanClass.h" #include <time.h> int main() {clock_t start, end, start1, end1;cout << "!-------------Huffman壓縮編碼---------!" << endl << endl;cout << "!--------------作者:小豬嘎嘎------------!" << endl << endl;cout << "!--------------壓縮程序----------------! " << endl << endl;cout << "!--------------csdn-------! " << endl << endl;string filePath;cout << "請輸入待編碼文件地址" << endl << endl;getline(cin, filePath);Huffman huf(filePath);start = clock();huf.count(); //獲取字符頻數存在charCountFrequency數組中cout << huf.charCountFrequency.size() << endl;//getchar();huf.CreateHuffmanTree(huf.charCountFrequency);huf.GetHuffmanCode(huf.root, 0);huf.WriteCode(huf.HuffmanCodeVec);end = clock();cout << "壓縮使用時間為 : " << double((end - start) / CLOCKS_PER_SEC) * 1000 << " /ms" << endl << endl;cout << "!--------------解碼程序------------!" << endl << endl;//cout << "!--------------請輸入待解碼的文件--------------!" << endl << endl;//string outfilePath;//getline(cin, outfilePath);//Huffman hufdecode(outfilePath);//huf.root = new Huffman::HuffmanNode;start1 = clock();Huffman hufde(filePath);hufde.Decode(filePath + ".dada", "./Out/" + filePath);end1 = clock();cout << "解碼使用時間為 : " << double((end1 - start1) / CLOCKS_PER_SEC) * 1000 << " /ms" << endl << endl; `getchar(); }

    ShannonFano.h

    #include <iostream> #include <vector> #include <fstream> #include <algorithm> using namespace std; class Fano { public:struct FanoNode{unsigned char value; // 字符struct FanoNode *Lchild = NULL; //左孩子struct FanoNode *Rchild = NULL; //右孩子}; private:struct CountVector{unsigned char value;int frequency = 0;struct FanoNode *nodeAddress = NULL;}; private:struct FanoCode{unsigned char value;int frequency;string code;int codelen;}; private:static bool mysortfunction(CountVector A, CountVector B){ //排序函數return A.frequency > B.frequency;} public:FanoNode *root; //存儲樹的結構string fileAddress;long int NumOfChar;vector<CountVector> charFrequency; //字符頻率vector<FanoCode> FanoCodeVec; //存儲Fano碼, 包括碼長,碼字Fano();void count();void open(string add);void CreateTree(vector<CountVector> charFrequency, FanoNode *rootNode);void GetFanoCode(FanoNode* root, int depth);void WriteCode(vector<FanoCode> HFCode); void Decode(string sourcefile, string dstfile); private:void splitVec(vector<CountVector> charFr, vector<CountVector> &charFr1, vector<CountVector> &charFr2); }; Fano::Fano() {NumOfChar = 0; } void Fano::open(string add) {fileAddress = add; } void Fano::count() {ifstream readfile;readfile.open(fileAddress, ios::in | ios::binary);unsigned char *now = new unsigned char; //′?′¢μ±?°?áè?μ?μ?×?·?while (!readfile.eof()){CountVector *presentChar = new CountVector; //?áè?μ?μ?×?·?D??¢readfile.read((char*)now, sizeof(unsigned char));int flag = 0; //±ê??ê?·?ê?D?3???μ?×?·?for (int i = 0; i < charFrequency.size(); i++){if (*now == charFrequency[i].value){charFrequency[i].frequency++;NumOfChar++;flag = 1;}}if (flag == 0){presentChar->value = *now;presentChar->frequency++;NumOfChar++;charFrequency.push_back(*presentChar);}}readfile.close(); } void Fano::CreateTree(vector<CountVector> charFr, FanoNode *rootNode) {vector<CountVector> buildtree = charFr;if (buildtree.size() == 1){//root->Lchild = new FanoNode;//root->Rchild = new FanoNode;rootNode->Lchild = NULL;rootNode->Rchild = NULL;rootNode->value = buildtree[0].value;}else{sort(buildtree.begin(), buildtree.end(), mysortfunction);vector<CountVector> charFr1, charFr2;splitVec(buildtree, charFr1, charFr2);rootNode->Lchild = new FanoNode;CreateTree(charFr1, rootNode->Lchild);rootNode->Rchild = new FanoNode;CreateTree(charFr2, rootNode->Rchild);rootNode->value = 0;}return; } void Fano::splitVec(vector<CountVector> charFr, vector<CountVector> &charFr1, vector<CountVector> &charFr2) {int length = charFr.size();if (length == 1){cout << "拆分的數組長度不夠" << endl;}long int NumOfCharf = 0;for (int i = 0; i < length; i++){NumOfCharf = NumOfCharf + charFr[i].frequency;}double ratio = 0;int splitIndex = 0; //切割處的索引for (int i = 0; i < length; i++){ratio = ratio + double(charFr[i].frequency / NumOfCharf);if (ratio > 0.5){if (i > 0){splitIndex = i - 1;break;}else{splitIndex = i;break;}}}for (int i = 0; i < splitIndex + 1; i++){charFr1.push_back(charFr[i]);}for (int i = splitIndex + 1; i < charFr.size(); i++){charFr2.push_back(charFr[i]);} } void Fano::GetFanoCode(FanoNode* root, int depth) {static char code[512];//?D??×ó?ù×óif (root->Lchild != NULL){code[depth] = '0';code[depth + 1] = '\0';GetFanoCode(root->Lchild, depth + 1);}if (root->Rchild != NULL){code[depth] = '1';code[depth + 1] = '\0';GetFanoCode(root->Rchild, depth + 1);}else{FanoCode insertCode;int codelength = 0;for (int i = 0; i < charFrequency.size(); i++){if (root->value == charFrequency[i].value){insertCode.code = code;insertCode.value = charFrequency[i].value;insertCode.frequency = charFrequency[i].frequency;}}for (int j = 0; code[j] != '\0'; j++){codelength++;}insertCode.codelen = codelength;FanoCodeVec.push_back(insertCode);} } void Fano::WriteCode(vector<FanoCode> HFCode) {//讀取文件并寫入數據int codeNum = HFCode.size();string address = fileAddress;ofstream writecode;ifstream read;read.open(address, ios::in | ios::binary); //以二進制方式讀取writecode.open(address + ".dada", ios::out | ios::binary); //以二進制方式寫入unsigned char *now = new unsigned char; //存儲字符值unsigned char save = 0; //保存當前字符int len = 0;long int totalLen = 0; //總長int last; //結尾字符長度for (int i = 0; i < HFCode.size(); i++){totalLen = totalLen + HFCode[i].codelen;}last = totalLen % 8;//char head = '>';writecode.write((char*)&head, sizeof(char));writecode.write((char *)&codeNum, sizeof(int));writecode.write((char *)& last, sizeof(int)); //D′è?×?oóò?′?D′è?μ???êyfor (int i = 0; i < codeNum; i++){ //D′è?×?·??μoí?μêywritecode.write((char*)&HFCode[i].value, sizeof(HFCode[i].value));writecode.write((char*)&HFCode[i].frequency, sizeof(HFCode[i].frequency));}//read.read((char*)now, 1);read.read((char*)now, sizeof(unsigned char));while (!read.eof()){int flag = 0;for (int i = 0; i < HFCode.size(); i++){if (*now == HFCode[i].value){flag = 1;for (int j = 0; j < HFCode[i].codelen; j++){if (len != 0)save = save << 1;save = save | (HFCode[i].code[j] - '0');len++;if (len == 8){writecode.write((char *)&save, sizeof(unsigned char));save = 0;len = 0;}}}}if (flag == 0){cout << *now << "沒有找到該字符屬性" << endl;}read.read((char*)now, sizeof(unsigned char));//*now = read.get();}if (len != 0){writecode.write((char*)&save, sizeof(unsigned char));}read.close();writecode.close(); } void Fano::Decode(string sourcefile, string dstfile) {ifstream read;ofstream write;vector<CountVector> arr;unsigned char now; //讀取的當前字符int last = 0; //最后一次讀取的位數int n; //字符種數read.open(sourcefile, ios::in | ios::binary); //讀取解碼文件write.open(dstfile, ios::out | ios::binary); //打開解碼后的文件read.read((char*)&now, sizeof(now));if (!(now == '>')){cout << "該文件的Huffman編碼格式不正確" << endl << endl;read.close();return;}read.read((char*)&n, sizeof(int));read.read((char*)&last, sizeof(last));for (int i = 0; i < n; i++){CountVector *insert = new CountVector;read.read((char*)&(insert->value), sizeof(unsigned char));read.read((char*)&(insert->frequency), sizeof(int));arr.push_back(*insert);}this->root = new FanoNode;CreateTree(arr, root);GetFanoCode(root, 0);FanoNode *pNow = root;unsigned char *temp = new unsigned char; //每次讀一個字節read.read((char*)temp, sizeof(unsigned char));while (!read.eof()){unsigned char *ifLast = new unsigned char; //用于判斷是否讀到文件末尾read.read((char*)ifLast, sizeof(unsigned char));int i;if (read.eof()){i = last - 1;}else{i = 7;}for (; i >= 0; i--){if ((*temp >> i & 1) == 0) //向右移動7位判斷讀出的是0 還是1 pNow = pNow->Lchild;elsepNow = pNow->Rchild;if (pNow->Lchild == NULL && pNow->Rchild == NULL){write.write((char*)&(pNow->value), sizeof(unsigned char));pNow = root;}}temp = ifLast;}read.close();write.close(); }

    Fano.cpp

    #include "fano.h" #include <string> #include <time.h> int main() {string filepath;cout << "請輸入待壓縮文件的地址" << endl << endl;getline(cin, filepath);clock_t start, end;start = clock();/*Fano myFano;myFano.open(filepath);myFano.count();myFano.root = new Fano::FanoNode;myFano.CreateTree(myFano.charFrequency, myFano.root);myFano.GetFanoCode(myFano.root, 0);myFano.WriteCode(myFano.FanoCodeVec);end = clock();cout << "壓縮文件用時:" << double((end - start) / CLOCKS_PER_SEC) << "/s" << endl;*/Fano myfanoDecode;myfanoDecode.open(filepath);myfanoDecode.Decode(filepath + ".dada", "./Result/ " + filepath);end = clock();cout << "解壓文件用時:" << double((start - end) / CLOCKS_PER_SEC) << "/s" << endl;getchar();}

    總結

    以上是生活随笔為你收集整理的信息论实验-信源编码算法 (Huffman and Shannonn Fano编码C++实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产一级片直播 | 成人免费网站视频 | 五月综合久久 | www.色爱 | 欧洲精品视频一区二区 | 免费看搞黄视频网站 | 国产高清精品在线观看 | 久久久久中文字幕 | 在线看v片成人 | 国产在线不卡精品 | 香蕉影院在线观看 | 中文字幕在线一二 | 久久免费视频一区 | 狂野欧美激情性xxxx欧美 | 一区二区三区韩国免费中文网站 | 五月花婷婷 | 精品免费久久久久久 | 99久久99视频只有精品 | 国产美女精品视频 | 波多野结衣电影一区二区 | 亚洲一区视频在线播放 | 毛片网在线播放 | 中文字幕在线播放第一页 | 97av影院 | 免费观看全黄做爰大片国产 | 日韩一区二区三区在线看 | 日韩一区二区三区视频在线 | 综合av在线| 精品久久一区二区三区 | av资源免费在线观看 | 天天鲁一鲁摸一摸爽一爽 | 91精品伦理| 超碰在线成人 | 在线观看色网 | 成人va天堂| 午夜精品久久久99热福利 | 97超级碰碰 | 综合在线亚洲 | 亚洲不卡av一区二区三区 | 99久视频| 国产一区二区三区视频在线 | 欧美午夜理伦三级在线观看 | 国产一在线精品一区在线观看 | 成人黄色影片在线 | 日韩| 91人人澡 | 欧美电影在线观看 | 亚洲精品乱码白浆高清久久久久久 | 五月开心六月婷婷 | 午夜国产福利在线观看 | 亚洲精品国产精品久久99 | 天天天插| 色天天综合网 | 国产亚洲婷婷 | 97在线公开视频 | 日韩av成人在线观看 | 激情av五月婷婷 | 最新不卡av| 夜夜看av | 怡红院av久久久久久久 | 91女神的呻吟细腰翘臀美女 | 国产一区二区视频在线播放 | av中文天堂 | 国产看片网站 | 99久久精品无码一区二区毛片 | 国产精品欧美 | 天天视频亚洲 | 人操人 | 久久国内精品视频 | 干 操 插 | 在线免费试看 | 91看片淫黄大片91 | 欧美日韩成人一区 | 91香蕉视频污在线 | 欧美日本三级 | 中国成人一区 | av免费在线看网站 | 欧美色图亚洲图片 | 久草在线免费色站 | 丁香花中文在线免费观看 | 97免费在线观看 | 五月天综合网站 | 成人毛片一区 | 成人羞羞视频在线观看免费 | 色综合久久综合中文综合网 | 视频一区二区精品 | 欧美激情第十页 | 日本aaaa级毛片在线看 | 97超碰人人澡人人 | 91成人精品观看 | 日韩精品免费一线在线观看 | 中国一 片免费观看 | 99视频一区二区 | 欧美精品成人在线 | 又黄又刺激的网站 | 五月婷婷操| 欧洲精品久久久久毛片完整版 | 中文字幕免费高清在线观看 | 亚洲精品久久久久中文字幕m男 | 蜜桃视频在线观看一区 | 日韩高清在线看 | 日日操网站| 久久天天躁狠狠躁亚洲综合公司 | 国产v视频| 国产高清av免费在线观看 | 天天色天天射天天综合网 | 欧美激情视频一区 | 国产69精品久久久久久久久久 | 久草在线视频免费资源观看 | 久久一区二区免费视频 | 国产精品成人在线观看 | 在线观看岛国片 | 久久久久久久久久影视 | 97在线看| 狠狠色狠狠色综合日日小说 | 日韩欧美精品免费 | 国产成人精品亚洲精品 | 日韩 在线a | 日韩电影一区二区三区 | 99999精品| 免费看的毛片 | 亚洲精品视频在线播放 | 免费观看性生交 | 99热99| 亚洲精品免费在线观看 | 国产91精品欧美 | 国产精品毛片久久 | 免费特级黄色片 | 成人网在线免费视频 | 国产日韩精品一区二区三区 | 人人爽人人爽人人爽 | 在线看中文字幕 | 人人干人人爽 | 五月色婷 | 成人一区电影 | 国产成人精品综合久久久久99 | 色婷婷av在线| 中文字幕免费高清在线观看 | 国产视频亚洲 | 最新中文字幕在线播放 | 精品中文字幕在线 | 五月婷在线 | 99在线观看免费视频精品观看 | 欧美国产日韩激情 | 狠狠躁夜夜躁人人爽超碰91 | 香蕉视频免费看 | 91看成人 | 青青河边草免费视频 | av3级在线 | 在线观看韩国av | 超碰在线9 | 中文字幕五区 | 久久婷婷色综合 | 久久久久免费电影 | 久草免费在线观看视频 | 国产一区二区播放 | 99国产精品一区二区 | 成年人免费电影在线观看 | 在线精品视频免费播放 | 久久久久| 国产精品久免费的黄网站 | 亚洲特级毛片 | 最近高清中文在线字幕在线观看 | 亚洲 欧美变态 另类 综合 | 97av视频| 免费av黄色| 日韩在线观看你懂的 | 久久午夜色播影院免费高清 | 国产精品久久精品 | 成人在线视频在线观看 | 夜夜夜夜操 | 午夜免费福利片 | 成人在线免费av | 亚洲激情视频 | 中文av一区二区 | 久久开心激情 | 国产伦精品一区二区三区在线 | 欧美尹人| 色噜噜在线观看 | 91视频电影 | 国产一级二级三级在线观看 | 中文字幕成人一区 | 99免费国产 | 精品视频999 | 天天在线操 | 日韩v在线 | 亚洲精选国产 | 国产视频一区二区三区在线 | 日韩视频在线观看免费 | 久久日韩精品 | 色婷婷久久久综合中文字幕 | 中文亚洲欧美日韩 | 久久精品www人人爽人人 | 亚洲精品欧美成人 | 99爱在线 | 黄色网www | 久久人91精品久久久久久不卡 | 日韩精品一卡 | 天天干天天摸 | 99视频久 | 少妇bbb好爽 | 国产剧情久久 | 欧美激情va永久在线播放 | 波多野结衣精品视频 | www.国产在线视频 | 狠狠狠色丁香婷婷综合久久五月 | 国产理论免费 | 91av福利视频 | 中文字幕在线播放第一页 | 欧美人牲| 成人资源在线观看 | 成人午夜电影网 | 久久精品国产v日韩v亚洲 | 99视频在线播放 | 狠狠色丁香婷婷综合欧美 | 中文字幕av在线不卡 | 亚洲黄色在线播放 | 久草色在线观看 | 欧美亚洲一级片 | 日本三级人妇 | av中文字幕在线观看网站 | 色中色亚洲| 99热在线精品观看 | 国产黄色片久久 | 色橹橹欧美在线观看视频高清 | 国产成人精品一区二区三区福利 | 一区二区三区免费在线播放 | 黄色片免费在线 | 久久国产精品久久精品 | 亚州欧美视频 | 成人三级视频 | 国产精品成人在线观看 | 国产精品久久久久久久久久久久午夜片 | 精品久久综合 | 亚洲色图色 | www.玖玖玖 | 欧美ⅹxxxxxx| 天天干中文字幕 | 九九热在线精品视频 | 免费网址你懂的 | 日韩1页| 国产色网| 成人免费观看网站 | 射射射av | 99精品久久久久久久 | 色综合夜色一区 | 中文网丁香综合网 | 亚洲国产高清在线观看视频 | 亚洲情影院 | 夜夜澡人模人人添人人看 | www.久久爱.cn| 天天色影院 | 99热这里只有精品8 久久综合毛片 | 国产精选在线观看 | 天天干夜夜擦 | 欧美性生活一级片 | 久久不色| 国产中文字幕大全 | 日韩网站免费观看 | 91av电影在线观看 | 五月婷网站 | 999在线观看视频 | av在线最新 | 91丨九色丨国产在线 | 中文字幕av一区二区三区四区 | 国产小视频在线观看 | 日韩免费在线网站 | 91av色| 婷婷香蕉 | 成人黄色在线观看视频 | www.国产视频 | 欧美色综合久久 | 国产不卡精品 | 伊甸园av在线 | 欧美一二三区播放 | a视频在线观看免费 | 在线观看黄色国产 | 超碰在线9| 岛国大片免费视频 | 国产精品免费大片视频 | 国产91精品久久久久 | 九九热精品视频在线观看 | 日韩在线电影观看 | 亚洲欧美视频一区二区三区 | 日韩一区视频在线 | 欧美韩国日本在线 | 国产一区二区三区免费在线观看 | 狠狠躁天天躁 | 日韩色高清 | 娇妻呻吟一区二区三区 | 麻豆传媒视频在线免费观看 | 中文字幕一区二区三区久久 | 射久久| 亚洲91中文字幕无线码三区 | 欧美一区二区免费在线观看 | 国产精品二区三区 | 国产小视频在线免费观看 | 97视频在线观看视频免费视频 | 国外成人在线视频网站 | 国产精品av久久久久久无 | 97视频免费在线 | 亚洲精品视频在 | 国产一区二区三区网站 | 亚洲无毛专区 | 在线观看免费福利 | 国产一区二区三区免费观看视频 | 欧美一级性生活片 | 国产精品av免费在线观看 | 中文字幕2021 | 一本一道波多野毛片中文在线 | 成片免费| 蜜臀av免费一区二区三区 | 爱干视频 | 99久久999久久久精玫瑰 | 超碰人人在线 | 久久久久久久久黄色 | 亚洲影院国产 | avv天堂| 五月婷婷中文网 | 在线观看免费成人av | 国产中文字幕在线播放 | 午夜视频久久久 | 国产日韩欧美在线影视 | 亚洲精品国偷拍自产在线观看 | 99在线高清视频在线播放 | 中文字幕人成一区 | 亚洲国产wwwccc36天堂 | 中文字幕欧美日韩va免费视频 | 国产精品久久久久久久久久新婚 | 亚洲欧美国内爽妇网 | 亚洲国产美女精品久久久久∴ | 在线观看资源 | 日日草天天干 | 狠狠干中文字幕 | 久久国产网站 | 国内精品久久久久影院优 | 日韩精品欧美专区 | 天天操天天干天天干 | 在线观看一区二区精品 | 91精品第一页| 激情综合网五月激情 | 日韩av电影中文字幕在线观看 | av片在线观看 | 日韩在线观看网站 | 五月婷婷激情六月 | 狠狠插狠狠干 | 久久中国精品 | 毛片888 | 午夜av电影 | 日韩一级黄色大片 | 国产免费二区 | 国产清纯在线 | 日日爽日日操 | 国产精品门事件 | 成人久久久久 | 亚洲理论在线观看 | 国产精品免费大片视频 | 久久免费国产电影 | 天天操天天干天天插 | 99色网站| 五月婷婷一区二区三区 | 2021国产在线视频 | 欧美精品亚洲精品 | 日韩和的一区二在线 | 亚洲不卡av一区二区三区 | 狠狠操精品 | 久久理伦片 | 亚洲成人精品在线观看 | 国产h在线播放 | 在线小视频你懂的 | 国产精品免费麻豆入口 | 久久久久久久久久久免费 | 丝袜美腿亚洲综合 | 在线观看日韩专区 | 91精品国自产在线观看 | 婷婷成人亚洲综合国产xv88 | 中文字幕中文字幕 | 激情五月婷婷网 | 午夜精品电影 | 欧美aa一级 | 国产午夜在线 | 久久avav| 日韩欧美在线一区二区 | 国内精品在线观看视频 | 日韩黄色一级电影 | av综合av| 亚洲视频axxx | 成人av在线观 | 91刺激视频 | 狠狠躁夜夜躁人人爽超碰91 | 国产精品久久久久久欧美 | 亚洲经典中文字幕 | 亚洲欧美日韩精品久久奇米一区 | 免费看毛片网站 | 亚洲国产精品电影 | 日韩av黄 | 欧美伦理一区二区三区 | 国产日韩欧美在线观看 | 在线亚洲成人 | 欧美日韩国产二区 | 国产精品久久一卡二卡 | 国产资源站 | 日韩欧美观看 | 特级毛片网站 | 日韩一区正在播放 | 国产成人精品一区二区三区在线 | 超碰人人干人人 | 国产精品久久久久久久久岛 | 99精品在线免费在线观看 | 在线视频观看成人 | 久久网站免费 | 日韩av成人在线观看 | 天天干天天上 | 天天操天天操天天操 | 国产精品久久久久久久久久久久午夜 | a精品视频 | 欧美日韩高清国产 | 日本最新中文字幕 | 免费亚洲片 | 黄色毛片视频免费观看中文 | 久久精品人 | 免费91麻豆精品国产自产在线观看 | 亚洲天堂网视频在线观看 | av色影院 | 人人玩人人添人人 | 操操日 | 国产精品成久久久久 | 国产精品美女久久久久久久 | 欧美a级片免费看 | 久久成人亚洲欧美电影 | 日韩有码在线播放 | 99精品久久久久 | 国产精品美女免费 | 久久精品播放 | 91成人精品 | 天天透天天插 | av在线超碰 | 亚洲情感电影大片 | 亚洲国产精品成人va在线观看 | 久久精品一区二区三区四区 | 福利视频第一页 | 夜夜躁日日躁狠狠久久av | 成年人在线观看网站 | 黄色网www | 国产一级特黄电影 | 成人欧美日韩国产 | 在线观看国产日韩 | 99久久精品国产免费看不卡 | 中文字幕资源在线 | 亚洲欧美视频 | 国产精品成人免费精品自在线观看 | 综合久久久久 | 国内精品久久影院 | 国产精品久久久久久电影 | 日韩av高清在线观看 | 日韩欧美视频二区 | 日韩在线精品 | av免费试看 | 久久国产剧场电影 | 久色小说 | 亚洲不卡123 | 久久一区二区三区国产精品 | 四虎在线观看网址 | 一区二区三区韩国免费中文网站 | 精品一二区 | 婷婷久久五月 | 亚洲精品国精品久久99热 | 亚洲国产mv| 国产亚洲精品中文字幕 | 91看片淫黄大片一级在线观看 | 91香蕉国产在线观看软件 | 久久中文欧美 | 久久精品看片 | 在线电影91 | 久久草精品 | 久久成人国产精品入口 | 狠狠干综合| 国产黄网在线 | 亚洲1区 在线 | 亚洲成人一二三 | 中文字幕无吗 | 国产999久久久 | 在线一区av | h视频日本 | 欧美日韩精品网站 | 成人综合婷婷国产精品久久免费 | 精品欧美日韩 | 久久精品电影网 | 精品99免费视频 | 91视频久久久久久 | 国产亚洲免费的视频看 | 色视频在线免费 | 夜夜操狠狠干 | 日本中文在线观看 | 一级黄色片在线播放 | 天天插日日操 | 免费黄色小网站 | 欧美一区二区三区激情视频 | 狠狠狠操| 91网页版免费观看 | 色吊丝在线永久观看最新版本 | 青草视频在线看 | 亚洲精品视频网站在线观看 | 亚洲综合涩 | 久久精品91视频 | 九九免费在线观看视频 | 日本精a在线观看 | 夜夜爽天天爽 | 国产免费xvideos视频入口 | 中文字幕中文字幕中文字幕 | 亚洲久草网| 亚洲欧美视频在线播放 | 国产精品去看片 | 亚洲一区免费在线 | 国产在线黄| 欧美一区二区三区激情视频 | 最新不卡av| 国产成人精品一区二区三区网站观看 | 亚洲精欧美一区二区精品 | 亚洲综合成人婷婷小说 | 久草精品视频在线播放 | a在线观看视频 | 一级成人免费视频 | www.黄色在线| 91麻豆国产福利在线观看 | 久久伊人免费视频 | 国产精品久久久久久久久费观看 | 91精品国产高清自在线观看 | 亚洲 欧美 日韩 综合 | 免费h精品视频在线播放 | 色噜噜在线观看 | 六月激情久久 | 日韩视频在线观看免费 | 一区二区三区免费在线观看视频 | 日韩中文字幕在线不卡 | 狠狠88综合久久久久综合网 | 精品一二三四五区 | 欧美看片| 久久久精品久久 | 91九色老| 91九色在线| 三日本三级少妇三级99 | 午夜色婷婷 | 97av在线视频 | 亚洲免费不卡 | 国产日韩在线一区 | 日韩在线第一区 | 国产精品成人久久久久 | 日韩欧美视频免费看 | 国产精品www | 在线免费观看视频a | 精品一区av| 成年人国产视频 | 精品国产一区二区在线 | 美腿丝袜一区二区三区 | 国产精品久久久久久久午夜片 | 久久人视频 | 国产福利在线免费 | 久久免费播放视频 | 久艹视频在线免费观看 | 中文字幕九九 | 精品国产一区二区三区久久久蜜臀 | 精品久久久久一区二区国产 | 成人av在线看 | 美女国内精品自产拍在线播放 | 天天射天天艹 | 色99导航| 中文在线a√在线 | 久久久免费精品 | 久久综合九色综合欧美狠狠 | 在线观看aaa| 青草视频在线免费 | 97超碰人人网 | 国产成人一区二区三区久久精品 | 狠狠色丁香婷婷综合视频 | 国产精品99久久久久人中文网介绍 | 中国精品少妇 | 91chinese在线| 久久久久久久久毛片精品 | 99热免费在线 | 丁香婷婷色月天 | 操操操日日| 成人午夜久久 | 国产一线二线三线在线观看 | 视频成人免费 | 国产精品视屏 | 黄色一级网 | 黄色综合| 婷婷丁香六月天 | 韩国精品在线观看 | 国产美腿白丝袜足在线av | 在线观看黄色国产 | 国产a网站 | 国产激情小视频在线观看 | 在线视频免费观看 | 欧美精品一区二区三区四区在线 | 少妇精品久久久一区二区免费 | 成人9ⅰ免费影视网站 | 精品亚洲免a | 91超碰在线播放 | 精品国偷自产国产一区 | 日韩视频中文字幕 | 国产黄色资源 | 国产女v资源在线观看 | 久久九九久久 | 在线观看国产中文字幕 | 日韩在线视 | 99国产视频 | 在线成人欧美 | 国产精品99久久久久久小说 | 国产69精品久久久久99尤 | 国产亚洲精品美女久久 | 二区三区毛片 | 国产精品原创视频 | 天天躁日日躁狠狠 | 麻豆一区在线观看 | av高清影院 | 91精彩在线视频 | 美女国产| 欧洲成人av | 欧美日韩国产一区二区在线观看 | 国产精品手机视频 | 国产精品久久在线 | 色999视频 | 青青河边草观看完整版高清 | 日韩av午夜在线观看 | 久久国产精品影视 | 亚洲精品视频免费 | avav99| 日韩有码中文字幕在线 | 色综合色综合久久综合频道88 | 亚洲成人精品在线观看 | 亚洲日韩中文字幕在线播放 | 91激情视频在线观看 | 日本久久久久久久久久 | 91精品国产高清自在线观看 | 日本中文字幕在线观看 | 操久在线| 亚洲成人午夜在线 | 免费国产黄线在线观看视频 | 国产在线小视频 | 在线视频 91 | 六月丁香婷婷久久 | 中文字幕av网站 | 久久精品综合一区 | a在线观看视频 | 91久久国产自产拍夜夜嗨 | 国产精品免费观看国产网曝瓜 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 中文字幕在线看 | 丁香久久综合 | 最近2019好看的中文字幕免费 | 久草在线视频在线 | 美女久久久久久久久久久 | 国产精品片 | 国产精品 欧美 日韩 | 五月天网页 | 99久久久久 | 亚洲激情 在线 | av黄色影院| 91成人免费观看视频 | 成年人视频在线免费播放 | 国产精品久久久久久久久久久久午夜片 | 免费av网址大全 | 免费日韩 精品中文字幕视频在线 | 91久久精品一区 | 成人av中文字幕在线观看 | 黄色小网站在线观看 | 国产精品美女www爽爽爽视频 | 欧美性网站 | 亚洲最新av网站 | 亚洲综合视频在线观看 | 日韩中文字幕免费 | www.夜夜| 99精品国产成人一区二区 | 99精品国产福利在线观看免费 | 亚洲精品五月天 | 国内精品免费久久影院 | 色永久免费视频 | 精品国偷自产国产一区 | 国产精品1000| 波多野结衣精品 | 99久久精品国产亚洲 | 人人看97| 又色又爽又激情的59视频 | 欧美巨大荫蒂茸毛毛人妖 | 日韩欧美在线影院 | 一区二区伦理 | 国产麻豆视频在线观看 | av电影在线免费 | 7777xxxx | 成人欧美日韩国产 | 中文字幕日韩有码 | 国产精品高潮久久av | 成年免费在线视频 | 久久精品久久99精品久久 | 六月丁香六月婷婷 | 国产香蕉97碰碰久久人人 | 国产一区二区久久精品 | 国产福利91精品张津瑜 | 久久婷婷一区 | 这里有精品在线视频 | 亚洲精品中文在线 | 久热免费在线 | 五月婷婷激情综合 | 国产精品九九久久99视频 | 国产小视频在线免费观看视频 | 黄色片亚洲 | 日韩精品视频免费专区在线播放 | 精品国产久| 欧美二区在线播放 | 日韩电影一区二区三区在线观看 | 美女免费视频一区 | av一区在线 | 日韩伦理片一区二区三区 | 国产精品久久av | 久久亚洲私人国产精品va | 日韩一区精品 | 久久精品—区二区三区 | 天堂av在线7 | 美女天天操 | 精品国产123 | 久久999久久 | 97夜夜澡人人爽人人免费 | 五月综合激情 | 亚洲国产理论片 | 天天干天天色2020 | 97超碰人人澡人人 | 久久国产精品色婷婷 | 日韩免费电影网站 | 91九色在线视频 | 日韩专区在线 | 国产片免费在线观看视频 | 亚洲精品美女视频 | 麻豆免费看片 | 91精品老司机久久一区啪 | 97看片| 日韩精品一区二区三区在线视频 | 国产成人在线免费观看 | 天天操比| 日韩精品免费 | a在线观看免费视频 | 日韩免费视频观看 | 免费成人在线观看视频 | 久久精品第一页 | 久久国产精品免费观看 | 亚洲尺码电影av久久 | 欧美精品中文在线免费观看 | 日日日操操 | 精品一二三四五区 | 综合网婷婷 | 久久99久久99精品免视看婷婷 | 精产嫩模国品一二三区 | 国产91aaa | 欧美一二三四在线 | 91视频麻豆视频 | 欧美性生活免费 | 九九一级片 | 五月天中文字幕mv在线 | av丁香| 中文电影网 | 日韩资源在线播放 | 亚洲精品视频在线免费 | 一区二区三区在线电影 | 国产精品video| 欧美日韩中文在线 | 日韩欧美在线中文字幕 | 国产99久久久精品 | 国产精品视频地址 | 色综合久久综合中文综合网 | 亚洲电影影音先锋 | 国产精品igao视频网网址 | 91在线中文 | 福利电影一区二区 | 成年人视频免费在线播放 | av中文字幕在线看 | 在线观看亚洲精品视频 | 久久精品精品 | 狠狠操欧美| 国产精品h在线观看 | 在线v | 九九免费精品视频在线观看 | 91免费观看视频网站 | 国产精品一区欧美 | 射九九| 国产一级特黄毛片在线毛片 | 波多野结衣网址 | 99热精品国产 | 亚洲欧美视频在线 | 亚洲精品视频偷拍 | 国产99久久九九精品免费 | 最近中文字幕大全中文字幕免费 | 91精品老司机久久一区啪 | 久久精品在线免费观看 | av网站地址 | 久久久99精品免费观看 | 中文字幕免费一区 | 亚洲精品免费在线观看 | 中文字幕在线视频一区二区 | 国产精品成 | 日韩aa视频 | 国产手机视频在线观看 | 日韩高清dvd | av线上免费看 | 一本一道久久a久久精品 | 色久网 | 天天射天天干 | 黄a在线看 | 久久国产露脸精品国产 | 香蕉视频在线免费 | 激情在线免费视频 | 精品国产综合区久久久久久 | 91最新中文字幕 | 亚洲精品无| 国产色a在线观看 | 激情综合婷婷 | 九色视频网址 | 99视频国产在线 | 97国产在线播放 | 最新日韩在线观看 | 丝袜美女在线 | 丁香六月天 | 500部大龄熟乱视频 欧美日本三级 | 成人中心免费视频 | 精品999在线观看 | 91色亚洲| 91av亚洲 | 97在线观看视频 | 国产免费资源 | 成人国产精品免费 | 特级西西444www大精品视频免费看 | 一级黄色免费 | 久久乐九色婷婷综合色狠狠182 | 国产精品免费看 | 99久久久| 欧美日韩国产一二三区 | 亚洲专区在线视频 | 91黄色免费网站 | 精品一区二区三区香蕉蜜桃 | 超碰人在线 | 日本3级在线观看 | 91亚洲精品国偷拍 | 天天操操操操操 | 精品国产成人在线影院 | av一级片在线观看 | 午夜一级免费电影 | 最近更新好看的中文字幕 | 国产精品不卡在线观看 | 精品国产一区二区三区免费 | 欧美精品xxx | 色久av| 欧美另类交在线观看 | 成人黄色在线观看视频 | 日日夜夜天天久久 | 在线观看电影av | 黄色一级大片在线观看 | 五月天婷婷在线播放 | 国产视频资源在线观看 | 草免费视频 | 美女久久久久久久久久久 | 一区二区三区四区影院 | av网站播放| 国产精品久久久久久久久蜜臀 | 黄色片免费看 | 欧美日韩裸体免费视频 | 最新国产精品视频 | 日本在线观看视频一区 | 久久情侣偷拍 | 91成年人在线观看 | 在线观看aa| 免费黄色a网站 | 黄色软件在线观看 | 色综合久久88色综合天天人守婷 | 色综合综合 | 久久综合狠狠 | 久久激情视频免费观看 | 97在线观看视频 | av电影免费在线播放 | 久久精品亚洲精品国产欧美 | 91av综合| 国产手机av | 在线国产黄色 | 玖玖在线看 | 91成人在线免费观看 | 亚洲色图22p| bayu135国产精品视频 | 亚一亚二国产专区 | 91热爆视频| 欧美日韩性视频 | 久久久久久久久久久高潮一区二区 | 992tv在线观看| 亚洲黄色免费在线看 | 在线观看 国产 | 日韩精品视频久久 | 欧美成人手机版 | 久久大香线蕉app | 园产精品久久久久久久7电影 | 国产精品不卡一区 | 国产亚洲综合精品 | 色多多在线观看 | 久久毛片视频 | 久色 网 | 亚洲国产精品推荐 | 不卡的一区二区三区 | 人人插人人舔 | 精品福利网 | 欧美大香线蕉线伊人久久 | 日韩欧美成 | 91桃色在线免费观看 | 天天干夜夜操视频 | 久久成人国产精品一区二区 | 日韩欧美视频免费在线观看 | 国产精品视屏 | 福利一区二区在线 | 色婷婷六月天 | 天天躁天天狠天天透 | 最近高清中文字幕 | 日日日操 | www.日日操.com| 免费看的黄色网 | 亚洲视频免费在线观看 | av青草 | 欧美日韩性视频 | 久久久国产精华液 | 911在线 | 久久er99热精品一区二区三区 | www色片 | 国内精品久久久久久久久久 | 国产黄色成人 | 91麻豆视频网站 | 亚洲欧美日本一区二区三区 | 经典三级一区 | 4p变态网欧美系列 | 日p视频在线观看 | 91女子私密保健养生少妇 | 国产美女视频一区 | 欧美日韩裸体免费视频 | 在线观看完整版免费 | 色在线亚洲| 亚洲婷婷在线 | 亚洲国产免费看 | 男女视频91 | av成人免费观看 | 国产精品一区二区视频 | 国产手机在线播放 | 一级片视频在线 | 911香蕉| 手机看片1042 | www五月天com | 久久深夜福利免费观看 | 视频一区二区在线观看 | 国产黄色片久久 | 91精品国自产拍天天拍 | 亚洲精品综合欧美二区变态 | 成人性生交大片免费看中文网站 | 精品国产乱码久久 | 国产成人在线播放 | 伊人日日干 | 亚洲国产网站 | 99视频精品 | 97久久久免费福利网址 | 国内偷拍精品视频 | 超碰在线98 | 日韩欧美综合视频 | 天天草综合网 | 国产一级电影在线 | 国产精品情侣视频 | 免费av网站在线 | 麻豆一二三精选视频 | 久久成人亚洲欧美电影 | 超碰97人人干 | 精品一区二区三区香蕉蜜桃 | 精品国产伦一区二区三区观看说明 | 免费观看www视频 | 久久综合九色综合欧美就去吻 | 黄色一级大片在线观看 | 日韩精品首页 | 伊人婷婷久久 | 日韩精品中文字幕有码 | 久久天天躁狠狠躁亚洲综合公司 | 中文字幕有码在线观看 | 日韩| 精品欧美乱码久久久久久 | 麻豆一二| 精品国产免费久久 | 91av视频在线播放 | 久久精品网址 | 一区在线观看视频 | 国产亚洲激情视频在线 | 青青河边草免费观看完整版高清 | 成人福利在线 | 亚洲国产精品女人久久久 | 久久久久久久久毛片精品 | 久久久久亚洲国产精品 | 国产不卡视频在线 | 亚洲人人爱 | 国产欧美高清 | 手机版av在线|