C++ 哈希表构造及解决哈希冲突的代码实现

22 篇文章 3 订阅
订阅专栏

声明:本人所有测试代码环境都为vs2017

一.哈希的引入及概念

引入:当在顺序结构(如数组)或者平衡树(平衡二叉树)中查找一个元素时,必须要经过多次与内部元素进行比较的过程,顺序结构的查找时间复杂度为O(N),平衡树的查找时间为Olog(N),其查找的效率都取决于查找过程中元素的比较次数。

概念:那么相比之下,最为理想的查找方法是:不经过任何比较,一次直接从表中得到要搜索的元素。所以,通过构造一种存储结构,该结构内用某函数可以使得元素的存储位置与自身值之间的一种一一对应的映射关系,在查找时,通过该函数就可以很快找到元素,这种对应关系就称之为哈希,元素所存放的空间就称之为哈希表

二.哈希表的构造

由于后面解决哈希冲突的方法不同,哈希表的底层构造都不同。比如开放地址法底层借助vector,链地址法底层借助单链表,所以在这里分别给出两种方法的哈希表构造代码。

  • 开放地址法哈希表的构造代码:
/*为了简单,我规定哈希表中不能插入相同的元素。并且,哈希表中删除后的元素位置不能再插入
元素,也就是没有元素,但是位置还是被占有。所以我在实现代码时加入了三种状态:存在,空,
删除。只有状态为空的位置才可以插入元素。*/
enum STATE{EMPTY,EXIST,DELETE};//对应状态

/*封装元素结构体*/
template <class T>
struct Elem
{
	Elem(const T& data=T())
		:_data(data)
		,_state(EMPTY)
	{}
	T _data;
	STATE _state;
};

/*封装哈希表*/
//T:元素的类型
//isLine:非模板类型参数,代表是否选择线性探测来解决哈希冲突,是--线性探测,否--二次探测
template<class T, bool isLine = true>
class HashTable
{
public:
	HashTable(size_t capacity=10)
		: _size(0)
	{
		_vtable.resize(10);
	}
private:
    //哈希函数
    size_t HashFunc(const T& data)
	{
		return data% _vtable.capacity();
	}
private:
	vector<Elem<T>> _vtable; 
	size_t _size;//哈希表中存储的有效元素的个数
};
  • 链地址法哈希表构造方法
//节点结构体
template <class T>
struct HashNode
{
public:
	HashNode(const T& data = T())
		:_pNext(nullptr)
		,_data(data)
	{}
	HashNode<T>* _pNext;
	T _data;
};
//封装哈希表
template<class T>
class HashBucket
{
	typedef HashNode<T> Node;
public:
	HashBucket(size_t capacity = 10)
		:_size(0)
	{
		_vtable.resize(10);	
	}
private:
	size_t HashFunc(const T& data)const
	{
		return data % _vtable.capacity();
	}
private:
	vector<Node*> _vtable;//哈希表的每个哈希桶中存储的是节点的地址
	size_t _size;//有效元素个数
};

三.哈希冲突的产生

