Chinaunix首页 | 论坛 | 博客
  • 博客访问: 942802
  • 博文数量: 116
  • 博客积分: 3923
  • 博客等级: 中校
  • 技术积分: 1337
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-23 01:22
文章分类

全部博文(116)

文章存档

2013年(1)

2012年(17)

2011年(69)

2009年(29)

分类: LINUX

2012-01-19 16:43:58

基本排序算法之冒泡排序C实现
基本排序算法之选择排序C实现
基本排序算法之插入排序C实现
基本排序算法之希尔排序C实现
基本排序算法之快速排序C实现
基本排序算法之归并排序C实现
基本排序算法之堆排序C实现

  1. /*
  2.  * file: main.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <time.h>
  10. #include <string.h>

  11. #include "sorts.h"

  12. int compare(const int *d1, const int *d2)
  13. {
  14.     if (*d1 < *d2)
  15.         return -1;
  16.     else if (*d1 > *d2)
  17.         return 1;
  18.     else
  19.         return 0;
  20. }


  21. #define CNTOFARRAY(x) (sizeof(x)/sizeof(x[0]))

  22. #define ARRAY_MAX 10
  23. #define DATA_MAX 100

  24. typedef void (*sort_func)(void*, size_t, size_t, CMP_FUNC, SWAP_FUNC);

  25. void test_random(sort_func fsort)
  26. {
  27.     int rdata, rsize, i, j;
  28.     int *pnew=0;
  29.     srand ((unsigned)time(NULL));    
  30.     
  31.     for (i = 0; i < 10; i++) {
  32.         rsize = rand()%ARRAY_MAX+1;
  33.         pnew = malloc(sizeof(int) * rsize);
  34.         __assert(pnew);
  35.         for (j = 0; j < rsize; j++) {
  36.             rdata = rand()%DATA_MAX;
  37.             rdata = rand()%2 ? -rdata : rdata;
  38.             pnew[j] = rdata;
  39.         }
  40.         printf("------------------------------\n");
  41.         fsort(pnew, rsize, sizeof(int), compare, 0);
  42.         if(pnew) free(pnew);
  43.     }
  44. }
  45. typedef struct sort_s {
  46.     char *p;
  47.     sort_func f;
  48. }sort_t;

  49. #define sort_init(s) {#s,s}

  50. void main()
  51. {
  52.     int i;
  53.     void *p1,*p2,*p3,*p4,*p5;
  54.     const int a1[]={9,7,-2,10,-3,2,8,7,1,0};
  55.     const int a2[]={1,1,1,1,1,1};
  56.     const int a3[]={3};
  57.     const int a4[]={5,2};
  58.     const int a5[]={49,38,65,97,76,13,27,49,55,04};

  59.     sort_t sorts[] = {
  60.         sort_init(bubble_sort),
  61.         sort_init(select_sort),    
  62.         sort_init(insert_sort),
  63.         sort_init(shell_sort),
  64.         sort_init(quick_sort),
  65.         sort_init(merge_sort),
  66.         sort_init(heap_sort),
  67.     };


  68.     p1 = malloc(sizeof(a1));
  69.     p2 = malloc(sizeof(a2));
  70.     p3 = malloc(sizeof(a3));
  71.     p4 = malloc(sizeof(a4));
  72.     p5 = malloc(sizeof(a5));
  73.     __assert (p1 && p2 && p3 && p4 && p5);

  74.     for (i=0; i < CNTOFARRAY(sorts); i++) {
  75.         memcpy(p1, a1, sizeof(a1));
  76.         memcpy(p2, a2, sizeof(a2));
  77.         memcpy(p3, a3, sizeof(a3));
  78.         memcpy(p4, a4, sizeof(a4));
  79.         memcpy(p5, a5, sizeof(a5));
  80.         printf("==========> %s start ==========\n", sorts[i].p);
  81.         sorts[i].f(p1, CNTOFARRAY(a1), sizeof(a1[0]), compare, 0);    
  82.         printf("---------------------------------------------\n");
  83.         sorts[i].f(p2, CNTOFARRAY(a2), sizeof(a2[0]), compare, 0);
  84.         printf("---------------------------------------------\n");
  85.         sorts[i].f(p3, CNTOFARRAY(a3), sizeof(a3[0]), compare, 0);
  86.         printf("---------------------------------------------\n");
  87.         sorts[i].f(p4, CNTOFARRAY(a4), sizeof(a4[0]), compare, 0);
  88.         printf("---------------------------------------------\n");
  89.         sorts[i].f(p5, CNTOFARRAY(a5), sizeof(a5[0]), compare, 0);

  90.         printf("================ random test ... ============\n");
  91.         test_random(sorts[i].f);
  92.         printf("==========> %s end ! ==========\n", sorts[i].p);
  93.     }

  94.     free(p1);
  95.     free(p2);
  96.     free(p3);
  97.     free(p4);
  98.     free(p5);
  99. }

---------------------------------------------------------------------------------------------
  1. /*
  2.  * file: sorts.h
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #ifndef __SORTS_H__
  8. #define __SORTS_H__

  9. #include <stdio.h>
  10. #include <stdlib.h>

  11. #ifndef __assert
  12. #define __assert(x)
  13. #endif

  14. typedef int (*CMP_FUNC)(const void *d1, const void *d2);
  15. typedef void (*SWAP_FUNC)(void *d1, void *d2, unsigned int size);

  16. int cmp_dft(const void *d1, const void *d2);
  17. void swap_dft(void *d1, void *d2, unsigned int size);

  18. void dump_all(void *base, size_t num, size_t size);
  19. int verify(void *base, size_t num, size_t size, CMP_FUNC cmpf);

  20. void bubble_sort(void *base, size_t num, size_t size,
  21.                  CMP_FUNC cmpf, SWAP_FUNC swapf);

  22. void select_sort(void *base, size_t num, size_t size,
  23.             CMP_FUNC cmpf, SWAP_FUNC swapf);

  24. void insert_sort(void *base, size_t num, size_t size,
  25.             CMP_FUNC cmpf, SWAP_FUNC swapf);

  26. void shell_sort(void *base, size_t num, size_t size,
  27.             CMP_FUNC cmpf, SWAP_FUNC swapf);

  28. void quick_sort(void *base, size_t num, size_t size,
  29.             CMP_FUNC cmpf, SWAP_FUNC swapf);
  1. void merge_sort(void *base, size_t num, size_t size,
  2.             CMP_FUNC cmpf, SWAP_FUNC swapf);
  1. void heap_sort(void *base, size_t num, size_t size,
  2.             CMP_FUNC cmpf, SWAP_FUNC swapf);           

  1. #endif

----------------------------------------------------------------------------------------------
  1. /*
  2.  * file: sorts.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #include "sorts.h"

  8. void swap_dft(void *d1, void *d2, unsigned int size)
  9. {
  10.     char t;
  11.     while (size--)
  12.     {
  13.         t = *(char*)d1;
  14.         *((char*)d1)++ = *(char*)d2;
  15.         *((char*)d2)++ = t;
  16.     }
  17. }

  18. void dump_dft(void *d1)
  19. {
  20.     printf("%d ", *(int*)d1);
  21. }

  22. void dump_all(void *base, size_t num, size_t size)
  23. {
  24.     unsigned int i;
  25.     __assert(base);

  26.     for (i=0; i < num; i++) {
  27.         dump_dft((char*)base+i*size);
  28.     }
  29.     printf("\n");
  30. }

  31. int verify(void *base, size_t num, size_t size, CMP_FUNC cmpf)
  32. {
  33.     unsigned int i, c;
  34.     int flag=0, r;
  35.     __assert(base);

  36.     for (i=0; i < num-1; i++) {
  37.         c = i*size;
  38.         r = cmpf((char*)base+c, (char*)base+c+size);
  39.         if (!flag && r)
  40.         {
  41.             flag = (flag=r)<0 ? -1 : 1;
  42.         }
  43.         if(r!=0 && r!=flag) return -1;
  44.     }
  45.     return 0;
  46. }

----------------------------------------------------------------------------------------------
  1. /*
  2.  * file: bubble_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG
  10. #define __dump(b,n,sz) dump_all(b,n,sz)
  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }
  16. #else
  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)
  19. #endif

  20. static void __swap(void *d1, void *d2, size_t size)
  21. {
  22.     unsigned int t = *(unsigned int *)d1;
  23.     *(unsigned int *)d1 = *(unsigned int *)d2;
  24.     *(unsigned int *)d2 = t;
  25. }

  26. void bubble_sort(void *base, size_t num, size_t size,
  27.             CMP_FUNC cmpf, SWAP_FUNC swapf)
  28. {
  29.     unsigned int i, j, c;
  30.     __assert(base && cmpf);
  31.     if (!swapf)
  32.         swapf = (size == 4 ? __swap : swap_dft);
  33.     __dump(base, num, size);
  34.     for (i = 1; i < num; i++){
  35.         for (j = 0; j < num-i; j++){
  36.             c = j*size;
  37.             if (cmpf((char*)base+c, (char*)base+c+size) > 0)
  38.                 swapf((char*)base+c, (char*)base+c+size, size);
  39.         }
  40.         __dump(base, num, size);
  41.     }
  42.     __verify(base, num, size, cmpf);
  43. }

----------------------------------------------------------------------------------------------
  1. /*
  2.  * file: select_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG
  10. #define __dump(b,n,sz) dump_all(b,n,sz)
  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }
  16. #else
  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)
  19. #endif

  20. static void __swap(void *d1, void *d2, size_t size)
  21. {
  22.     unsigned int t = *(unsigned int *)d1;
  23.     *(unsigned int *)d1 = *(unsigned int *)d2;
  24.     *(unsigned int *)d2 = t;
  25. }

  26. void select_sort(void *base, size_t num, size_t size,
  27.             CMP_FUNC cmpf, SWAP_FUNC swapf)
  28. {
  29.     unsigned int i, j;
  30.     void *pmark;
  31.     __assert(base && cmpf);
  32.     if (!swapf)
  33.         swapf = (size == 4 ? __swap : swap_dft);
  34.     __dump(base, num, size);
  35.     for (i = 0; i < num-1; i++) {
  36.         pmark = (char*)base+i*size;
  37.         for (j = i+1; j < num; j++) {
  38.             if (cmpf(pmark, (char*)base+j*size)>0)
  39.                 pmark = (char*)base+j*size;
  40.         }
  41.         swapf(pmark, (char*)base+i*size, size);
  42.         __dump(base, num, size);
  43.     }
  44.     __verify(base, num, size, cmpf);
  45. }

----------------------------------------------------------------------------------------------
  1. /*
  2.  * file: insert_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG

  10. #define __dump(b,n,sz) dump_all(b,n,sz)

  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }

  16. #else

  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)

  19. #endif


  20. static void __swap(void *d1, void *d2, size_t size)
  21. {
  22.     unsigned int t = *(unsigned int *)d1;
  23.     *(unsigned int *)d1 = *(unsigned int *)d2;
  24.     *(unsigned int *)d2 = t;
  25. }

  26. void insert_sort(void *base, size_t num, size_t size,
  27.             CMP_FUNC cmpf, SWAP_FUNC swapf)
  28. {
  29.     unsigned int i, j, c;
  30.     __assert(base && cmpf);
  31.     if (!swapf)
  32.         swapf = (size == 4 ? __swap : swap_dft);
  33.     __dump(base, num, size);
  34.     for (i = 1; i < num; i++){
  35.         for (j = i; j > 0; j--){
  36.             c = j*size;
  37.             if (cmpf((char*)base+c, (char*)base+c-size) < 0)
  38.                 swapf((char*)base+c, (char*)base+c-size, size);
  39.             else
  40.                 break;
  41.         }
  42.         __dump(base, num, size);
  43.     }
  44.     __verify(base, num, size, cmpf);
  45. }
----------------------------------------------------------------------------------------------

  1. /*
  2.  * file: shell_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG
  10. #define __dump(b,n,sz) dump_all(b,n,sz)
  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }
  16. #else
  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)
  19. #endif

  20. static void __swap(void *d1, void *d2, size_t size)
  21. {
  22.     unsigned int t = *(unsigned int *)d1;
  23.     *(unsigned int *)d1 = *(unsigned int *)d2;
  24.     *(unsigned int *)d2 = t;
  25. }

  26. static void __shell_once(void *base, size_t num, size_t size,
  27.             CMP_FUNC cmpf, SWAP_FUNC swapf, unsigned int scale)
  28. {
  29.     unsigned int i, j, c, d, q=0;
  30.     //printf("---> scale : %d \n", scale);
  31.     while (q < scale) {
  32.         for (i = q+scale; i < num; i = i+scale){
  33.             for (j = i; j >= scale; j = j-scale){
  34.                 c = j*size;
  35.                 d = scale*size;
  36.                 if (cmpf((char*)base+c, (char*)base+c-d) < 0)
  37.                     swapf((char*)base+c, (char*)base+c-d, size);
  38.                 else
  39.                     break;
  40.             }
  41.         }
  42.         q++;
  43.     }
  44.     __dump(base, num, size);
  45. }

  46. void shell_sort(void *base, size_t num, size_t size,
  47.             CMP_FUNC cmpf, SWAP_FUNC swapf)
  48. {
  49.     unsigned int s = num;
  50.     __assert(base && cmpf);
  51.     if (!swapf)
  52.         swapf = (size == 4 ? __swap : swap_dft);
  53.     __dump(base, num, size);
  54.     while ((s=(s)>>1) >= 1) {
  55.         __shell_once(base, num, size, cmpf, swapf, (s&0x01)?s:s+1);
  56.     }
  57.     __verify(base, num, size, cmpf);
  58. }
----------------------------------------------------------------------------------------------

  1. /*
  2.  * file: quick_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG

  10. #define __dump(b,n,sz) dump_all(b,n,sz)

  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }

  16. #else

  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)

  19. #endif


  20. static void __swap(void *d1, void *d2, size_t size)
  21. {
  22.     unsigned int t = *(unsigned int *)d1;
  23.     *(unsigned int *)d1 = *(unsigned int *)d2;
  24.     *(unsigned int *)d2 = t;
  25. }


  26. static unsigned int __quick_once(void *base, size_t num, size_t size,
  27.             CMP_FUNC cmpf, SWAP_FUNC swapf)
  28. {
  29.     unsigned int i=0, j=num-1;
  30.     while (1) {
  31.         while (i<j && cmpf((char*)base+i*size, (char*)base+j*size) <= 0)
  32.             j--;
  33.         if (i==j) break;
  34.         swapf((char*)base+i*size, (char*)base+j*size, size);
  35.         i++;
  36.         while (i<j && cmpf((char*)base+i*size, (char*)base+j*size) <= 0)
  37.             i++;
  38.         if (i==j) break;
  39.         swapf((char*)base+i*size, (char*)base+j*size, size);
  40.         j--;
  41.     }
  42.     return i;
  43. }

  44. static void __quick_sort(void *base, size_t num, size_t size,
  45.             CMP_FUNC cmpf, SWAP_FUNC swapf)
  46. {
  47.     unsigned int k;
  48.     __assert(base && cmpf);
  49.     if (!swapf)
  50.         swapf = (size == 4 ? __swap : swap_dft);
  51.     if (num > 1)
  52.     {
  53.         k = __quick_once(base,num,size,cmpf,swapf);
  54.         __quick_sort(base, k, size, cmpf, swapf);
  55.         __quick_sort((char*)base+(k+1)*size, num-k-1, size, cmpf, swapf);
  56.     }
  57. }

  58. void quick_sort(void *base, size_t num, size_t size,
  59.                          CMP_FUNC cmpf, SWAP_FUNC swapf)
  60. {
  61.     __dump(base, num, size);
  62.     __quick_sort(base, num, size, cmpf, swapf);
  63.     __dump(base, num, size);
  64.     __verify(base, num, size, cmpf);
  65. }
----------------------------------------------------------------------------------------------
  1. /*
  2.  * file: merge_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG

  10. #define __dump(b,n,sz) dump_all(b,n,sz)

  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }

  16. #else

  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)

  19. #endif

  20. #define __malloc(x)    malloc(x)
  21. #define __free(x)    free(x)
  22. #define __memcpy(d,s,c) memcpyx(d,s,c)

  23. static void *memcpyx(void *dest, const void*src, size_t n)
  24. {
  25.     char *dest1 = dest;
  26.     const char *src1 = src;
  27.     while(n--)
  28.         *dest1++ = *(char*)src1++;
  29.     return dest;
  30. }

  31. static void __swap(void *d1, void *d2, size_t size)
  32. {
  33.     unsigned int t = *(unsigned int *)d1;
  34.     *(unsigned int *)d1 = *(unsigned int *)d2;
  35.     *(unsigned int *)d2 = t;
  36. }

  37. /*
  38.  * [0 ... m] [m+1 ... num-1]
  39.  */
  40. static void __merge(void *base, size_t num, size_t size, size_t m,
  41.                      CMP_FUNC cmpf, SWAP_FUNC swapf)
  42. {
  43.     unsigned int i=0, j=m+1, c;
  44.     void *ptmp, *pold;
  45.     pold = ptmp = __malloc(num*size);

  46.     __assert(base && ptmp && m <= num);
  47. //    printf("----------> m: %d\n", m);
  48.     while (i<=m && j<num) {
  49.         c = cmpf((char*)base+i*size, (char*)base+j*size)<=0 ? i++ : j++;
  50.         __memcpy(ptmp, (char*)base+c*size, size);
  51.         ptmp = (char*)ptmp+size;
  52.     }
  53.     if (i<=m)
  54.         __memcpy(ptmp, (char*)base+i*size, (m-i+1)*size);
  55.     if (j<num)
  56.         __memcpy(ptmp, (char*)base+j*size, (num-j)*size);
  57.     __memcpy(base, pold, num*size);

  58. //    __dump(base, num, size);
  59.     __free(pold);
  60. }


  61. void merge_sort(void *base, size_t num, size_t size,
  62.                 CMP_FUNC cmpf, SWAP_FUNC swapf)
  63. {
  64.     unsigned int i, c, step=1;
  65.     __assert(base && cmpf);
  66.     if (!swapf)
  67.         swapf = (size == 4 ? __swap : swap_dft);
  68.     __dump(base, num, size);
  69.     while (step < num)
  70.     {
  71.         for(i = 0; i < num; i += 2*step)
  72.         {
  73.             c = (i+2*step)>num?num-i:step*2;
  74.             __merge((char*)base+i*size, c, size, step-1, cmpf, swapf);
  75.         }
  76.         step *= 2;
  77.     }
  78.     __dump(base, num, size);
  79.     __verify(base, num, size, cmpf);
  80. }
