深圳 做网站 车公庙,使用阿里云建网站,windows10系统优化,凡客诚品售后文章目录 声明list的简单介绍list的简单使用list中sort效率测试list的简单模拟封装迭代器insert模拟erase模拟头插、尾插、头删、尾删模拟自定义类型迭代器遍历const迭代器clear和析构函数拷贝构造#xff08;传统写法#xff09;拷贝构造#xff08;现代写法#xff09; 源… 文章目录 声明list的简单介绍list的简单使用list中sort效率测试list的简单模拟封装迭代器insert模拟erase模拟头插、尾插、头删、尾删模拟自定义类型迭代器遍历const迭代器clear和析构函数拷贝构造传统写法拷贝构造现代写法 源码 声明
本文源代码已上传至我的gitee仓库欢迎查看list模拟实现源代码
list的简单介绍
在学习STL时一定要先阅读C文档 list使用文档
list是可以在常数范围内在任意位置进行插入和删除的序列式容器并且该容器可以前后双向迭代list的底层是双向链表结构双向链表中每个元素存储在互不相关的独立节点中在节点中通过指针指向其前一个元素和后一个元素。list与forward_list非常相似最主要的不同在于forward_list是单链表只能朝前迭代已让其更简单高效。与其他的序列式容器相比(arrayvectordeque)list通常在任意位置进行插入、移除元素的执行效率更好。与其他序列式容器相比list和forward_list最大的缺陷是不支持任意位置的随机访问比如要访问list的第6个元素必须从已知的位置(比如头部或者尾部)迭代到该位置在这段位置上迭代需要线性的时间开销list还需要一些额外的空间以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
list的简单使用
这里罗列列表的基本操作非常简单相信大家在学习完string、vector后学习list的功能非常简单
# define _CRT_SECURE_NO_WARNINGS
#includeiostream
#includelistusing namespace std;int main()
{listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);//迭代器listint::iterator it lt.begin();while (it ! lt.end()){cout *it ;it;}cout endl;//范围forfor (auto e : lt){cout e ;}cout endl;//逆置lt.reverse();for (auto e : lt){cout e ;}cout endl;//排序lt.sort();for (auto e : lt){cout e ;}cout endl;//节点转移listint lt1;lt1.push_back(10);lt1.push_back(20);lt1.push_back(30);lt1.push_back(40);lt.splice(lt.begin(), lt1);for (auto e : lt){cout e ;}cout endl;for (auto e : lt1){cout e ;}cout endl;return 0;
}运行结果
1 2 3 4 5
1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
10 20 30 40 1 2 3 4 5list中sort效率测试
表示双向循环链表以及数据初始化
void test_op()
{srand((unsigned int)time(NULL));const int N 1000000;vectorint v;v.reserve(N);listint lt1;listint lt2;for (int i 0; i N; i){int e rand();lt1.push_back(e);lt2.push_back(e);}// 拷贝到vector排序排完以后再拷贝回来int begin1 clock();for (auto e : lt1){v.push_back(e);}sort(v.begin(), v.end());size_t i 0;for (auto e : lt1){e v[i];}int end1 clock();//list调用自己的sortint begin2 clock();lt2.sort();int end2 clock();printf(vector sort:%d\n, end1 - begin1);printf(list sort:%d\n, end2 - begin2);
}测试结果发现list的sort排序效率很低在实际应用中使用的很少
list的简单模拟
templateclass Tstruct ListNode{ListNodeT* _next;ListNodeT* _prev;T _data;ListNode(const T x T()):_next(nullptr), _prev(nullptr), _data(x){}};模板类ListNode表示双向链表中的节点。该节点包括三个成员_next指向下一个节点的指针、_prev指向上一个节点的指针和 _data存储节点的数据。 定义了一个构造函数用于初始化节点的数据成员如果不提供具体的数据则使用默认值进行初始化。 实现简单的双向循环链表
templateclass Tclass list{typedef ListNodeT Node;public:list(){_head new Node;_head-_next _head;_head-_prev _head;}void push_back(const T x){Node* newnode new Node(x);Node* tail _head-_prev;tail-_next newnode;newnode-_next _head;_head-_prev newnode;}private:Node* _head;};定义了一个模板类 list实现了简单的双向循环链表。在 list 中使用了之前定义的 ListNode 作为节点通过模板类的方式实现了对不同类型元素的支持。
构造函数中创建了一个头节点并将头节点的 _next 和 _prev 都指向自身构成一个空的循环链表。
list(): 这是类的构造函数用于初始化链表。在构造函数中首先创建了一个头节点 _head然后将头节点的 _next 和 _prev 都指向自身从而形成一个空的循环链表。
void push_back(const T x): 这是一个成员函数用于在链表尾部插入新的元素。在函数中首先创建了一个新的节点 newnode 并存储数据 x然后找到当前尾节点 tail将尾节点的 _next 指向新节点新节点的 _next 指向头节点头节点的 _prev 指向新节点从而完成了新元素的插入。 封装迭代器
封装迭代器
定义了一个名为ListIterator的模板类
templateclass T
class ListIterator
{typedef ListNodeT Node;typedef ListIteratorT Self;Node* _node;
typedef ListIteratorT Self;定义了一个别名Self它代表了当前类的类型这样就可以在类内部使用Self来引用当前类的对象。 Node* _node;声明了一个指针成员变量_node它用于指向链表中的节点。
成员函数的定义
public:ListIterator(Node* node):_node(node){}
构造函数ListIterator(Node* node)接受一个指向链表节点的指针作为参数将其赋值给成员变量_node。 T operator*(){return _node-_data;}
解引用操作符operator*()返回当前迭代器指向的节点的数据成员的引用。
Self operator()
{_node _node-_next;return *this;
}前置递增操作符operator()将迭代器指向下一个节点并返回递增后的迭代器自身的引用。 Self operator(int){Self tmp(*this);_node _node-_next;return tmp;}
后置递增操作符operator(int)创建当前迭代器的副本tmp然后将迭代器指向下一个节点并返回tmp。 Self operator--(){_node _node-_prev;return *this;}Self operator--(int){Self tmp(*this);_node _node-_prev;return tmp;}
置和后置递减操作符的定义与递增操作符类似只不过是将迭代器指向前一个节点。 bool operator!(const Self it){return _node ! it._node;}
};
不等于操作符operator!比较两个迭代器的_node成员如果它们不相等则返回true否则返回false。
源代码
templateclass Tstruct ListConstIterator{typedef ListNodeT Node;typedef ListConstIteratorT Self;Node* _node;ListConstIterator(Node* node):_node(node){}// *itconst T operator*(){return _node-_data;}// it-const T* operator-(){return _node-_data;}// itSelf operator(){_node _node-_next;return *this;}Self operator(int){Self tmp(*this);_node _node-_next;return tmp;}Self operator--(){_node _node-_prev;return *this;}Self operator--(int){Self tmp(*this);_node _node-_prev;return tmp;}bool operator!(const Self it){return _node ! it._node;}bool operator(const Self it){return _node it._node;}};关于链表开始和结束的定义
typedef ListConstIteratorT iterator;iterator begin(){return iterator(_head-_next);}iterator end(){return iterator(_head);}begin()函数返回一个迭代器它指向链表中的第一个元素也就是头节点的下一个节点。 end()函数返回一个迭代器它指向链表中最后一个元素的下一个位置也就是头节点本身。 insert模拟
模拟实现insert void insert(iterator pos, const T val){Node* cur pos._node;Node* newnode new Node(val); Node* prev cur-_prev;//prev newnode curprev-_next newnode;newnode-_prev prev;newnode-_next cur;cur-_prev newnode;}erase模拟
模拟实现erase iterator earse(iterator pos){Node* cur pos._node;Node* prev cur-_prev;Node* next cur-_next;prev-_next next;next-_prev prev;delete cur;return iterator(next);}注意最后返回一个指向下一个节点的迭代器以便在调用方继续操作链表。 头插、尾插、头删、尾删模拟
在刚刚插入和删除的基础上模拟实现头插、尾插、头删、尾删
void push_back(const T x){insert(end(), x);}void push_front(const T x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}自定义类型迭代器遍历
自定义一个结构体A然后进行插入删除操作
struct A{int _a1;int _a2;A(int a10,int a20):_a1(a1),_a2(a2){}};void test_list2(){listA lt;A aa1(1, 1);A aa2 { 2,2 };lt.push_back(aa1);lt.push_back(aa1);lt.push_back(A(2, 2));lt.push_back({ 3,3 });lt.push_back({ 4,4 });listA::iterator it lt.begin();while (it ! lt.end()){cout *it ;it;}cout endl;}运行一下报错了 解决方法有两种
第一种 在循环内部通过cout (*it)._a1 : (*it)._a2 endl;语句打印当前迭代器it指向的A类型对象的_a1和_a2成员变量的值中间用冒号分隔并在末尾换行。这里使用了解引用操作符(*)来获取迭代器指向的对象然后通过点操作符(.)访问对象的成员变量_a1和_a2 (*it)._a1: (*it)是迭代器it指向的元素即链表中的一个A类型对象.是成员访问运算符_a1是这个A类型对象的成员变量_a1的值。所以(*it)._a1表示获取当前迭代器指向的对象的_a1成员变量的值。 void test_list2(){listA lt;A aa1(1, 1);A aa2 { 2,2 };lt.push_back(aa1);lt.push_back(aa1);lt.push_back(A(2, 2));lt.push_back({ 3,3 });lt.push_back({ 4,4 });listA::iterator it lt.begin();while (it ! lt.end()){cout (*it)._a1 : (*it)._a2 endl;it;}cout endl;}第二种 定义了一个operator-()重载函数箭头运算符用于访问对象的成员而对于指向对象的指针使用箭头运算符来访问成员会更方便 const T*: 这是函数的返回类型表示返回一个指向类型为T的常量数据的指针。也就是说该函数返回的是一个指向T类型常量数据的指针。 operator-(): 这是重载的箭头运算符函数名。当我们通过指向某个对象的指针使用箭头运算符时就会调用此函数来执行操作。 { return _node-_data; }: 函数体内部返回了一个指向_node-_data的指针。在这里_node是一个指向节点的指针_data是节点中存储的数据。通过返回_node-_data实际上是返回了指向节点数据的指针。
// it-
const T* operator-()
{return _node-_data;
}遍历
void test_list2(){listA lt;A aa1(1, 1);A aa2 { 2,2 };lt.push_back(aa1);lt.push_back(aa1);lt.push_back(A(2, 2));lt.push_back({ 3,3 });lt.push_back({ 4,4 });listA::iterator it lt.begin();while (it ! lt.end()){cout it-_a1 : it-_a2 endl;it;}cout endl;}it-_a1和it-_a2就是使用迭代器it来访问链表中当前元素的成员变量_a1和_a2的值。这里的it-_a1和it-_a2相当于(*it)._a1和(*it)._a2
const迭代器
cont迭代器是迭代器指向的内容不能修改
注意
const_iterator是迭代器指向的内容不能修改迭代器指向的元素不可修改模拟实现的是const T* p2const iterator是迭代器本身不能修改这个const修饰的是iteratoriterator是自定义类型前面加了const那就是不能修改这个自定义类型模拟实现的是T* const p1
const_iterator begin() const{return iterator(_head-_next);}const_iterator end() const{return iterator(_head);}void PrintList(const listint clt){listint::const_iterator it clt.begin();while (it ! clt.end()){cout *it ;it;}cout endl;}void test_list3(){listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);PrintList(lt);}使用模板封装一个迭代器
templateclass T, class Ref, class Ptrstruct ListIterator{typedef ListNodeT Node;typedef ListIteratorT, Ref, Ptr Self;Node* _node;ListIterator(Node* node):_node(node){}// *it//T operator*()Ref operator*(){return _node-_data;}// it-//T* operator-()Ptr operator-(){return _node-_data;}// itSelf operator(){_node _node-_next;return *this;}Self operator(int){Self tmp(*this);_node _node-_next;return tmp;}Self operator--(){_node _node-_prev;return *this;}Self operator--(int){Self tmp(*this);_node _node-_prev;return tmp;}bool operator!(const Self it){return _node ! it._node;}bool operator(const Self it){return _node it._node;}};templateclass T, class Ref, class Ptr模板声明用来定义模板类 ListIterator它有三个模板参数 T、Ref 和 Ptr。
在这个模板类中class T、class Ref 和 class Ptr 是模板参数它们的作用如下
T表示节点中存储的数据类型。通过模板参数 T可以让 ListIterator 类型适用于不同类型的链表例如整数、字符串、自定义对象等。Ref表示引用类型。在 C 中引用类型通常用来表示对某个对象的引用通过模板参数 Ref可以指定迭代器返回的数据的引用类型例如 T对 T 类型的对象的引用。Ptr表示指针类型。通过模板参数 Ptr可以指定迭代器返回数据的指针类型例如 T*指向 T 类型的指针。
clear和析构函数
void clear(){iterator it begin();while (it ! end()){it erase(it);}}~list(){clear();delete _head;_head nullptr;}clear() 方法 首先创建一个迭代器 it 并初始化为链表的头部即第一个节点。 然后通过循环遍历链表中的每个节点调用 erase() 方法来删除当前节点并将返回的下一个节点的迭代器赋值给 it。 循环直到 it end()即遍历完整个链表。 析构函数 ~list() 在析构函数中首先调用 clear() 方法清空链表中的所有节点。 然后释放链表的头节点 _head 所占用的内存避免内存泄漏。 最后将 _head 指针设置为 nullptr确保不再指向已释放的内存。
通过在析构函数中调用 clear() 方法可以确保在销毁链表对象时先清空链表中的所有节点然后再释放头节点的内存。这样做有助于避免内存泄漏并正确地释放链表所占用的资源。
拷贝构造传统写法
void empty_init(){_head new Node;_head-_next _head;_head-_prev _head;_size 0;}list(){empty_init();}// lt2(lt1)list(const listT lt){empty_init();for (auto e : lt){push_back(e);}}empty_init() 初始化空的链表。它创建了一个新的节点作为头结点并将头结点的指针指向自己形成一个循环链表。同时将链表的大小 _size 初始化为 0。 默认构造函数 list() 在这个构造函数中它调用了 empty_init() 方法来初始化一个空的链表。 拷贝构造函数 list(const list lt) 这个构造函数通过调用 empty_init() 方法来初始化一个空的链表即新建一个头结点。然后通过遍历传入的链表 lt将其中的元素逐个添加到新建的链表中使用 push_back(e) 方法将元素添加到新链表的末尾。 拷贝构造现代写法
void swap(listT lt)
{std::swap(_head, lt._head);std::swap(_size, lt._size);
}// lt1 lt3
listT operator(listT lt)
{swap(lt);return *this;
}swap 交换两个链表对象的内容。它通过调用 std::swap 函数交换当前链表对象的头结点 _head 和大小 _size 与传入的链表对象 lt 的对应成员的值。这样可以在不需要额外内存分配的情况下快速交换两个链表的内容。 赋值运算符重载函数 operator 这个赋值运算符重载函数接受一个传值参数 lt在函数内部会对传入的链表 lt 调用 swap 方法将传入链表的内容与当前链表对象进行交换。 通过传值参数的方式会触发拷贝构造函数从而创建传入链表 lt 的一个副本。然后调用 swap(lt) 来交换当前链表对象和副本链表对象的内容最终实现将传入链表 lt 中的内容赋值给当前链表对象。 最后返回 *this即当前链表对象的引用以支持链式赋值操作。
源码
#pragma once
#includeassert.h
namespace gwj
{templateclass Tstruct ListNode{ListNodeT* _next;ListNodeT* _prev;T _data;ListNode(const T x T()):_next(nullptr), _prev(nullptr), _data(x){}};//typedef ListIteratorT, T, T* iterator;//typedef ListIteratorT, const T, const T* const_iterator;templateclass T, class Ref, class Ptrstruct ListIterator{typedef ListNodeT Node;typedef ListIteratorT, Ref, Ptr Self;Node* _node;ListIterator(Node* node):_node(node){}// *it//T operator*()Ref operator*(){return _node-_data;}// it-//T* operator-()Ptr operator-(){return _node-_data;}// itSelf operator(){_node _node-_next;return *this;}Self operator(int){Self tmp(*this);_node _node-_next;return tmp;}Self operator--(){_node _node-_prev;return *this;}Self operator--(int){Self tmp(*this);_node _node-_prev;return tmp;}bool operator!(const Self it){return _node ! it._node;}bool operator(const Self it){return _node it._node;}};//templateclass T//struct ListConstIterator//{// typedef ListNodeT Node;// typedef ListConstIteratorT Self;// Node* _node;// ListConstIterator(Node* node)// :_node(node)// {}// // *it// const T operator*()// {// return _node-_data;// }// // it-// const T* operator-()// {// return _node-_data;// }// // it// Self operator()// {// _node _node-_next;// return *this;// }// Self operator(int)// {// Self tmp(*this);// _node _node-_next;// return tmp;// }// Self operator--()// {// _node _node-_prev;// return *this;// }// Self operator--(int)// {// Self tmp(*this);// _node _node-_prev;// return tmp;// }// bool operator!(const Self it)// {// return _node ! it._node;// }// bool operator(const Self it)// {// return _node it._node;// }//};templateclass Tclass list{typedef ListNodeT Node;public://typedef ListIteratorT iterator;//typedef ListConstIteratorT const_iterator;typedef ListIteratorT, T, T* iterator;typedef ListIteratorT, const T, const T* const_iterator;//iterator begin()//{// //return iterator(_head-_next);// iterator it(_head-_next);// return it;//}iterator begin(){return _head-_next;}iterator end(){return _head;}// const迭代器需要是迭代器不能修改还是迭代器指向的内容// 迭代器指向的内容不能修改const iterator不是我们需要const迭代器// T* const p1// const T* p2const_iterator begin() const{return _head-_next;}const_iterator end() const{return _head;}void empty_init(){_head new Node;_head-_next _head;_head-_prev _head;_size 0;}list(){empty_init();}// lt2(lt1)list(const listT lt){empty_init();for (auto e : lt){push_back(e);}}void swap(listT lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}// lt1 lt3listT operator(listT lt){swap(lt);return *this;}// 需要析构一般就需要自己写深拷贝// 不需要析构一般就不需要自己写深拷贝默认浅拷贝就可以void clear(){iterator it begin();while (it ! end()){it erase(it);}}~list(){clear();delete _head;_head nullptr;}//void push_back(const T x)//{// Node* newnode new Node(x);// Node* tail _head-_prev;// tail-_next newnode;// newnode-_next _head;// _head-_prev newnode;//}void push_back(const T x){insert(end(), x);}void push_front(const T x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}void insert(iterator pos, const T val){Node* cur pos._node;Node* newnode new Node(val); Node* prev cur-_prev;//prev newnode curprev-_next newnode;newnode-_prev prev;newnode-_next cur;cur-_prev newnode;_size;}iterator erase(iterator pos){Node* cur pos._node;Node* prev cur-_prev;Node* next cur-_next;prev-_next next;next-_prev prev;delete cur;_size--;return iterator(next);}bool empty(){return _size 0;}private:Node* _head;size_t _size;};void test_list1(){listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);listint::iterator it lt.begin();while (it ! lt.end()){cout *it ;it;}cout endl;lt.push_front(10);lt.push_front(20);lt.push_front(30);for (auto e : lt){cout e ;}cout endl;lt.pop_back();lt.pop_front();for (auto e : lt){cout e ;}cout endl;}struct A{int _a1;int _a2;A(int a10,int a20):_a1(a1),_a2(a2){}};void test_list2(){listA lt;A aa1(1, 1);A aa2 { 2,2 };lt.push_back(aa1);lt.push_back(aa1);lt.push_back(A(2, 2));lt.push_back({ 3,3 });lt.push_back({ 4,4 });listA::iterator it lt.begin();while (it ! lt.end()){//cout (*it)._a1 : (*it)._a2 endl;cout it-_a1 : it-_a2 endl;it;}cout endl;}void PrintList(const listint clt){listint::const_iterator it clt.begin();while (it ! clt.end()){cout *it ;it;}cout endl;}void test_list3(){listint lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);PrintList(lt);listint lt1(lt);PrintList(lt1);}
} 文章转载自: http://www.morning.mlzyx.cn.gov.cn.mlzyx.cn http://www.morning.wmmtl.cn.gov.cn.wmmtl.cn http://www.morning.nnhrp.cn.gov.cn.nnhrp.cn http://www.morning.rfpb.cn.gov.cn.rfpb.cn http://www.morning.snnwx.cn.gov.cn.snnwx.cn http://www.morning.kjsft.cn.gov.cn.kjsft.cn http://www.morning.haibuli.com.gov.cn.haibuli.com http://www.morning.xkyst.cn.gov.cn.xkyst.cn http://www.morning.fnywn.cn.gov.cn.fnywn.cn http://www.morning.kqrql.cn.gov.cn.kqrql.cn http://www.morning.cpmwg.cn.gov.cn.cpmwg.cn http://www.morning.mmjyk.cn.gov.cn.mmjyk.cn http://www.morning.zztmk.cn.gov.cn.zztmk.cn http://www.morning.hmjasw.com.gov.cn.hmjasw.com http://www.morning.cwyfs.cn.gov.cn.cwyfs.cn http://www.morning.ktfbl.cn.gov.cn.ktfbl.cn http://www.morning.ccsdx.cn.gov.cn.ccsdx.cn http://www.morning.zylzk.cn.gov.cn.zylzk.cn http://www.morning.fwmln.cn.gov.cn.fwmln.cn http://www.morning.zqnmp.cn.gov.cn.zqnmp.cn http://www.morning.fswml.cn.gov.cn.fswml.cn http://www.morning.bfhrj.cn.gov.cn.bfhrj.cn http://www.morning.qpzjh.cn.gov.cn.qpzjh.cn http://www.morning.qgdsd.cn.gov.cn.qgdsd.cn http://www.morning.cwkcq.cn.gov.cn.cwkcq.cn http://www.morning.fbxlj.cn.gov.cn.fbxlj.cn http://www.morning.rxfbf.cn.gov.cn.rxfbf.cn http://www.morning.pndw.cn.gov.cn.pndw.cn http://www.morning.gtylt.cn.gov.cn.gtylt.cn http://www.morning.zrjzc.cn.gov.cn.zrjzc.cn http://www.morning.gqwbl.cn.gov.cn.gqwbl.cn http://www.morning.bhdyr.cn.gov.cn.bhdyr.cn http://www.morning.knrgb.cn.gov.cn.knrgb.cn http://www.morning.ydxwj.cn.gov.cn.ydxwj.cn http://www.morning.clxpp.cn.gov.cn.clxpp.cn http://www.morning.brlcj.cn.gov.cn.brlcj.cn http://www.morning.ktnt.cn.gov.cn.ktnt.cn http://www.morning.qnzk.cn.gov.cn.qnzk.cn http://www.morning.zntf.cn.gov.cn.zntf.cn http://www.morning.xmtzk.cn.gov.cn.xmtzk.cn http://www.morning.wnqbf.cn.gov.cn.wnqbf.cn http://www.morning.ysybx.cn.gov.cn.ysybx.cn http://www.morning.mjglk.cn.gov.cn.mjglk.cn http://www.morning.nytgk.cn.gov.cn.nytgk.cn http://www.morning.twhgn.cn.gov.cn.twhgn.cn http://www.morning.tqwcm.cn.gov.cn.tqwcm.cn http://www.morning.zntf.cn.gov.cn.zntf.cn http://www.morning.nkiqixr.cn.gov.cn.nkiqixr.cn http://www.morning.zfcfk.cn.gov.cn.zfcfk.cn http://www.morning.zrfwz.cn.gov.cn.zrfwz.cn http://www.morning.lfmwt.cn.gov.cn.lfmwt.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.dxpzt.cn.gov.cn.dxpzt.cn http://www.morning.kpygy.cn.gov.cn.kpygy.cn http://www.morning.kqwsy.cn.gov.cn.kqwsy.cn http://www.morning.tqpds.cn.gov.cn.tqpds.cn http://www.morning.jrdbq.cn.gov.cn.jrdbq.cn http://www.morning.xpzkr.cn.gov.cn.xpzkr.cn http://www.morning.ntzbr.cn.gov.cn.ntzbr.cn http://www.morning.qjsxf.cn.gov.cn.qjsxf.cn http://www.morning.pxsn.cn.gov.cn.pxsn.cn http://www.morning.ntyanze.com.gov.cn.ntyanze.com http://www.morning.ynjhk.cn.gov.cn.ynjhk.cn http://www.morning.rzysq.cn.gov.cn.rzysq.cn http://www.morning.rnhh.cn.gov.cn.rnhh.cn http://www.morning.cfynn.cn.gov.cn.cfynn.cn http://www.morning.wwgpy.cn.gov.cn.wwgpy.cn http://www.morning.qfnrx.cn.gov.cn.qfnrx.cn http://www.morning.rwwdp.cn.gov.cn.rwwdp.cn http://www.morning.fjzlh.cn.gov.cn.fjzlh.cn http://www.morning.dqzcf.cn.gov.cn.dqzcf.cn http://www.morning.sblgt.cn.gov.cn.sblgt.cn http://www.morning.junyaod.com.gov.cn.junyaod.com http://www.morning.qpmwb.cn.gov.cn.qpmwb.cn http://www.morning.pzbjy.cn.gov.cn.pzbjy.cn http://www.morning.wknjy.cn.gov.cn.wknjy.cn http://www.morning.jbxd.cn.gov.cn.jbxd.cn http://www.morning.yqfdl.cn.gov.cn.yqfdl.cn http://www.morning.lgnz.cn.gov.cn.lgnz.cn http://www.morning.sxfnf.cn.gov.cn.sxfnf.cn