概念:不同元素通过哈希函数计算出相同的哈希地址,导致多个元素要插同一位置引起冲突。
举一个例子
假设现在有一组数据集合{1,7,6,4,5,9},哈希函数使用除留余数法(哈希函数可以有很多种,常见的有直接定址法,除留余数法等,具体每种方法的原理参考文章:https://wenku.baidu.com/view/61b121c06137ee06eff918c1.html),设哈为hash(value)=value%10,那么现在可以通过哈希函数将元素依次存放进哈希表
在这里插入图片描述
如果此时再插入一个元素55,则hash(55)=55%10=5,所以它和元素5的哈希地址相同,这就是哈希冲突。

四.解决哈希冲突的方法及代码实现

  1. 设计一个合理的哈希函数,但是还是不能从根本上解决
  2. 开放定址法(闭散列):从发生哈希冲突的位置开始,找下一个空位置,找空位置又分为两种方法:线性探测和非线性探测。

(1)线性探测:从当前位置依次往后找空位置,找到末尾时,地址下标置0, 从头开始查找。
优点:处理哈希冲突方式比较简单
缺点:一旦发生冲突,容易造成数据的堆积
解决:不挨着往后找空位置,避免产生数据堆积。解决方法:非线性探测里的二次探测

(2)非线性探测:二次探测:从当前位置,不采用依次往后查找,而通过公式来寻找下一个空位置。公式获取:H(i+1)=H(i)+2*i+1;i=1,2,3,4…代表查找次数。
找到末尾时,地址下标%表容量,保证每次是不同的位置;不能置0,会引起无休止的探测。
优点:可以解决线性探测中数据堆积的问题
缺点:如果表格中的空位置比较少,容易错过空位置,可能就需要探测多次

  1. 链地址法(开散列):将发生哈希冲突的元素放在同一个链表中

具体实现:采用哈希桶
(1)计算当前元素所在桶号
(2)在桶号对应链表查看看桶号位置是否有元素,无则直接插入,有则往下遍历该桶号对应链表,直到找到空位置
(3)插入元素

具体的相关函数实现代码:

  1. 开放定址法
//1.插入:
   a.通过哈希函数计算元素在哈希表中的位置
   b.如果当前位置状态不为empty:
	  (1)如果状态为exist,且当前位置数值与插入元素数值相同,直接返回
	  (2)如果状态为delete或为exist且data不同,则线性探测或者二次探测,直到找到empty的位置为止
   c.插入元素
bool Insert(const T& data)
	{
		//a.通过哈希函数计算元素在哈希表中的位置
		size_t hashAddr = HashFunc(data);
		size_t i = 0;//代表二次探测的探测次数
		
		//b.如果当前位置状态不为empty:
		while (_vtable[hashAddr]._state != EMPTY)
		{
			//(1)状态为exist,且当前位置数值与插入元素数值相同,即元素已经存在,直接退出
			if (_vtable[hashAddr]._state == EXIST && _vtable[hashAddr]._data == data)
			{
				return false;
			}
			//(2)状态为delete或为exist,且元素不存在,则继续探测

			//线性探测,依次往后遍历查找
			if (isLine)
			{
				hashAddr++;
				if (hashAddr == _vtable.capacity())//地址下标走到末尾
				{
					hashAddr = 0;
				}
			}
			//二次探测
			else
			{
				i++;
				hashAddr = hashAddr + 2 * i + 1;
				hashAddr %= _vtable.capacity();//保证每次是不同的位置
			}

		}
		//c.(循环结束,肯定已经找到空位置)插入元素
		_vtable[hashAddr]._data = data;
		_vtable[hashAddr]._state = EXIST;
		_size++;
		return true;
	}

 //2.查找:
   a.通过哈希函数计算元素在哈希表中的位置
   b.如果当前状态不为empty:
	   (1)如果状态为exist且元素相同,返回当前下标
	   (2)如果状态为delete或者为exist且data不同,则线性探测或者二次探测,直到找到empty的位置为止
int Find(const T& data)
	{
		//a.通过哈希函数计算元素在哈希表中的位置
		size_t hashAddr = HashFunc(data);

		size_t i = 0;//代表二次探测的探测次数

		//b.如果当前状态不为empty:
		while (_vtable[hashAddr]._state != EMPTY)
		{
			//(1)如果状态为EXIST且元素相同,返回当前下标
			if (_vtable[hashAddr]._state == EXIST && _vtable[hashAddr]._data == data)
			{
				return hashAddr;
			}
			//(2)如果状态为EXIST且data不同 或者 状态为DELETE,继续往后探测
			
			//线性探测
			if (isLine)
			{
				hashAddr++;
				if (hashAddr == _vtable.capacity())//地址下标走到末尾
				{
					hashAddr = 0;
				}
			}
			//二次探测
			else
			{
				i++;
				hashAddr = hashAddr + 2 * i + 1;
				hashAddr %= _vtable.capacity();//保证每次是不同的位置
			}
		}
		return -1;//未找到
	}

//3.删除:
  a.通过哈希函数计算元素在哈希表中的位置
  b.判断当前位置是否=被删除元素
	   是---删除
	   不是---继续向后探测
//删除
	bool Erase(const T& data)
	{
		size_t pos = HashFunc(data);
		if (pos != -1)
		{
			_vtable[pos]._state = DELETE;
			_size--;
			return true;
		}
		return false;
	}
  1. 链地址法
//1.插入:
  (1)通过哈希函数计算当前桶号
  (2)检测值为data的元素是否存在
    a.如果有,返回
    b.如果没有,插入新节点,头插
bool Insert(const T& data)
	{
		//1.计算桶号
		size_t bucketNum = HashFunc(data);
		//2.检测当前元素是否存在
		Node* pcur = _vtable[bucketNum];
		while (pcur)
		{
			if (pcur->_data == data)
			{
				return false;
			}
			pcur = pcur->_pNext;
		}
		//3.说明已有空位置,插入元素--头插
		pcur = new Node(data);
		pcur->_pNext = _vtable[bucketNum];
		_vtable[bucketNum] = pcur;
		_size++;
		return true;
	}
//2.删除(删除值为data的第一个元素)
(1)通过哈希函数计算当前桶号
(2)在桶号所在链表中寻找值为data的节点
    a.如果找到,删除
	b.找不到,继续往后找,直到末尾
bool Erase(const T& data)
	{
		//1.计算桶号
		size_t bucketNum = HashFunc(data);
		//2.寻找节点
		Node* pcur = _vtable[bucketNum];
		Node* pre = nullptr;
		while (pcur)
		{
			if (pcur->_data == data)
			{
				//删除节点
				//if (pre == nullptr)//删除的是第一个节点
				if (_vtable[bucketNum] == pcur)//删除的是第一个节点

				{
					_vtable[bucketNum] = pcur->_pNext;
				}
				else
				{
					//删除非第一个节点
					pre->_pNext = pcur->_pNext;
				}
				delete pcur;
				_size--;
				return true;
			}
			else
			{
				pre = pcur;
				pcur = pcur->_pNext;
			}
		}
		return false;
	}
//3.查找
(1)通过哈希函数计算当前桶号
(2)在桶号所在链表中寻找值为data的节点
    a.如果找到,返回
	b.找不到,继续往后找,直到末尾
Node* Find(const T& data)const
	{
		//1.计算桶号
		size_t bucketNum = HashFunc(data);
		//2.寻找节点
		Node* pcur = _vtable[bucketNum];
		while (pcur)
		{
			if (pcur->_data == data)
			{
				return pcur;
			}
			else
			{
				pcur = pcur->_pNext;
			}
		}
		return nullptr;
	}

代码还存在一些需要完善的地方
1.当哈希表的负载因子(哈希表元素个数/表容量)过大时,哈希表需要扩容,怎么扩容?
2.当哈希表中元素的data部分是非整型时,就无法进行哈希函数计算,需要封装一个转换方法,使得哈希函数可以适用于不同的数据类型。
3.为了简单,我设计的哈希函数时,除留余数法的除数直接写了10,但其实这个除数应该是一个素数,并且需要比当前表容量大,那么怎么来获取这个素数?
4.由于STL中的unordered系列关联式容器底层是通过链式定制法的哈希表来实现的,所以需要对该哈希表进行增加一些迭代器的封装等,适用于实现一些与hash相关的容器。
那么关于这些问题的解决,详情可以参考我的后期代码解决: https://github.com/Zhaotiedan/Code-Practice/tree/master/C%2B%2B/13-unordered%E7%B3%BB%E5%88%97%E5%85%B3%E8%81%94%E5%BC%8F%E5%AE%B9%E5%99%A8/%E5%93%88%E5%B8%8C

哈希表 数据结构学校使用
07-11
假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。 [测试数据] 取读者周围较熟悉的30个人名
哈希表设计问题.CPP
01-28
功能描述:针对自己的班同学名单设计一个哈希表,使得平均查找长度不超过2,完成相应的建表和查表程序。 设计要求:假设人名为中国姓名的汉语拼音形式,哈希函数用除留余数法构造,用链表法处理冲突。
C++ 哈希表
最新发布
Han同学
02-26 1689
C++哈希表
一个c++实现哈希表类-C++文档类资源
03-23
在程序中我们对关键字key应用散列函数H(key)来判断关键字key是否在散列表中,即计算H(key)的值,H(key)值确定所存数据在散列表中的位置。这样一个数据元素的地址是通过函数来计算的,所以数据元素并不需要按照特定的顺序来存放。但是散列函数H(key)将关键字映射为一个整数时,有可能两个关键字的地址相同,所以构造散列函数时要考虑尽量减少冲突的发生。构造散列函数有多种方法,如:平方取中法、除留余数随机数法。本程序采用除留余数法。程序的具体实现如下:本程序是用模板类myhash实现,包括protected和public属性成员。其中protected成员有*ht(自定义散列表指针)、*e
剑指offer-字符流中第一个不重复的字符(c++ hash
qq_40552827的博客
06-01 115
字符流中第一个不重复的字符 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符“go”时,第一个只出现一次的字符是“g”。当从该字符流中读出前六个字符“google”时,第一个只出现一次的字符时“l”。 如果当前字符流没有存在出现一次的字符,返回#字符。 题解: 利用hash表对字符进行存储,然后根据存储的顺序,找到 ...
C++自学笔记】哈希结构浅识(如何解决哈希冲突—闭散列、开散列)待更新~
C/C++菜鸟养成记
08-24 288
一、哈希概念 顺序结构以及平衡树中,元素的关键码与其存储位置之间没有对应关系,因此在查找一个元素的时候,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为数的高度,即O(log2N),搜索的效率取决于搜索过程中元素的比较次数; 理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素。如果构造一种存储结构,通过某种函数(hashFunc)使元素的存储位置与它的关键码...
C++】【哈希表】【哈希函数实现自己的哈希表解决哈希冲突;动态哈希表
多丰富下自己呀
06-26 2123
文章目录前言1、哈希表哈希函数的引入2、哈希表一、设计1、一般、通用哈希函数的设计2、默认哈希函数二、哈希冲突1、链地址法。(seperate chaining )1、1实现1.2、测试2、哈希表的动态空间优化参考 前言 1、哈希表哈希函数的引入 就像这道题来说,用一个26个的int 型数组,就可以实现对每个字符进行哈希映射。 其中哈希函数为:f(char) = char -‘a’ ;哈希表就是那个int [26]; 这种简单的哈希函数就处理了从键到索引的转换,同时也是简单的一一对应的。 而更复杂
C++ unordered_map实现方案,与hash冲突解决办法
yptsqc的博客
07-17 9393
unordered_map有点类似c++11之前的非标准库hash_map, c++11后, 加入了unordered_map, 可就用来代替之前的hash_map。 今天来看看unordered_map的底层实现。 END
C++实现哈希表 HashMap冲突链式解决
霖林烟雨
05-31 8130
简述: 考虑到有大量数据的情况,所以使用Hash表 使用泛型实现 TypeA 是Key的类型,TypeB 是value的类型 1. 主要函数 1). TypeB Put(HashNode 函数用来加入一个新的MapNode 2). TypeB Delete(const TypeA& key) 用来删除一个键值为key的节点 3). TypeB GetValue(const
哈希表冲突及处理冲突的方法(含例子)
Super_King_的博客
10-20 2571
哈希法又称散列法、杂凑法以及关键字地址计算法等,相应的表成为哈希表。基本思想:首先在元素的关键字K和元素的位置P之间建立一个对应关系f,使得P=f(K),其中f成为哈希函数。创建哈希表时,把关键字K的元素直接存入地址为f(K)的单元;查找关键字K的元素时利用哈希函数计算出该元素的存储位置P=f(K).
hash 表 --- 链地址法解决冲突
cai0612123的专栏
08-10 717
hashtable
一个c++实现哈希表
06-27
public成员包括构造函数、析构函数和复制构造函数以及=重载函数,其它成员函数主要有:traver(遍历散列表)、show()(打印出哈希表所存的元素)返回值为bool类型的函数search\insert\Delete。search函数(查询关键字为...
MFC 哈希表 小电话簿 线性探测法 除留取余法
06-26
从键盘输入各记录,以用户名为关键字建立哈希表哈希函数用除留取余数法构造, 采用线性探测法解决冲突。可以插入、查找、删除并显示给定用户名的记录, 并计算查找长度, 哈希表保存到文件中。 测试数据: 取自己...
C++】---哈希冲突(面试常考点)
L19002S的博客
08-16 1691
哈希冲突一、何为哈希二、何为哈希冲突三、如何解决哈希冲突1.闭散列线性探测插入删除线性探测的实现线性探测优化方案二次探测2.开散列开散列概念开散列实现开散列增容3.开散列与闭散列比较 一、何为哈希 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(log2N ),搜索的效率取决于搜索过程中元素的比较次数。 理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素。 如果构造一种存
C++】-- 哈希(上万字详细配图配代码从执行一步步讲解)
weixin_64609308的博客
01-02 907
C++】-- 哈希(上万字详细配图配代码从执行一步步讲解)详细讲解哈希处理数据查找的一些系列操作的亮眼操作之处。从数据结构的计数排序到哈希的哈希冲突哈希冲突解决:开散列、闭散列。
C++数据结构:哈希 -- unordered系列容器、哈希表的结构以及如何通过闭散列的方法解决哈希冲突
weixin_43908419的博客
05-14 1719
本文介绍了unordered系列的容器以及哈希的结构,并讲解了如何通过闭散列的方法解决哈希冲突然后进行了模拟实现
哈希表的【构造方法】【冲突处理方法】及【哈希拉链法的简单代码实现
行而不辍,未来可期 - King
09-08 5304
由于哈希表的查找高效性,在平时的算法中用的也是比较多。例如:字符串、单词个数的统计,只出现一次字符或者数字的统计,两个集合相同元素的查找等等,还有插入删除的高效(链地址法)都可以用哈希表解决。所以这里对其做一个小小的总结。缺点可能是需要占用额外的内存空间。一、哈希函数构造方法 下面介绍五种常用的哈希构造方法: 构造哈希函数的原则是: (1)函数本身便于计算; (2)计算出来的地址分布均匀,即对任一关键字k,f(k) 对应不同地址的概率相等,目的是尽可能减少冲突。 1、除留余数法; 取关键字被某个不大于
哈希表简述+常用算法代码
icc_hhy的博客
05-25 509
数组的特点:访问地址、数据容易,但删除和插入困难;而链表的特点:寻找地址困难,二插入和删除容易;是否有可能取其精华,构造出一种二者优势兼具的数据结构呢?这便是哈希表
C++实现从.txt文件中读取数据存入数组,将数组数据写入.txt文件
热门推荐
赵铁蛋的博客
04-29 2万+
声明: 编译器:vs2017 所有用到的.txt文件都是提前放在当前工程目录下的。 1.从.txt文件中读取数据,并存入数组 #include <iostream> #include <fstream> #include<vector> using namespace std; int main() { //读取数据文件 ifstream in("datadata.txt", ios::in); if (!in.is_open()) { cout
C++实现c++ 构造哈希表,并查询关键字K(整数)在哈希表中的结果:查询成功,返回K在哈希表中的位置
05-30
下面是一个简单的C++代码示例,实现构造哈希表和查询关键字K的功能: ```c++ #include #include using namespace std; // 定义哈希表的大小 const int HASH_SIZE = 101; // 哈希节点结构体 struct HashNode ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 打印二维数组的三种方法 36704
  • C++实现从.txt文件中读取数据存入数组,将数组数据写入.txt文件 29068
  • 求平均数的三种方法 19679
  • 浅析:2019高教社杯全国大学生数学建模竞赛题目---B题 “同心协力”策略研究 17861
  • C++中大小写转换的几种方式 16516

分类专栏

  • C/C++ 22篇
  • 刷题 8篇
  • 算法 1篇
  • 服务器搭建 1篇
  • 数学建模 2篇
  • git 1篇
  • C语言基础 25篇
  • 数据结构 7篇
  • Mysql 3篇
  • Linux 10篇

最新评论

  • C++实现从.txt文件中读取数据存入数组,将数组数据写入.txt文件

    m0_73768992: 大佬,为什么我这显示exit没有定义?

  • 浅析:2019高教社杯全国大学生数学建模竞赛题目---B题 “同心协力”策略研究

    『蝶殇』※花醉: 参加国赛前回顾往期的题进行训练表情包

  • Java和C的数组区别

    赵铁蛋: 当然是不存在这个元素的,只是可以这样理解C数组的线性结构

  • Java和C的数组区别

    秋名山小白: 请问“C中的数组是按线性结构顺序存储的,所以arr[0][4]与arr[1][0]是同一个元素”,arr[0][4]不是超过了数组下标吗,为什么和arr[1][0]是同一个元素?

  • C++实现从.txt文件中读取数据存入数组,将数组数据写入.txt文件

    昨日青空411: 怎么把数组中的字符串变成可计算的数组呢?

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • C++--手动实现循环队列(数组+链表)
  • 字典树(C++)
  • C++--力扣5 最长回文子串(动规)
2022年8篇
2021年2篇
2020年17篇
2019年39篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

聚圣源矿泉水公司起名鼠宝宝姓李起名给学校起名称宝宝起名软件哪个下载花豹突击队微信账号起名wcdma手机是什么意思举杯邀明月下一句程姓怎么起名字起点都市小说排行榜前十名雳剑氵字旁的有哪些字字起名字好大e梦见烧火宝宝免费起名字程序武汉翠堤春晓龙潭大峡谷火影忍者羁绊密码二笔画的字女孩起名武汉科技大学黄家湖校区台球风暴4东宫小说阅读免费劳动服务公司起什么名字方姓起名字女孩名字大全隐婚100分:惹火娇妻嫁一送一wecom弃后独步天下全文免费阅读小说考试作文合适起名字的宋词女生起什么名字好淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化