1. 顺序查找 ( Sequential search )

顺序查找是按照序列原有顺序对 数组/链表 进行遍历比较查询的基本查找算法。

1.1 算法实现

  1. 从表中的最后一个数据元素开始,逐个同记录的关键字做比较
  2. 如果匹配成功,则查找成功;反之,如果直到表中第一个关键字查找完也没有成功匹配,则查找失败。
  3. 时间复杂度:O(n)

静态查找表既可以使用顺序表表示,也可以使用链表结构表示。虽然一个是数组、一个链表,但两者在做查找操作时,基本上大同小异。我们这里使用数组进行操作。

// 顺序查找--如果发现则返回查找到的值,否则返回0.
int SequentialSearch(int arr[], int len, int KeyData)
{// 第一种方法:每次循环都得考虑是否越界// int tmp = 0;// for (int i = 0; i < len; i++) {//   if (arr[i] == KeyData)//     return i;// }//第二种方法 优化int i;arr[0] = KeyData;  //设置arr[0]为关键字值,也叫做"哨兵"i = len - 1;  // 循环数组尾部开始while (arr[i] != KeyData) {i--;}return i;
}

1.2 测试

void printf_arr(int arr[],int size) //打印数组
{int i = 0;for (; i < size; i++) {printf("%d ", arr[i]);}printf ("\n");
}int main()
{int arr[] = {90, 70, 34, 35, 26, 89, 56};int len = sizeof (arr) / sizeof (arr[0]);printf ("原数据:\n");printf_arr (arr, len);int retData = SequentialSearch(arr, len, arr[6]);printf("找到数组[%d] 数据为: %d\n", retData, arr[6]);return 0;
}

2. 二分查找 ( Binary Search )

二分查找也称折半查找,是一种在有序数组中查找某一特定元素的搜索算法。我们可以从定义可知,运用二分搜索的前提是数组必须是有序的,这里需要注意的是,我们的输入不一定是数组,也可以是数组中某一区间的起始位置和终止位置。

  1. 必须采用顺序存储结构。
  2. 必须按关键字大小有序排列。
  3. 时间复杂度:O (lognlog_{n}logn​)

2.1 算法实现

