0
点赞
收藏
分享

微信扫一扫

学习日记:2022年1月21日(快排)

小北的爹 2022-01-21 阅读 61

第一个题目,最经典的快排

 

以题目中给出的数据为例

4 2 4 5 1

假设我们以第一个数字4为参照物,大的放右边,小的放左边

2 1 4 4 5

第二次我们是把它分成两组,2 1 4 和5以我们最开始的那个4为分界线

第一组的2 1 4 我们以2为参照物,大的放右边,小的放左边

变成1 2 4

第二组的5只有一个也不需要动

最后就得到了排序后的结果

也就是1 2 4 4 5

基本原理就是这样

代码如下:

#include"bits/stdc++.h"
using namespace std;
int data[100005];
int change;
void sorting(int start,int end)
{
    if(start>=end)
    return ;
    int i=start;
    int j=end;
    while(i<j)
    {
        while(data[j]>=data[start]&&i<j)
        j--;
        while(data[i]<=data[start]&&i<j)
        i++;
        {
            swap(data[i],data[j]);
        }
    }
    swap(data[start],data[i]);
    if(i>start)
    sorting(start,i-1);
    if(i<end)
    sorting(i+1,end);
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    scanf("%d",&data[i]);
    
    sorting(0,n-1);
    for(int  i=0;i<n;i++)
    printf("%d ",data[i]);
}

题目都写完了,

接下来就是今天自学的一些内容

第一个:哈夫曼树

哈夫曼树主要用来压缩编码的长度

以二进制为例:假设a是001,b是010,c是011,d是100,e是101,f是110,g是111

规定每3个为一段

如果有aaaaaaabbbbbbcccccddddeeeffg

7个a,6个b,5个c,4个d,3个e,2个f,1个g

一般编码出来就是

001 001 001 001 001 001 001 010 010 010 010 010 010 011 011 011 011 011 100 100 100 100 101 101 101 110 110 111 

没有空格的长度就是001001001001001001001010010010010010010011011011011011100100100100101101101110110111

一共84个

我们要通过哈夫曼树来进行编码的话,首先就是要计算出每个单词在其中的个数

按照从小到大排列

 根据出现次数最少的两个g和f生成一个根,根为所有叶子节点的次数总和

 重复上面的步骤,连接最小的两个根,生成一个新的根

 重复步骤

 重复步骤

 重复步骤

连接最后的两个 

 把位置调整一下,最终结果如下

 这样就生成了一棵哈夫曼树

我们制定一个规则

左边为0,右边为1

 根据从根节点到每一个节点,我们就得出了一套新的编码规则

a:11

b:01

c:101

d:100

e:001

f:0001

g:0000

观察一下就不难发现,出现次数比较多的都变短了,出现次数很少的变长了

我们继续那前面的来编码一下,看是不是会更短了

11111111111111010101010101101101101101101100100100100001001001000100010000

计算一下2*7+2*6+3*5+3*4+3*3+4*2+4=74,比前面的编码规则刚好少了十个

第二个内容就是字典树,又叫做前缀树

假设已知有一堆单词good  gold  goods  google goln

这样的一堆单词,请问以g开头的单词有哪些,以go开头的单词有哪些。

最简单的方法就是放把每个单词都放到数组里面去,然后一个一个的查找。如果单词的个数是n

需要查找的单词的长度为m那么时间复杂度就是n*m

单词量少一点就好说,但是单词量一旦大起来的话可能速度就不行了。像那些搜索引擎是如何快速定位关键的呢。

这种方法就是前缀树

 画出来大概就是这样子

如果我们查找以g开头的话,我们就从g开始寻找

以go开头的话,我们先找g再找o就这样找下去。方法显然是要比放在数组里面要快很多

在每一个单词的结尾都会有一个标记,用来标记从开头到这里表示的是一个单词的结尾

比如说good和goods,d的位置有一个标记,s的位置也有一个标记。

如果还要把每一个单词输出的话,为了避免还需要回溯或者保留原有的字符

我们也可以在标记的同时保留这个整个单词

举报

相关推荐

0 条评论