从零开始学算法:十种排序算法介绍_by_Matrix67.pdf-玻璃钢制品

从零开始学算法:十种排序算法介绍_by_Matrix67.pdf 13页

  • 内容提供方:好文精选
  • 大小264.8 KB
  • 字数约2.05万字
  • 发布时间2018-05-24发布于四川
  • 浏览人气1
  • 下载次数仅上传者可见
  • 收藏次数0
  • 需要金币*** 金币 (10金币=人民币1元)

从零开始学算法:十种排序算法介绍_by_Matrix67.pdf

  • 关闭预览
从零开始学算法:十种排序算法介绍_by_Matrix67.pdf

想预览更多内容,点击免费在线预览全文

免费在线预览全文
从零开始学算法:十种排序算法介绍(上) Program Impossible | 2007-03-31 23:23| 17 Comments | 本文内容遵从CC 版权协议 转载请注明出自 今天我正式开始按照我的目录写我的OI 心得了。我要把我所有学到的OI 知识传给以后千千万万的OIer。 以前写过的一些东西不重复写了,但我最后将会重新整理,使之成为一个完整的教程。 按照我的目录,讲任何东西之前我都会先介绍时间复杂度的相关知识,以后动不动就会扯到这个东西。这个 已经写过了,你可以在这里看到那篇又臭又长的文章。在讲排序算法的过程中,我们将始终围绕时间复杂度的内 容进行说明。 我把这篇文章称之为“从零开始学算法”,因为排序算法是最基础的算法,介绍算法时从各种排序算法入手是 最好不过的了。 给 出n个数,怎样将它们从小到大排序?下面一口气讲三种常用的算法,它们是最简单的、最显然的、最 容易想到的。选择排序(SelectionSort)是说,每次从数列中找出一个最小的数放到最前面来,再从剩下的n-1个数 中选择一个最小的,不断做下去。插入排序(Insertion Sort)是,每次从数列中取一个还没有取出过的数,并按照 大小关系插入到已经取出的数中使得已经取出的数仍然有序。冒泡排序(BubbleSort)分为若干趟进行,每一趟排 序从前往后比较每两个相邻的元素的大小(因此一趟排序要比较n-1对位置相邻的数)并在每次发现前面的那个 数比紧接它 后的数大时交换位置;进行足够多趟直到某一趟跑完后发现这一趟没有进行任何交换操作(最坏情 况下要跑n-1趟,这种情况在最小的数位于给定数列的最后面时 发生)。事实上,在第一趟冒泡结束后,最后面 那个数肯定是最大的了,于是第二次只需要对前面n-1个数排序,这又将把这n-1个数中最小的数放到整个数列 的 倒数第二个位置。这样下去,冒泡排序第i趟结束后后面i个数都已经到位了,第i+1趟实际上只考虑前n-i 个数 (需要的比较次数比前面所说的n-1要 小)。这相当于用数学归纳法证明了冒泡排序的正确性:实质与选择排序 相同。上面的三个算法描述可能有点模糊了,没明白的话网上找资料,代码和动画演示遍地 都是。 这三种算法非常容易理解,因为我们生活当中经常在用。比如,班上的MM 搞选美活动,有人叫我给所有 MM 排个名。我们通常会用选择排序,即先找出自 己认为最漂亮的,然后找第二漂亮的,然后找第三漂亮的, 不断找剩下的人中最满意的。打扑克牌时我们希望抓完牌后手上的牌是有序的,三个8挨在一起,后面紧 接着 两个9。这时,我们会使用插入排序,每次拿到一张牌后把它插入到手上的牌中适当的位置。什么时候我们会用 冒泡排序呢?比如,体育课上从矮到高排队时, 站队完毕后总会有人出来,比较挨着的两个人的身高,指挥到: 你们俩调换一下,你们俩换一下。 这是很有启发性的。这告诉我们,什么时候用什么排序最好。当人们渴望先知道排在前面的是谁时,我们用 选择排序;当我们不断拿到新的数并想保持已有的数始终有序时,我们用插入排序;当给出的数列已经比较有序, 只需要小幅度的调整一下时,我们用冒泡排序。 我们来算一下最坏情况下三种算法各需要多少次比较和赋值操作。 选择排序在第i 次选择时赋值和比较都需要n-i 次(在n-i+1个数中选一个出来作为当前最小值,其余n-i 个 数与当前最小值比较并不断更新当前最小值),然后需要一次赋值操作。总共需要n(n-1)/2 次比较与n(n-1)/2+n 次赋值。 插 入排序在第i次寻找插入位置时需要最多i-1次比较(从后往前找到第一个比待插入的数小的数,最坏情 况发生在这个数是所有已经取出的数中最小的一个的时 候),在已有数列中给新的数腾出位置需要i-1 次赋值操 作来实现,还需要两次赋值借助临时变量把新取出的数搬进搬出。也就是说,最坏情况下比较需要 n(n-1)/2次, 赋值需要n(n-1)/2+2n 次。我这么写有点误导人,大家不要以为程序的实现用了两个数组哦,其实一个数组就够 了,看看上面的演 示就知道了。我只说算法,一般不写如何实现。学算法的都是强人,知道算法了都能写出一 个漂亮的代码来。 冒泡排序第i趟排序需要比较n-i 次,n-1 趟排序总共n(n-1)/2 次。给出的序列逆序排列是最坏的情况,这时 每一次比较都要进行交换操作。一次交换操作需要3 次赋值实现,因此冒泡排序最坏情况下需要赋值3n(n-1)/2 次。 按 照渐进复杂度理论,忽略所有的常数,三种排序的最坏情况下复杂度都是一样的:O(n^2)。但实际应用 中三种排序的效率并不相同。实践证明(政治考试时每 道大题都要用这四个字),插入排序是最快的(虽然最坏 情况下与选择排序相当甚至更糟),因为每一次插入时寻找插入的位置多数情况只需要与已有数的一部分进 行比 较(你可能知道这还能二分)。你或许会说冒泡排序也可以在半路上完成,还没有跑到第n-1 趟就已经有序。但 冒泡排序的交换操作更费时,而插入排序中找 到了插入的位置后移动操作只需要用赋值就能完成(你可能知道 这还能用move)。本文后面将介绍的一种算法就利用插入排序的这些优势。 我 们证明了,三种排序方法在最坏情况下时间复杂度都是O(n^2)。但大家想过吗,这只是最坏情况下的。 在很多时候,复杂度没有这么大,因为插入和冒泡在数 列已经比较有序的情况下需要的操作远远低于n^2次(最 好情况下甚至是线性的)。抛开选择排序不说(因为它的复杂度是“死”的,对于选择排序没有什么“好 ”的情况), 我们下面探讨插入排序和冒泡排序在特定数据和平均情况下的复杂度。 你会发现,如果把插入排序中的移动赋值操作看作是把当前取 出的元素与前面取出的且比它大的数逐一交 换,那插入排序和冒泡排序对数据的变动其实都是相邻元素的交换操作。下面我们说明,若只能对数列中相邻的 数进行交 换操作,如何计算使得n个数变得有序最少需要的交换次数。 我们定义逆序对的概念。假设我们要把数列从小到大排序,一个逆序对是指的在原数 列中,左边的某个数 比右边的大。也就是说,如果找到了某个i和j使得ij 且AiAj,我们就说我们找到了一个逆序对。比如说,数 列 3,1,4,2中有三个逆序对,而一个已经有序的数列逆序对个数为0。我们发现,交换两个相邻的数最多消除一 个逆序对,且冒泡排序(或插入排序)中的一次 交换恰好能消除一个逆序对。那么显然,原数列中有多少个逆 序对冒泡排序(或插入排序)就需要多少次交换操作,这个操作次数不可能再少。 若 给出的n 个数中有m个逆序对,插入排序的时间复杂度可以说是O(m+n)的,而冒泡排序不能这么说, 因为冒泡排序有很多“无用”的比较(比较后没有交 换),这些无用的比较超过了O(m+n)个。从这个意义上说, 插入排序仍然更为优秀,因为冒泡排序的复杂度要受到它跑的趟数的制约。一个典型的例子是这样 的数列:8,2, 3,4,5,6,7,1。在这样的输入数据下插入排序的优势非常明显,冒泡排序只能哭着喊上天不公。 然而,我们并不想计算排序算法对于某个特定数据的效率。我们真正关心的是,对于所有可能出现的数据, 算法的平均复杂度是多少。不用激动了,平均复杂度并不会低于平方。下面证明,两种算法的平均复杂度仍然是 O(n^2)的。 我们仅仅证明算法需要的交换次数平均为O(n^2)就足够了。前面已经说过,它们需要的交换次数与逆序对 的个数相同。我们将证明,n个数的数列中逆序对个数平均O(n^2)个。 计 算的方法是十分巧妙的。如果把给出的数列反过来(从后往前倒过来写),你会发现原来的逆序对现在变 成顺序的了,而原来所有的非逆序对现在都成逆序了。正反 两个数列的逆序对个数加起来正好就是数列所有数 对的个数,它等于n(n-1)/2。于是,平均每个数列有n(n-1)/4个逆序对。忽略常数,逆序对平均 个数O(n^2)。 上面的讨论启示我们,要想搞出一个复杂度低于平方级别的排序算法,我们需要想办法能把离得老远的两个 数进行操作。 人 们想啊想啊想啊,怎么都想不出怎样才能搞出复杂度低于平方的算法。后来,英雄出现了,DonaldShell 发明了一种新的算法,我们将证明它的复杂度最坏情况下也没有O(n^2) (似乎有人不喜欢研究正确性和复杂度 的证明,我会用实例告诉大家,这些证明是非常有意思的)。他把这种算法叫做Shell 增量排序算法(大家常说的 希尔排 序)。 Shell 排序算法依赖一种称之为“排序增量”的数列,不同的增量将导致不同的效率。假如我们对20个数进行 排序,使用的增量为 1,3,7。那么,我们首先对这20个数进行“7-排序”(7-sortedness)。所谓7-排序,就是按照位 置除以7的余数分组进行排序。具体地 说,我们将把在1、8、15三个位置上的数进行排序,将第2、9、16个 数进行排序,依此类推。这样,对于任意一个数字k,单看A(k),A(k+7),A(k+14),...这些数是有序的。7-排序后, 我们接着又进行一趟3-排序(别忘了我们使用的排序增量为1,3,7)。最后进行1-排序(即普通的排序)后整个 Shell 算法完成。看看我们的例子: 3 7 9 0 5 1 6 8 4 2 0 6 1 5 7 3 4 9 8 2 -- 原数列 3 3 2 0 5 1 5 7 4 4 0 6 1 6 8 7 9 9 8 2 -- 7-排序后 0 0 1 1 2 2 3 3 4 4 5 6 5 6 8 7 7 9 8 9 -- 3-排序后 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 -- 1-排序后(完成) 在每一趟、每一组的排序中我们总是使用插入排序。仔细观察上面的例子你会发现是什么导致了Shell 排序 的高效。对,每一趟排序将使得数列部分有序,从而使得以后的插入排序很快找到插入位置。我们下面将紧紧围 绕这一点来证明Shell 排序算法的时间复杂度上界。 只 要排序增量的第一个数是1,Shell 排序算法就是正确的。但是不同的增量将导致不同的时间复杂度。我 们上面例子中的增量(1, 3,7,15,31,..., 2^k-1)是使用最广泛的增量序列之一,可以证明使用这个增量的时间复杂 度为O(n√n)。这个证明很简单,大家可以参看一些其它的资料,我们今天不证 明它。今天我们证明,使用增量 1,2,3,4,6,8,9,12,16,...,2^p*3^q,时间复杂度为O(n*(logn)^2)。 很显然,任何一个大于1的正整数都可以表示为2x+3y,其中x和y是非负整数。于是,如果一个数列已经 是2-排序的且是 3-排序的,那么对于此时数列中的每一个数A(i),它的左边比它大的只有可能是A(i-1)。A2绝 对不可能比A12大,因为10可以表示为两个2 和两 个3的和,则A2A4A6A9A12。那么,在这个增量中 的1-排序时每个数找插入位置只需要比较一次。一共有n个数, 所以1-排序是O(n)的。事实上,这个增量中的 2-排序也是O(n),因为在2-排序之前,这个数列已经是4-排序且6-排序过的,只看数列的奇数项或 者偶数项(即 单看每一组)的话就又成了刚才的样子。这个增量序列巧妙就巧妙在,如果我们要进行 h-排序,那么它一定是 2h-排序过且3h-排序过,于是处 理每个数A(i)的插入时就只需要和A(i-h)进行比较。这个结论对于最开始几次(h 值较大时)的h-排序同样成立,当2h、3h大于n时,按照定义, 我们也可以认为数列是2h-排序和3h-排序的, 这并不影响上述结论的正确性(你也可以认为h太大以致于排序时每一组里的数字不超过3个,属于常数级)。现 在,这个增量中的每一趟排序都是O(n)的,我们只需要数一下一共跑了多少趟。也就是说,我们现在只需要知 道小于n的数中有多少个数具有2^p*3^q 的形式。要想2^p*3^q不超过n,p的取值最多O(logn)个,q的取值最 多也是O(logn)个,两两组合的话共有O(logn*logn)种情况。于是,这样的增量排序需要跑O((logn)^2)趟,每一 趟的复杂度O(n),总的复杂度为O(n*(logn)^2)。早就说过了,证明时间复杂度其实很有意思。 我们自然会想,有没有能使复杂度降到O(nlogn)甚至更低的增量序列。很遗憾,现在没有任何迹象表明存在 O(nlogn)的增量排序。但事实上,很多时候Shell 排序的实际效率超过了O(nlogn)的排序算法。 后面我们将介绍三种O(nlogn)的排序算法和三种线性时间的排序算法。最后我们将以外部排序和排序网络结 束这一章节。 很 多人问到我关于转贴的问题。我欢迎除商业目的外任何形式的转贴(论坛、Blog、Wiki、个人网站、PodCast, 甚至做成ppt、pdf),但一定 要注明出处,最好保留原始链接。我的网站需要点反向链接才能在网络中生存下去, 大家也都可以关注并且推广这个Blog。我一直支持cc版权协议,因此发现 了文章中的问题或者想要补充什么东 西尽管提出来,好让更多的人学习到好东西。我昨天看Blog上原来写的一些东西,居然连着发现了几个错误式 子和错别字, 好奇大家居然没有提出来。发现了问题真的要告诉我,即使格式有点问题也要说一下,决不能让 它那么错着。另外有什么建议或想法也请说一下,我希望听到不同的 声音不同的见解,好让我决定这类文章以 后的发展方向。 本文被华丽的分割线分为了四段。对于O(nlogn)的排序算法,我们详细介绍归并排序并证明归并排序的时间 复杂度,然后简单介绍堆排序,之后给 出快速排序的基本思想和复杂度证明。最后我们将证明,O(nlogn)在理 论上已经达到了最优。学过OI 的人一般都学过这些很基础的东西,大多数 OIer 们不必看了。为了保持系列文 章的完整性,我还是花时间写了一下。 首先考虑一个简单的问题:如何在线性的时间内将两个有序队列合并为一个有序队列(并输出)? A队列:13579 B队列:12789 看上面的例子,AB两个序列都是已经有序的了。在给出数据已经有序的情况下,我们会发现很多神奇的事, 比如,我们将要输出的第一个数一定来自于这两个序列各自最前面的那个数。两个数都是1,那么我们随便取出 一个(比如A队列的那个1)并输出: A队列:1 3 5 7 9 B队列:1 2 7 8 9 输出:1 注意,我们取出了一个数,在原数列中删除这个数。删除操作是通过移动队首指针实现的,否则复杂度就高 了。 现在,A队列打头的数变成3了,B 队列的队首仍然是1。此时,我们再比较3和1哪个大并输出小的那个 数: A队列:1 3 5 7 9 B队列:1 2 7 8 9 输出:1 1 接下来的几步如下: A队列:1 3 5 7 9 A队列:1 3 5 7 9 A队列:1 3 5 7 9 A队列:1 3 5 7 9 B队列:12789 == B队列:12789 == B队列:12789 == B队列:12789 …… 输出:1 1 2 输出:1 1 2 3 输出:1 1 2 3 5 输出:1 1 2 3 5 7 我希望你明白了这是怎么做的。这个做法显然是正确的,复杂度显然是线性。 归 并排序(MergeSort)将会用到上面所说的合并操作。给出一个数列,归并排序利用合并操作在O(nlogn)的 时间内将数列从小到大排序。归并排序用的是分治 (Divide andConquer)的思想。首先我们把给出的数列平分为 左右两段,然后对两段数列分别进行排序,最后用刚才的合并算法把这两段(已经排过序的)数列合并为一 个 数列。有人会问“对左右两段数列分别排序时用的什么排序”么?答案是:用归并排序。也就是说,我们递归地把 每一段数列又分成两段进行上述操作。你不需要 关心实际上是怎么操作的,我们的程序代码将递归调用该过程 直到数列不能再分(只有一个数)为止。 初看这个算法时有人会误以为时间复杂度相当高。我们下面给出的一个图将用非递归的眼光来看归并排序的 实际操作过程,供大家参考。我们可以借助这个图证明,归并排序算法的时间复杂度为O(nlogn)。 [3] [1] [4] [1] [5] [9] [2] [7] \ / \ / \ / \ / [1 3] [1 4] [5 9] [2 7] \ / \ / [1 1 3 4] [2 5 7 9] \ / [1 1 2 3 4 5 7 9] 上 图中的每一个“\ /”表示的是上文所述的线性时间合并操作。上图用了4行来图解归并排序。如果有n个 数,表示成上图显然需要 O(logn)行。每一行的合并操作复杂度总和都 是O(n),那么logn 行的总复杂度为 O(nlogn)。这相当于用递归树的方法对归并排序的复杂度进行了分析。假设,归并排序的复杂度为 T(n),T(n)由 两个T(n/2)和一个关于n 的线性时间组成,那么T(n)=2*T(n/2)+O(n)。不断展开这个式子我们可以同样可以得到 T(n)=O(nlogn)的结论,你可以自己试试。如果你能在线性的时间里把分别计算出的两组不同数据的结果合并在一 起,根据 T(n)=2*T(n/2)+O(n)=O(nlogn),那么我们就可以构造O(nlogn)的分治算法。这个结论后面经常用。我们 将在计算几何部分举 一大堆类似的例子。 如果你第一次见到这么诡异的算法,你可能会对这个感 兴趣。分治是递归的一种应用。这是我们第一次接 触递归运算。下面说的快速排序也是用的递归的思想。递归程序的复杂度分析通常和上面一样,主定理 (Master Theory)可以简化这个分析过程。主定理和本文内容离得太远,我们以后也不会用它,因此我们不介绍它,大家 可以自己去查。有个名词在这里的话找学习资 料将变得非常容易,我最怕的就是一个东西不知道叫什么名字, 半天找不到资料。 归并排序有一个有趣的副产品。利用归并排序能够在 O(nlogn)的时间里计算出给定序列里逆序对的个数。 你可以用任何一种平衡二叉树来完成这个操作,但用归并排序统计逆序对更方便。我们讨论逆序对一般 是说的 一个排列中的逆序对,因此这里我们假设所有数不相同。假如我们想要数1,6,3,2,5,4中有多少个逆序对,我们 首先把这个数列分为左右两段。那么一个逆序对只可能有三种情况:两个数都在左边,两个数都在右边,一个在 左一个在右。在左右两段 分别处理完后,线性合并的过程中我们可以顺便算出所有第三种情况的逆序对有多少 个。换句话说,我们能在线性的时间里统计出A队列的某个数比B队列的某个数 大有多少种情况。 A队列:1 3 6 A队列:1 3 6 A队列:1 3 6 A队列:1 3 6 A队列:1 3 6 B队列:245 == B队列:245 == B队列:245 == B队列:245 == B队列:245 …… 输出: 输出:1 输出:1 2 输出:1 2 3 输出:1 2 3 4 每 一次从B 队列取出一个数时,我们就知道了在A 队列中有多少个数比B 队列的这个数大,它等于A队 列现在还剩的数的个数。比如,当我们从B队列中取出2时,我 们同时知道了A队列的3和6两个数比2大。 在合并操作中我们不断更新A队列中还剩几个数,在每次从B队列中取出一个数时把当前A队列剩的数目加进 最终答案 里。这样我们算出了所有“大的数在前一半,小的数在后一半”的情况,其余情况下的逆序对在这之前 已经被递归地算过了。 ============================华丽的分割线============================ 堆排序(HeapSort)利用了堆(Heap)这种数据结构(什么是堆?)。 堆的插入操作是平均常数的,而删除一个 根节点需要花费O(log n)的时间。因此,完成堆排序需要线性时间建立堆(把所有元素依次插入一个堆),然后 用总共O(nlogn)的时间不断取出最小的那个数。只要堆会搞,堆 排序就会搞。堆在那篇日志里有详细的说明, 因此这里不重复说了。 ============================华丽的分割线=====================
  • 下载文档
  • 收藏
  • 0