int binary_search(int key,int a[],int n)
{int left, right, mid;int count = 0,count1=0;left = 0;right = n-1;while(left < right) {         //査找范围不为0时执行循环体语句count++;                  //count记录査找次数mid=(left + right) / 2;     //求中间位置printf ("第 %d 次查找, left : %d  right : %d  mid : %d\n", count, left, right, mid);if(key < a[mid])          //key小于中间值时right = mid - 1;         //确定左子表范围else if(key > a[mid])     //key 大于中间值时left = mid + 1;    //确定右子表范围else if(key == a[mid]) {  //当key等于中间值时,证明查找成功printf("\n查找成功!\n\n查找 %d 次!", count);    //输出査找次数及所査找元素在数组中的位置count1++;             //count1记录查找成功次数break;}}if(count1 == 0)    //判断是否查找失敗printf("查找失敗!");    //査找失敗输出no foundreturn mid;
}

2.2 测试

void printf_arr(int arr[],int size) //打印数组
{int i = 0;for (; i < size; i++) {printf("%d ", arr[i]);}printf ("\n");
}int main (void)
{int i, key, a[100], n;printf("请输入数组的长度:\n");scanf("%d",&n);    //输入数组元素个数printf("请输入数组元素:\n");for(i = 0; i < n; i++)scanf("%d",&a[i]);    //输入有序数列到数组a中printf ("\n原数据:\n");printf_arr (a, n);printf("\n请输入你想查找的元素:\n");scanf("%d",&key);    //输入要查找的关键字int pos = binary_search(key, a, n);if(pos != -1)printf("\n在数组 [%d] 找到元素:%d\n", pos, key);elseprintf("\n未在数组中找到元素: %d\n", key);return 0;
}

3. 插值查找 ( Interpolation Search )

  1. 插值查找,有序表的一种查找方式。
  2. 插值查找是根据查找关键字与查找表中最大最小记录关键字比较后的查找方法。
  3. 插值查找基于二分查找,将查找点的选择改进为自适应选择,提高查找效率。
  4. 对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。
  5. 复杂度分析:查找成功或者失败的时间复杂度均为O (log2log_{2}log2​(lognlog_{n}logn​))。

3.1 算法实现

折半查找这种查找方式,不是自适应的(也就是说是傻瓜式的)。二分查找中查找点计算如下: mid = (low + high) / 2,即mid = low + 1/2 * (high - low); 通过类比,我们可以将查找的点改进为如下:
mid = ((key - a[low]) * (high - low )) / (a[high] - a[low]) + low
也就是将上述的比例参数1/2改进为自适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。

int Interpolation_search(int *a, int key, int n)  //插值查找
{int mid, low, high;int count = 0,count1=0;low = 0,high = n - 1;while(low <= high){count++;mid = ((key - a[low]) * (high - low )) / (a[high] - a[low]) + low;printf ("第 %d 次查找, low : %d  high : %d  mid : %d\n", count, low, high, mid);if(a[mid] < key) {low = mid + 1;} else if (a[mid] == key) {printf("\n查找成功!\n\n查找 %d 次!",count);    //输出査找次数及所査找元素在数组中的位置count1++;break;} else {high = mid - 1;}}if(count1 == 0)    //判断是否查找失敗printf("查找失敗!");    //査找失敗输出no foundreturn mid;
}

3.2 测试

void printf_arr(int arr[],int size) //打印数组
{int i = 0;for (; i < size; i++) {printf("%d ", arr[i]);}printf ("\n");
}int main()
{int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int n = sizeof (arr) / sizeof (arr[0]);int key;printf ("\n原数据:\n");printf_arr (arr, n);printf("请输入要查找的数字:\n");scanf("%d",&key);int pos = Interpolation_search(arr, key, n);if(pos != -1)printf("\n在数组 [%d] 找到元素:%d\n", pos, key);elseprintf("\n未在数组中找到元素: %d\n", key);return 0;}

4. 斐波那契查找 ( Fibonacci Search )

  1. 黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。
  2. 也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。
  3. 时间复杂度: log2nlog_2{n}log2​n

4.1 算法实现

相对于折半查找,一般将待比较的key值与第mid=(low+high)/2位置的元素比较,比较结果分三种情况:

  1. 相等,mid位置的元素即为所求

  2. 大于, low = mid + 1;

  3. 小于,high = mid - 1。

斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1;

开始将k值与第F(k-1)位置的记录进行比较(及mid = low + F(k-1)-1),比较结果也分为三种

  1. 相等,mid位置的元素即为所求
  2. 大于,low=mid+1,k-=2;
    说明:low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找。
  3. 小于,high=mid-1,k-=1。
    说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归 的应用斐波那契查找。

核心点:

  1. 斐波那契是一种特殊的分割方法,和二分、插值本质上是一样的,都是分割方法;
  2. 利用了斐波那契数列特殊的性质,一个长度只要可以被黄金分割,那么分割后的片段仍然可以继续进行黄金分割,循环。

首先,我们构造一个完整的斐波那契数列,然后开始分,小于就取左边的分割,F变为F-1;大于就取右边的分割,F变为F-2。

#define MAXN 11  /*
*产生斐波那契数列
* */
void Fibonacci(int *f)
{int i;f[0] = 1;f[1] = 1;for (i = 2; i < MAXN; ++i)f[i] = f[i - 2] + f[i - 1];
}int Fibonacci_Search(int *a, int key, int n) //斐波那契查找
{int i, low = 0, high = n - 1;int mid = 0;int k = 0;int F[MAXN];int count = 0, count1 = 0;Fibonacci(F); while (n > F[k] - 1)          //计算出n在斐波那契中的数列  ++k;for (i = n; i < F[k] - 1; ++i) //把数组补全  a[i] = a[high];while (low <= high) {count++;mid = low + F[k - 1] - 1;  //根据斐波那契数列进行黄金分割  printf ("第 %d 次查找, low : %d  high : %d  mid : %d\n", count, low, high, mid);if (a[mid] > key) {high = mid - 1;k = k - 1;} else if (a[mid] < key) {low = mid + 1;k = k - 2;} else {if (mid <= high) { //如果为真则找到相应的位置printf("\n查找成功!\n\n查找 %d 次!",count);count1++;break;} else {mid = -1;break;}}}if(count1 == 0) {  //判断是否查找失敗printf("查找失敗!");  //査找失敗输出no foundmid = -1;}return mid;
}

4.2 测试

void printf_arr(int arr[],int size) //打印数组
{int i = 0;for (; i < size; i++) {printf("%d ", arr[i]);}printf ("\n");
}int main()
{int a[MAXN] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int k, res = 0;int n = sizeof (a) / sizeof (a[0]);printf ("\n原数据:\n");printf_arr (a, n);printf("请输入要查找的数字:\n");scanf("%d", &k);res = Fibonacci_Search(a, k, n);if (res != -1)printf("\n在数组的第%d个位置找到元素:%d\n", res + 1, k);elseprintf("\n未在数组中找到元素:%d\n", k);return 0;
}

5. 分块查找 ( Block search )

  1. 分块查找也叫索引顺序查找,是折半查找和顺序查找的一种改进方法
  2. 分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。

5.1 算法实现

将n个数据元素"按块有序"划分为m块(m ≤ n)。每一块中的结点不必有序,但块与块之间必须"按块有序";即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,……

算法实现除了需要查找表本身之外,还需要根据查找表建立一个索引表。

主要包含两部分:

  1. 子表部分中最大的关键字
  2. 第一个关键字在总表中的位置

建立的索引表要求按照关键字进行升序排序,查找表要么整体有序,要么分块有序。

分块有序指的是第二个子表中所有关键字都要大于第一个子表中的最大关键字,第三个子表的所有关键字都要大于第二个子表中的最大关键字,依次类推。

struct index {  //定义块的结构int key;int start;
} newIndex[3];   //定义结构体数组int search (int key, int a[]);int cmp(const void *a, const void* b)
{return (*(struct index*)a).key>(*(struct index*)b).key ? 1 : -1;
}int BlockSearch(int key, int a[])
{int i, startValue;i = 0;while (i < 3 && key > newIndex[i].key) { //确定在哪个块中,遍历每个块,确定key在哪个块中i++;}if (i >= 3) {  //大于分得的块数,则返回0return -1;}startValue = newIndex[i].start;  //startValue等于块范围的起始值while (startValue <= startValue + 5 && a[startValue] != key) {startValue++;}if (startValue > startValue + 5) {  //如果大于块范围的结束值,则说明没有要查找的数return -1;}return startValue;
}

5.2 测试

int main()
{int i, j=-1, k, key;int a[] = {16, 11, 3, 19, 14,   34, 27, 56, 33, 54,    63, 61, 74, 77, 81};//确认模块的起始值和最大值for (i=0; i<3; i++) {newIndex[i].start = j+1;  //确定每个块范围的起始值j += 6;for (int k=newIndex[i].start; k<=j; k++) {if (newIndex[i].key<a[k]) {newIndex[i].key=a[k];}}}//对结构体按照 key 值进行排序qsort(newIndex,3, sizeof(newIndex[0]), cmp);//输入要查询的数,并调用函数进行查找printf("请输入您想要查找的数:\n");scanf("%d", &key);k = BlockSearch(key, a);//输出查找的结果if (k>0) {printf("查找成功!您要找的数在数组中的位置是:%d\n",k+1);} else {printf("查找失败!您要找的数不在数组中。\n");}return 0;
}

6. 树表查找 ( Tree table search )

最简单的树表查找算法——二叉树查找算法

参考链接:非线性结构——简单树相关

7. 哈希查找 ( Hash Search )

哈希查找是通过计算数据元素的存储地址进行查找的一种方法。

实现哈希查找的步骤如下:

  1. 用给定的哈希函数构造哈希表;
  2. 根据选择的冲突处理方法解决地址冲突;
  3. 在哈希表的基础上执行哈希查找。

7.1 哈希表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

简而言之,哈希表的建立同数学函数类似,把函数中的 key 用查找记录时使用的关键字来代替,然后将关键字的值带入一个精心设计的公式中,就可以求出一个值,用这个值来表示记录存储的哈希地址。

哈希地址 = f (key)

哈希地址只是表示在查找表中的存储位置,而不是实际的物理存储位置。f()是一个函数,通过这个函数可以快速求出该关键字对应的的数据的哈希地址,称之为“哈希函数”。

7.1.1 哈希表的构建

7.1.1.1 直接定址法

哈希地址:f(key) = a * key + b (a,b为常数)

  • 优点:简单、均匀、无冲突。
  • 应用场景:需要事先知道关键字的分布情况,适合查找表较小且连续的情况

7.1.1.2 数字分析法

就是分析我们的关键字,取其中一段,或对其位移,叠加,用作地址。比如我们的学号,前 6 位都是一样的,但是后面 3 位都不相同,我们则可以用学号作为键,后面的 3 位做为我们的散列地址。如果我们这样还是容易产生冲突,则可以对抽取数字再进行处理。我们的目的只有一个,提供一个散列函数将关键字合理的分配到散列表的各位置。

在取法上尽量选择变化较多的位,避免冲突发生。

  • 优点:简单、均匀、适用于关键字位数较大的情况
  • 应用场景:关键字位数较大,知道关键字分布情况且关键字的若干位较均匀

7.1.1.3 折叠法

处理我们的关键字然后用作我们的散列地址,主要思路是将关键字从左到右分割成位数相等的几部分,然后叠加求和,并按散列表表长,取后几位作为散列地址。

比如我们的关键字是123456789,则我们分为三部分 123 ,456 ,789 然后将其相加得 1368 然后我们再取其后三位 368 作为我们的散列地址。

  • 优点:事先不需要知道关键字情况

  • 应用场景:适合关键字位数较多的情况

7.1.1.4 除留余数法

哈希地址:f(key) = key % p (p<=m) m为哈希表表长。

  • 优点:计算效率高,灵活
  • 应用场景:不知道关键字分布情况

7.1.1.5 乘法散列法

  1. 用关键字 k 乘上常数 A(0 < A < 1),并提取 k A 的小数部分
  2. 用 m 乘以这个值,再向下取整

哈希地址:f(k) = floor ( m * ( kA % 1 ) )

kA % 1 的含义是取 keyA 的小数部分

  • 优点:对 m 的选择不是特别关键一般选择它为 2 的某个幂次(m = 2 ^ p ,p为某个整数)
  • 应用场景:不知道关键字情况

7.1.1.6 平方取中法

这个方法就比较简单了,假设关键字是 321,那么他的平方就是 103041,再抽取中间的 3 位就是 030 或 304 用作散列地址。再比如关键字是 1234 那么它的平方就是 1522756 ,抽取中间 3 位就是 227 用作散列地址.

  • 优点:灵活,适用范围广泛
  • 适用场景:不知道关键字分布,而位数又不是很大的情况。

7.1.1.7 随机数法

哈希地址:f(key) = random(key)

这里 random 是随机函数,当 key 的长度不等时,采用这种方法比较合适。

  • 适用场景:关键字的长度不等时

7.1.2 处理哈希冲突的方法

对应不同的关键字可能获得相同的hash地址,即 key1≠key2,但是f(key1)=f(key2)。这种现象就是冲突,而且这种冲突只能尽可能的减少,不能完全避免。因为哈希函数是从关键字集合和地址集合的映像,通常关键字集合比较大,而地址集合的元素仅为哈希表中的地址值。

7.1.2.1 开放地址法

开放地址法就是一旦发生冲突,就去寻找下一个空的散列地址,只要列表足够大,空的散列地址总能找到,并将记录存入,为了使用开放寻址法插入一个元素,需要连续地检查散列表,或称为探查。

开放定址法 H(key)=(H(key)+ d)MOD m(其中 m 为哈希表的表长,d 为一个增量) 当得出的哈希地址产生冲突时,选取以下 3 种方法中的一种获取 d 的值,然后继续计算,直到计算出的哈希地址不在冲突为止,这 3 种方法为:
线性探测法:d=1,2,3,…,m-1
二次探测法:d=12,-12,22,-22,32,…
伪随机数探测法:d=伪随机数

7.1.2.2 再哈希法

利用不同的哈希函数再求得一个哈希地址,直到不出现冲突为止。

f,(key) = RH,( key ) (i = 1,2,3,4……k)

7.1.2.3 链地址法

key 不同 f(key) 相同的情况,我们将这些同义词存储在一个单链表中,这种表叫做同义词子表,散列表中只存储同义词子表的头指针。我们还是用刚才的例子,关键字集合为{12,67,56,16,25,37,22,29,15,47,48,21},表长为12,我们再用散列函数 f(key) = key mod 12。我们用了链地址法之后就再也不存在冲突了,无论有多少冲突,我们只需在同义词子表中添加结点即可。

7.1.2.4 公共溢出区法

在创建哈希表时,同时创建另一个表,将所有发生哈希冲突的记录都存储到溢出表。

7.2 算法实现

define HASHSIZE 7 //定义散列表长为数组的长度
#define NULLKEY -1typedef struct{int *elem;//数据元素存储地址,动态分配数组int count; //当前数据元素个数
}HashTable;//对哈希表进行初始化
void Init(HashTable *hashTable)
{int i;hashTable->elem = (int *)malloc(HASHSIZE*sizeof(int));hashTable->count = HASHSIZE;for (i = 0; i < HASHSIZE; i++) {hashTable->elem[i] = NULLKEY;}
}//哈希函数(除留余数法)
int Hash(int data)
{return data % HASHSIZE;
}//哈希表的插入函数,可用于构造哈希表
void Insert(HashTable *hashTable, int data)
{int hashAddress = Hash (data); //求哈希地址//发生冲突while(hashTable->elem[hashAddress] != NULLKEY){//利用开放定址法解决冲突hashAddress = (++hashAddress) % HASHSIZE;}hashTable->elem[hashAddress] = data;
}//哈希表的查找算法
int Search(HashTable *hashTable, int data)
{int hashAddress = Hash(data); //求哈希地址while(hashTable->elem[hashAddress] != data) {//发生冲突//利用开放定址法解决冲突hashAddress = (++hashAddress) % HASHSIZE;//如果查找到的地址中数据为NULL,或者经过一圈的遍历回到原位置,则查找失败if (hashTable->elem[hashAddress] == NULLKEY || hashAddress == Hash(data)){return -1;}}return hashAddress;
}

测试

int main(void)
{int i,result;HashTable hashTable;int arr[HASHSIZE]={13,29,27,28,26,30,38};//初始化哈希表Init(&hashTable);//利用插入函数构造哈希表for (i = 0; i < HASHSIZE; i++) {Insert(&hashTable, arr[i]);}//调用查找算法result = Search(&hashTable, 29);if (result==-1) printf("查找失败");else printf("29在哈希表中的位置是: %d\n",result+1);return  0;
}

C语言实现基础查找算法相关推荐

  1. c语言的七大查找算法,非常值得学习

    今天带着大家学习下,C语言七大查找算法!!!!!!!!!! 这里我们首先看下算法的概念: 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描 ...

  2. tail -f 查找关键字_C语言九种查找算法 | 总有一款适合你

    时间.空间复杂度比较 查找算法 平均时间复杂度 空间复杂度 查找条件 顺序查找 O(n) O(1) 无序或有序 二分查找(折半查找) O(log2n) O(1) 有序 插值查找 O(log2(log2 ...

  3. C语言入门基础——Brute-Force算法

    Brute-Force算法的基本思想是: 1) 从目标串s 的第一个字符起和模式串t的第一个字符进行比较,若相等,则继续逐个比较后续字符,否则从串s 的第二个字符起再重新和串t进行比较. 2) 依此类 ...

  4. 数据结构–七大查找算法总结

    查看全文 http://www.taodudu.cc/news/show-3546957.html 相关文章: C语言实现基础查找算法 查找算法--顺序查找 微信小程序之算法查询 Idea 配置git ...

  5. java 用折半查找,java折半查找算法

    //当 low>high 时表示查找区间为空,查找失败 } Java 代码: /** * 二分查找算法 * * @param srcArray 有序数组 * @param target 被查找的 ...

  6. C语言二分查找算法[基础算法]

    该算法一般适用于查找数组元素 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好,占用系统内存较少; 其缺点是要求待查表为有序表,且插入删除困难. 适用于不经常变动而查找频繁的有序列表. ...

  7. 家族关系查询系统程序设计算法思路_七大查找算法(附C语言代码实现)

    来自:Poll的笔记 - 博客园 链接:http://www.cnblogs.com/maybe2030/p/4715035.html 阅读目录 1.顺序查找 2.二分查找 3.插值查找 4.斐波那契 ...

  8. C语言基础排序算法-选择排序

    C语言基础排序算法-选择排序 什么是选择排序? 选择排序(Selection sort)是一种简单直观的排序算法,第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从 ...

  9. C语言基础排序算法-冒泡排序

    C语言基础排序算法-冒泡排序 什么是冒泡排序? 顾名思义,这种排序方法就像水中的气泡一样,从底逐渐往上冒,一次前进一步.我们来看一个例子,看看到底是怎么冒泡的.假设有一个数组3,2,5,4,1,我们希 ...

最新文章

  1. nginx转发请求_Nginx为什么高效?一文搞明白Nginx核心原理
  2. 在目录下所有文件中查找字符串
  3. 首发:徐亦达教授团队最新发表的两篇机器学习论文
  4. 通过JAVA对HDFS进行操作管理插件
  5. Yet Another Multiple Problem 同余定理 bfs
  6. ESP8266开发笔记
  7. 140行代码实现一个逼真的大雪纷飞的效果
  8. 速看 | 电子元器件如何确定好坏?
  9. mysql rsync复制,mysql复制又同步
  10. 输入法 java_使用 Utf7ime 输入法实现中文输入 Windows+Java 平台(完整步骤版)
  11. 鸿蒙对比ios流畅对比,鸿蒙OS对比iOS,华为再次“超越”,流畅度大幅领先苹果!...
  12. 二年级机器人伙伴看图写话_期末考试一二年级看图写话22篇,附范文!
  13. [渝粤教育] 中国地质大学 工程地质 复习题
  14. html5 微信 飞机 源码,[HTML5]微信飞机大战
  15. 衬线字体和非衬线字体
  16. 宝塔面板配置SSL证书
  17. 推荐几个常用的Python扩展工具包
  18. mysql dump 1449_关于mysqldump的ERROR 1449 问题
  19. 全系列毕业设计论文来了
  20. 数据库基本知识(MySql版)

热门文章

  1. $.inArray()方法介绍
  2. 非标品如何写标题、选关键词?淘宝非标品关键词怎么进行布局?
  3. 苹果怎么删除通讯录联系人_通讯录删除的号码怎么找回?苹果手机恢复方法
  4. 一文搞定Darma Cash(DMCH)!
  5. Mysql—快速安装、配置
  6. Arduino实战小项目: 数字时钟制作
  7. VGGNet学习笔记及仿真
  8. Linux inotify + Epoll实现机制
  9. 优漫动游:学ui设计的人后来都怎么样了?
  10. Python什么是闭包、闭包特征、定义闭包传入一个数求和并输出,定义一个装饰器:打印函数运行花费的时间,定义一个类:要求:包含一个对象属性,且用_(单下划线)命名的定义一个类方法(装饰器)