----------------------------------------------------------------------------------------------

  1. /*
  2.  * file: heap_sort.c
  3.  * author: vincent.cws2008@gmail.com
  4.  * history:
  5.  * initial @ 2012-01-19
  6.  */

  7. #define DEBUG

  8. #include "sorts.h"

  9. #ifdef DEBUG

  10. #define __dump(b,n,sz) dump_all(b,n,sz)

  11. #define __verify(b,n,sz,cmp) \
  12. { \
  13.     if(verify(b, n, sz, cmp)!=0) \
  14.         printf("\n==>verification failed!\n"); \
  15. }

  16. #else

  17. #define __dump(b,n,sz)
  18. #define __verify(b,n,sz,cmp)

  19. #endif


  20. static void __swap(void *d1, void *d2, size_t size)
  21. {
  22.     unsigned int t = *(unsigned int *)d1;
  23.     *(unsigned int *)d1 = *(unsigned int *)d2;
  24.     *(unsigned int *)d2 = t;
  25. }

  26. /*
  27.  * i is the first position of array need to adjust ...
  28.  */
  29. void heap_adjust(void *base, size_t num, size_t size, int i,
  30.              CMP_FUNC cmpf, SWAP_FUNC swapf)
  31. {
  32.     unsigned int nchild, c;
  33.     void *pmark;
  34.     int t1, t2;
  35.     for (; 2*i+1 < num; i=nchild)
  36.     {
  37.         pmark=(char*)base+i*size;
  38.         nchild = 2*i+1;
  39.         c = nchild*size;
  40.         if (nchild < num-1 && cmpf((char*)base+c, (char*)base+c+size) < 0)
  41.         {
  42.             ++nchild;
  43.             c += size;
  44.         }
  45.         t1 = *(int*)pmark;
  46.         t2 = *(int*)((char*)base+c);
  47.         if (cmpf(pmark, (char*)base+c) < 0)
  48.             swapf(pmark, (char*)base+c, size);
  49.         else
  50.             break;
  51.     }
  52.     __dump(base, num, size);
  53. }

  54. void heap_sort(void *base, size_t num, size_t size,
  55.              CMP_FUNC cmpf, SWAP_FUNC swapf)
  56. {
  57.     int i;
  58.     __assert(base && cmpf);
  59.     if (!swapf)
  60.         swapf = (size == 4 ? __swap : swap_dft);
  61.     __dump(base, num, size);
  62.     
  63.     for (i=num/2-1; i>=0; --i)
  64.     {
  65.         heap_adjust(base, num, size, i, cmpf, swapf);
  66.     }
  67.     for (i=num-1; i>0; --i)
  68.     {
  69.         swapf((char*)base, (char*)base+i*size, size);
  70.         heap_adjust(base, i, size, 0, cmpf, swapf);
  71.     }
  72.     __dump(base, num, size);
  73.     __verify(base, num, size, cmpf);
  74. }


结束!

附件:
 algorithm_sorts.rar  




阅读(4754) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~