文档评论(0)

  • 内容提供方:好文精选
  • 审核时间:2018-05-24
  • 审核编号:8031142034001104
  • 认证类型:实名认证
  • 能力类型:内容提供者
  • 领域认证:
  • 版权证书:
  • 区块链号:

相关文档

相关内容推荐

池州景观不锈钢雕塑厂家上海不锈钢雕塑艺术品保山不锈钢雕塑定做郑州环保不锈钢雕塑市场淮南不锈钢雕塑定做哪家专业太原不锈钢地标雕塑河南水景不锈钢卡通雕塑报价东营音乐不锈钢雕塑制作舟山不锈钢雕塑厂家电话多少丽江市不锈钢雕塑设计价格绵阳不锈钢景观雕塑承接工程价格镇江大型不锈钢鹿雕塑生产厂家不锈钢异形雕塑咨询酒泉大型不锈钢雕塑设计水景不锈钢卡通雕塑定制厂家新乡不锈钢景观室外镂空雕塑公司南昌不锈钢雕塑市场哈尔滨特色不锈钢雕塑定做价格湖南不锈钢园林雕塑多少钱不锈钢雕塑项目惠济不锈钢雕塑陕西不锈钢景观雕塑小区绿地摆件广西不锈钢雕塑定制报价安徽景观不锈钢雕塑定制周口肖像不锈钢景观雕塑厂家鹤壁镂空校园不锈钢景观雕塑山西抽象不锈钢造型雕塑不锈钢雕塑工程多少钱德州广场不锈钢雕塑济南不锈钢园林雕塑出售北京不锈钢雕塑大全深圳园林不锈钢雕塑定做信阳校园不锈钢铜雕塑厂家惠济不锈钢雕塑费用禹王台不锈钢雕塑福清不锈钢雕塑厂家湖南室内室外不锈钢雕塑小品公司安徽户外装饰不锈钢镂空雕塑加工湖南不锈钢抽象雕塑造型烟台不锈钢雕塑定制厂家安宁加工不锈钢雕塑制作咨询潍坊大型不锈钢鹿雕塑生产厂家广场不锈钢创意雕塑儿童游乐不锈钢雕塑设备古典风不锈钢雕塑生产厂家户外不锈钢雕塑制作步骤黑龙江水景不锈钢雕塑制作洛阳锻铜不锈钢园林雕塑厂家不锈钢孔子雕塑哪家强新密大型园林不锈钢雕塑定做厂家东莞不锈钢发光月亮雕塑太原不锈钢园林雕塑专业定制张家口镜面不锈钢雕塑制作广东不锈钢雕塑材质湖州大型不锈钢雕塑批发晋城人物不锈钢卡通雕塑保山不锈钢镜面雕塑长沙不锈钢公园雕塑批发城市几何不锈钢雕塑厂商销售许昌学校不锈钢雕塑小品厂家长沙不锈钢人物雕塑原理焦作室内不锈钢雕塑小品价格永康城市不锈钢雕塑定做不锈钢发光雕塑玻璃折边长春哪里有户外不锈钢雕塑天水大型不锈钢雕塑订做三沙小型镜面不锈钢雕塑加工南阳人物不锈钢雕塑定制青海公园不锈钢雕塑哪家好江西不锈钢小品雕塑厂家武汉不锈钢几何雕塑售价湖北彩色不锈钢雕塑厂开远不锈钢月亮雕塑东莞校园不锈钢雕塑定制焦作公园水景镂空不锈钢雕塑厂家湖南不锈钢蝴蝶雕塑哪家好绍兴不锈钢假山雕塑石首不锈钢异形雕塑安顺不锈钢造型雕塑厂哪家好济南定制不锈钢雕塑山西景观园林不锈钢卡通雕塑厂家园林不锈钢雕塑价格多少烟台不锈钢镂空球雕塑公司远景不锈钢雕塑电话多少不锈钢雕塑喷雾树清远商场不锈钢雕塑湖北不锈钢雕塑厂家不锈钢党建雕塑生产厂家安庆不锈钢雕塑市场山西不锈钢小品雕塑公司晋州不锈钢月亮雕塑造景吉林不锈钢兰花雕塑广场艺术美陈酒泉园林景观不锈钢雕塑哪家好沧州广东不锈钢人物雕塑景观标识动物不锈钢雕塑制作芜湖景区不锈钢雕塑联系方式山东省枣庄雪花白不锈钢雕塑云南不锈钢雕塑定做长春不锈钢假山雕塑濮阳公园水景不锈钢树叶雕塑厂家宿州户外不锈钢雕塑厂家宝鸡不锈钢雕塑特点周口抽象不锈钢雕塑生产洛阳景观标识不锈钢镂空雕塑抚顺不锈钢雕塑联系方式沈阳景观不锈钢雕塑安装不锈钢金属雕塑费用情况山西不锈钢雕塑哪里找宜昌学校不锈钢雕塑公司漯河不锈钢公园雕塑河南广场镂空不锈钢雕塑生产不锈钢体育雕塑成都不锈钢雕塑订做价格平湖不锈钢雕塑厂家电话多少商丘不锈钢假山雕塑广东酒店不锈钢镂空雕塑工厂沈阳定做人物不锈钢雕塑河南广场喷泉不锈钢雕塑报价内蒙不锈钢校园雕塑生产厂家烟台不锈钢蝴蝶雕塑价钱标牌不锈钢雕塑小品订做价格河南不锈钢公园景观雕塑设计湖南党建不锈钢雕塑生产厂家南京户内不锈钢雕塑安阳镜面不锈钢树叶雕塑邵阳城市不锈钢雕塑生产厂家太原不锈钢拉丝雕塑上海校园文化不锈钢雕塑厂南京多彩不锈钢雕塑信阳室内不锈钢室外抽象雕塑哈尔滨佛像不锈钢雕塑多少钱许昌锻铜不锈钢雕塑拳头不锈钢雕塑工艺图片珠海不锈钢镂空鱼雕塑东营不锈钢蚂蚁雕塑制作昆明户内不锈钢雕塑定制自贡不锈钢拉丝雕塑不锈钢景观凤尾雕塑红军不锈钢雕塑厂商销售室内户外不锈钢雕塑定制重庆不锈钢雕塑加工厂宣城哪里做不锈钢雕塑平顶山镂空不锈钢雕塑厂家韶关不锈钢标识牌雕塑濮阳专业不锈钢大型城市雕塑厂家青岛大型校园不锈钢雕塑公司广州佛像不锈钢雕塑价位湖南企业不锈钢雕塑供应商鹤壁价值观室内不锈钢雕塑小品定制不锈钢动物雕塑制作江苏不锈钢字雕塑哪里有通辽人物不锈钢雕塑安装湖州不锈钢雕塑供应商太原不锈钢小品雕塑价格山东不锈钢佛像雕塑订做六安欧式不锈钢雕塑哪家便宜福建不锈钢雕塑哪家好定制城市不锈钢雕塑宝鸡不锈钢雕塑特点七台河酒店不锈钢雕塑定制鹤壁景观园林户外不锈钢雕塑厂家温州不锈钢雕塑品牌哪家好湖州环保不锈钢雕塑水景景观不锈钢雕塑绍兴不锈钢卡通雕塑公司河源不锈钢雕塑哪家好天津直销不锈钢雕塑厂家吉安大型不锈钢雕塑销售电话西安企业不锈钢雕塑一般多少钱内蒙党建不锈钢雕塑专业定制内蒙不锈钢大型雕塑采购运城不锈钢镂空月亮雕塑天津定做大型不锈钢雕塑常州不锈钢雕塑设计报价沧州广场不锈钢雕塑哪里好贵州不锈钢小品假山雕塑艺术小品成都环保不锈钢雕塑价位福建不锈钢雕塑模型无锡不锈钢雕塑订做黑河城市不锈钢雕塑安装南阳大型户外不锈钢雕塑宿迁不锈钢雕塑设计公司陕西不锈钢抽象摆件景观雕塑加工商丘室外不锈钢雕塑小品订做价格内蒙不锈钢大型景观雕塑造型定西不锈钢镂空雕塑制作河南公园景观不锈钢雕塑专业定制池州大型不锈钢雕塑生产厂家深圳小区不锈钢雕塑多边形不锈钢雕塑品牌鞍山不锈钢假山雕塑开封不锈钢镂空大型城市雕塑广安不锈钢雕塑设计图片内蒙不锈钢校园雕塑施工厂家烟台不锈钢雕塑字体焦作人物不锈钢雕塑定做价格不锈钢太湖石雕塑小品定做松江区拉丝不锈钢雕塑价格合理揭阳不锈钢雕塑生产洛阳不锈钢雕塑定制厂家

合作伙伴

玻璃钢制品

龙岗网络公司
深圳网站优化
龙岗网站建设
坪山网站建设
百度标王推广
天下网标王
SEO优化按天计费
SEO按天计费系统