首页 > 编程语言 > 详细

C数组实现静态链表及常用操作(模拟无指针编程语言数组实现链表)

时间:2021-03-15 22:52:06      阅读:38      评论:0      收藏:0      [点我收藏+]
说明:

数据元素为结构体(复合数据类型):

    存放游标和实际数据
    数据的第1个元素和末尾元素存放元数据
           **第1个元素**
                        游标:存放(指向)备用下标,供下次使用,初始化为1
                        数据:链表tail标识,(尾节点下标)
           **末尾元素:**
                        游标:存放链表第1个有效节点下标, head标识,初始化为1(根据len特殊处理)
                        数据:链表当前有效节点个数(长度len)
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>

#define MAXSIZE 10

typedef struct Node{
    int data;
    int cur;
} NODE, LINKLIST[MAXSIZE];

void init(LINKLIST);
bool is_full(LINKLIST);
bool is_empty(LINKLIST);
// 遍历所有有效元素
void traverse(LINKLIST);
// 遍历所有元素,便于学习
void traverse_all(LINKLIST);
// 追加节点(入栈)
bool append(LINKLIST, int);
// 获取指定位置上一个节点的下标,注意先检查再调用
int get_pre(LINKLIST, int);
// 删除指定节点,只返回成功失败,不返回删除成功的元素值
bool delete(LINKLIST, int);
// 允许前后插入
bool insert(LINKLIST, int, int);
/* 
 * 清空链表, 如没特殊要求, 也可用init函数代替
 * 这里调用delete函数,并从链表尾向前删除节点(只清空不改变head指向)
*/ 
bool clear(LINKLIST);
// 获取指定节点, 假设数据范围为正整数,错误我们返回-1
int get(LINKLIST, int);
// 获取并删除尾节点(出栈), 假设数据范围取正整数,错误我们返回-1
int pop(LINKLIST);

int pop(LINKLIST L)
{
    if (is_empty(L)) {
        printf("pop error! linklist is empty.\n");
        return -1;
    }

    int len = L[MAXSIZE-1].data;
    int val = get(L, len);
    delete(L, len);
    printf("pop success! val: %d\n", val);
    return val;
}

int get(LINKLIST L, int pos)
{
    int len = L[MAXSIZE-1].data;

    if (pos < 1 || pos > len) {
        printf("get error! pos(%d) out of range.\n", pos);
        return -1;
    }

    if (pos == 1) {
        int head = L[MAXSIZE-1].cur;
        int val = L[head].data;
        printf("get success! val:%d\n", val);
        return val;
    }

    int pre = get_pre(L, pos);
    int pos_index = L[pre].cur;
    int val = L[pos_index].data;
    printf("get success! val:%d\n", val);

    return val;
}

bool clear(LINKLIST L)
{
    if (is_empty(L)) {
        printf("链表为空,无需clear操作.\n");
        return true;
    }

    int len = L[MAXSIZE-1].data;
    for (int i=len; i > 0; i--) {
        if (! delete(L, i))
            return false;
    }
    return true;
}

bool insert(LINKLIST L, int pos, int e)
{
    int len = L[MAXSIZE-1].data;
    int head = L[MAXSIZE-1].cur;
    int tail = L[0].data;
    int now_index = L[0].cur;
    int next_index = L[now_index].cur;

    if (is_full(L)) {
        printf("插入失败,链表已满!\n");
        return false;
    } 

    if (pos < 1 || pos > len + 1) {
        printf("插入失败,无效的插入位置: %d\n", pos);
        return false;
    }

    int pre = get_pre(L, pos);

    printf("尝试插入位置 %d 值 %d", pos, e);
    // 插入空链表的第1个节点(条件成立时一定是pos=1)
    if (is_empty(L)) {
        printf(", (节点类型: 空链表第1个节点)");
        NODE New = {e, 0};
        L[now_index] = New;
        L[0].cur = next_index;
        L[0].data = now_index;
        ++L[MAXSIZE-1].data;
        L[MAXSIZE-1].cur = now_index;
    }
    // 插入新头节点
    else if (pos == 1) {
        printf(", (节点类型: 新头节点)");
        NODE New = {e, head};
        L[now_index] = New;
        // head 指向新头节点
        L[MAXSIZE-1].cur = now_index;
        // 备用节点指向
        L[0].cur = next_index;
        ++L[MAXSIZE-1].data;
    }
    // 插入新尾节点
    else if (pos == len + 1){
        printf(", (节点类型: 新尾节点)");
        NODE New = {e, 0};
        L[now_index] = New;
        // 上一个节点(前尾节点)由原来的0指向新的tail节点
        L[pre].cur = now_index;
        L[0].cur = next_index;
        // 更新tail标识
        L[0].data = now_index;
        ++L[MAXSIZE-1].data;
    }
    //插入中间节点
    else {
        printf(", (节点类型: 中间节点)");
        int this_next = L[pre].cur;
        // 连接后继节点
        NODE New = {e, this_next};
        L[now_index] = New;
        // 连接前躯节点
        L[pre].cur = now_index;
        L[0].cur = next_index;
        ++L[MAXSIZE-1].data;
    }

    putchar(‘\n‘);
    return true;
}

bool delete(LINKLIST L, int pos)
{
    /*删除任意节点共用操作:
     *  len减1
     *  回收空间
     *删除不同类型节点需要做的额外操作:
     *  pos == 1 的情况:头节点非尾节点,或头节点同时为尾节点
     *      无需再查找删除位置的前躯节点下标
     *      更新链表head, tail标识
     *  pos > 1的情况:尾节点, 或中间节点
     *    删除尾节点:pos == len
     *      查找前躯节点下标
     *      前躯节点的游标改为0
     *      更新链表tail标识为前躯节点
     *    删除中间节点:
     *      查找前躯节点下标
     *      连接前躯节点及后继节点
     *
     */
    printf("尝试删除位置: %d,  ", pos);
    if (is_empty(L)) {
        printf("删除失败, 链表为空!\n");
        return false;
    }

    int head = L[MAXSIZE-1].cur;
    int tail = L[0].data;

    if (pos < 1 || pos > MAXSIZE-2) {
        printf("删除失败, 位置超出范围\n");
        return false;
    }
    else if (pos == 1) {
        int new_head = L[head].cur;
        // 被删除节点数据置0
        L[head].data = 0;

        // 判断头节点是否同时为尾节点
        if (new_head == 0) {
            printf("(节点类型:头节点 + 尾节点)");
            // tail指向0(head不变,下次追加元素从这个开始追加)
            L[0].data = 0;
        }
        else {
            printf("(节点类型:头节点)");
            L[MAXSIZE-1].cur = new_head;
        }

        // 回收空间
        L[head].cur = L[0].cur;
        L[0].cur = head;
    }
    else {
        int pre = get_pre(L, pos);

        // 删除的位置等于长度则为尾节点
        if (pos == L[MAXSIZE-1].data) {
            // 被删除节点数据置0
            L[tail].data = 0;
            printf("(节点类型:尾节点)");
            // 更新tail指向
            L[0].data = pre;
            // 上一个节点变为尾节点,更新游标
            L[pre].cur = 0;
            // 回收空间
            L[tail].cur = L[0].cur;
            L[0].cur = tail;
        }
        else {
            printf("(节点类型:中间节点)");
            // 连接前躯和后继
            int now_index = L[pre].cur;
            L[pre].cur = L[now_index].cur;
            // 被删除节点数据置0
            L[now_index].data = 0;
            // 回收空间
            L[now_index].cur = L[0].cur;
            L[0].cur = now_index;
        } 
    }

    --L[MAXSIZE-1].data;
    printf(", 删除成功!\n");
    return true;
}

// 函数不做复杂检查,无法找到时返回-1
int get_pre(LINKLIST L, int pos)
{
    if (pos == 1)
        return 0;
    int p = L[MAXSIZE-1].cur;
    int i = 1;
    while (L[p].cur && i < pos-1) {
        p = L[p].cur;
        ++i;
    }
    return p;
}

bool append(LINKLIST L, int e)
{
    printf("追加元素:%d\n", e);
    if (is_full(L)) {
        printf("追加失败,链表已满!\n");
        return false;
    }

    NODE New = {e, 0}; //追加的尾元素固定指向0

    int tail_index = L[0].data; //获取链表尾元素的下标
    int now_index = L[0].cur; //本次追加元素使用的下标
    int next_index = L[now_index].cur; //保存备用下标的下一个下标作为新备用下标

    L[now_index] = New;
    ++L[MAXSIZE-1].data; //len(当前有效元素)加1
    L[0].data = now_index; //更新链表tail标识
    L[0].cur = next_index; //更新链表备用下标
    // 非init后首次插入,需要tail元素连接新元素操作
    if (tail_index != 0)
        L[tail_index].cur = now_index;

    return true;
}

bool is_empty(LINKLIST L)
{
    if (L[MAXSIZE-1].data == 0)
        return true;
    return false;
}

bool is_full(LINKLIST L)
{
    if (L[MAXSIZE-1].data == MAXSIZE-2)
        return true;
    return false;
}
void traverse(LINKLIST L)
{
    if (is_empty(L)) {
        printf("链表为空!\n");
        return; 
    }

    printf("链表元素:");
    // 保存链表的头元素下标(并不总是1)
    int head = L[MAXSIZE-1].cur;
    // 当head == 0 代表有效节点遍历结束
    while (head != 0) {
        printf("%d ", L[head].data);
        head = L[head].cur;
    }
    putchar(‘\n‘);
}

void traverse_all(LINKLIST L)
{
    printf("--------------current linklist state-----------------\n");
    printf("%10s", "Cursor: ");
    for (int i=0; i<MAXSIZE;i++) {
        printf("%4d ", L[i].cur);
    }
    putchar(‘\n‘);
    printf("%10s", "Data: ");
    for (int i=0; i<MAXSIZE;i++) {
        printf("%4d ", L[i].data);
    }
    putchar(‘\n‘);
    printf("%10s", "index: ");
    for (int i=0; i<MAXSIZE;i++) {
        printf("%4d ", i);
    }
    putchar(‘\n‘);
}

void init(LINKLIST L)
{
    for (int i=0; i<MAXSIZE-1; i++) {
        L[i].cur = i + 1;
        L[i].data = 0;
    }
    /*
     * 数组的尾元素的游标初始化指向第1个有数据的元素下标
     * 虽然此时1并不是是有效元素,但是append追加元素不用再加判断为空修改head变量了
    */
    L[MAXSIZE-1].cur = 1; //head
    L[MAXSIZE-1].data = 0; //len
}

int main(void)
{
    LINKLIST L;
    init(L);
    // test append
    traverse(L);
    traverse_all(L);
    append(L, 11);
    traverse_all(L);
    append(L, 12);
    traverse_all(L);
    append(L, 13);
    append(L, 14);
    append(L, 15);
    append(L, 16);
    append(L, 17);
    append(L, 18);
    traverse_all(L);
    append(L, 19);
    traverse_all(L);
    traverse(L);

    // test delete
    delete(L, 9);
    delete(L, 0);
    delete(L, 1);
    traverse_all(L);
    delete(L, 7);
    traverse_all(L);
    delete(L, 4);
    traverse_all(L);
    delete(L, 2);
    traverse_all(L);
    delete(L, 2);
    traverse_all(L);
    delete(L, 3);
    traverse_all(L);
    delete(L, 1);
    traverse_all(L);
    delete(L, 1);
    traverse_all(L);
    delete(L, 1);
    traverse(L);

    // test append
    append(L, 21);
    traverse_all(L);
    append(L, 22);
    traverse_all(L);
    append(L, 23);
    append(L, 24);
    append(L, 25);
    append(L, 26);
    append(L, 27);
    append(L, 28);
    traverse_all(L);
    append(L, 29);
    traverse_all(L);
    traverse(L);

    // test clear
    clear(L);
    traverse_all(L);
    traverse(L);
    clear(L);

    // test insert
    insert(L, 0, 100);
    insert(L, 2, 101);
    insert(L, 1, 32);
    traverse_all(L);
    traverse(L);
    insert(L, 1, 31);
    traverse_all(L);
    traverse(L);
    insert(L, 3, 33);
    traverse_all(L);
    traverse(L);
    insert(L, 4, 34);
    traverse_all(L);
    traverse(L);
    insert(L, 5, 35);
    traverse_all(L);
    traverse(L);
    insert(L, 5, 355);
    traverse_all(L);
    traverse(L);
    insert(L, 4, 344);
    traverse_all(L);
    traverse(L);
    insert(L, 3, 333);
    traverse_all(L);
    traverse(L);
    insert(L, 2, 322);
    traverse_all(L);
    traverse(L);

    // test pop
    get(L, 9);
    get(L, 0);
    get(L, 8);
    get(L, 1);

    // test pop
    pop(L);
    traverse_all(L);
    traverse(L);
    pop(L);
    traverse_all(L);
    traverse(L);
    pop(L);
    traverse_all(L);
    traverse(L);
    pop(L);
    traverse_all(L);
    traverse(L);
    pop(L);
    pop(L);
    traverse_all(L);
    traverse(L);
    pop(L);
    pop(L);
    pop(L);
    traverse_all(L);
    traverse(L);

    return 0;

}

output

链表为空!
--------------current linklist state-----------------
  Cursor:    1    2    3    4    5    6    7    8    9    1 
    Data:    0    0    0    0    0    0    0    0    0    0 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:11
--------------current linklist state-----------------
  Cursor:    2    0    3    4    5    6    7    8    9    1 
    Data:    1   11    0    0    0    0    0    0    0    1 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:12
--------------current linklist state-----------------
  Cursor:    3    2    0    4    5    6    7    8    9    1 
    Data:    2   11   12    0    0    0    0    0    0    2 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:13
追加元素:14
追加元素:15
追加元素:16
追加元素:17
追加元素:18
--------------current linklist state-----------------
  Cursor:    9    2    3    4    5    6    7    8    0    1 
    Data:    8   11   12   13   14   15   16   17   18    8 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:19
追加失败,链表已满!
--------------current linklist state-----------------
  Cursor:    9    2    3    4    5    6    7    8    0    1 
    Data:    8   11   12   13   14   15   16   17   18    8 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:11 12 13 14 15 16 17 18 
尝试删除位置: 9,  删除失败, 位置超出范围
尝试删除位置: 0,  删除失败, 位置超出范围
尝试删除位置: 1,  (节点类型:头节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    1    9    3    4    5    6    7    8    0    2 
    Data:    8    0   12   13   14   15   16   17   18    7 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 7,  (节点类型:尾节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    8    9    3    4    5    6    7    0    1    2 
    Data:    7    0   12   13   14   15   16   17    0    6 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 4,  (节点类型:中间节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    5    9    3    4    6    8    7    0    1    2 
    Data:    7    0   12   13   14    0   16   17    0    5 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 2,  (节点类型:中间节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    3    9    4    5    6    8    7    0    1    2 
    Data:    7    0   12    0   14    0   16   17    0    4 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 2,  (节点类型:中间节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    4    9    6    5    3    8    7    0    1    2 
    Data:    7    0   12    0    0    0   16   17    0    3 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 3,  (节点类型:尾节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    7    9    6    5    3    8    0    4    1    2 
    Data:    6    0   12    0    0    0   16    0    0    2 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 1,  (节点类型:头节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    2    9    7    5    3    8    0    4    1    6 
    Data:    6    0    0    0    0    0   16    0    0    1 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 1,  (节点类型:头节点 + 尾节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    6    9    7    5    3    8    2    4    1    6 
    Data:    0    0    0    0    0    0    0    0    0    0 
   index:    0    1    2    3    4    5    6    7    8    9 
尝试删除位置: 1,  删除失败, 链表为空!
链表为空!
追加元素:21
--------------current linklist state-----------------
  Cursor:    2    9    7    5    3    8    0    4    1    6 
    Data:    6    0    0    0    0    0   21    0    0    1 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:22
--------------current linklist state-----------------
  Cursor:    7    9    0    5    3    8    2    4    1    6 
    Data:    2    0   22    0    0    0   21    0    0    2 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:23
追加元素:24
追加元素:25
追加元素:26
追加元素:27
追加元素:28
--------------current linklist state-----------------
  Cursor:    9    0    7    5    3    8    2    4    1    6 
    Data:    1   28   22   25   24   26   21   23   27    8 
   index:    0    1    2    3    4    5    6    7    8    9 
追加元素:29
追加失败,链表已满!
--------------current linklist state-----------------
  Cursor:    9    0    7    5    3    8    2    4    1    6 
    Data:    1   28   22   25   24   26   21   23   27    8 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:21 22 23 24 25 26 27 28 
尝试删除位置: 8,  (节点类型:尾节点), 删除成功!
尝试删除位置: 7,  (节点类型:尾节点), 删除成功!
尝试删除位置: 6,  (节点类型:尾节点), 删除成功!
尝试删除位置: 5,  (节点类型:尾节点), 删除成功!
尝试删除位置: 4,  (节点类型:尾节点), 删除成功!
尝试删除位置: 3,  (节点类型:尾节点), 删除成功!
尝试删除位置: 2,  (节点类型:尾节点), 删除成功!
尝试删除位置: 1,  (节点类型:头节点 + 尾节点), 删除成功!
--------------current linklist state-----------------
  Cursor:    6    9    7    5    3    8    2    4    1    6 
    Data:    0    0    0    0    0    0    0    0    0    0 
   index:    0    1    2    3    4    5    6    7    8    9 
链表为空!
链表为空,无需clear操作.
插入失败,无效的插入位置: 0
插入失败,无效的插入位置: 2
尝试插入位置 1 值 32, (节点类型: 空链表第1个节点)
--------------current linklist state-----------------
  Cursor:    2    9    7    5    3    8    0    4    1    6 
    Data:    6    0    0    0    0    0   32    0    0    1 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:32 
尝试插入位置 1 值 31, (节点类型: 新头节点)
--------------current linklist state-----------------
  Cursor:    7    9    6    5    3    8    0    4    1    2 
    Data:    6    0   31    0    0    0   32    0    0    2 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 
尝试插入位置 3 值 33, (节点类型: 新尾节点)
--------------current linklist state-----------------
  Cursor:    4    9    6    5    3    8    7    0    1    2 
    Data:    7    0   31    0    0    0   32   33    0    3 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 33 
尝试插入位置 4 值 34, (节点类型: 新尾节点)
--------------current linklist state-----------------
  Cursor:    3    9    6    5    0    8    7    4    1    2 
    Data:    4    0   31    0   34    0   32   33    0    4 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 33 34 
尝试插入位置 5 值 35, (节点类型: 新尾节点)
--------------current linklist state-----------------
  Cursor:    5    9    6    0    3    8    7    4    1    2 
    Data:    3    0   31   35   34    0   32   33    0    5 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 33 34 35 
尝试插入位置 5 值 355, (节点类型: 中间节点)
--------------current linklist state-----------------
  Cursor:    8    9    6    0    5    3    7    4    1    2 
    Data:    3    0   31   35   34  355   32   33    0    6 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 33 34 355 35 
尝试插入位置 4 值 344, (节点类型: 中间节点)
--------------current linklist state-----------------
  Cursor:    1    9    6    0    5    3    7    8    4    2 
    Data:    3    0   31   35   34  355   32   33  344    7 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 33 344 34 355 35 
尝试插入位置 3 值 333, (节点类型: 中间节点)
--------------current linklist state-----------------
  Cursor:    9    7    6    0    5    3    1    8    4    2 
    Data:    3  333   31   35   34  355   32   33  344    8 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 333 33 344 34 355 35 
插入失败,链表已满!
--------------current linklist state-----------------
  Cursor:    9    7    6    0    5    3    1    8    4    2 
    Data:    3  333   31   35   34  355   32   33  344    8 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 333 33 344 34 355 35 
get error! pos(9) out of range.
get error! pos(0) out of range.
get success! val:35
get success! val:31
get success! val:35
尝试删除位置: 8,  (节点类型:尾节点), 删除成功!
pop success! val: 35
--------------current linklist state-----------------
  Cursor:    3    7    6    9    5    0    1    8    4    2 
    Data:    5  333   31    0   34  355   32   33  344    7 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 333 33 344 34 355 
get success! val:355
尝试删除位置: 7,  (节点类型:尾节点), 删除成功!
pop success! val: 355
--------------current linklist state-----------------
  Cursor:    5    7    6    9    0    3    1    8    4    2 
    Data:    4  333   31    0   34    0   32   33  344    6 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 333 33 344 34 
get success! val:34
尝试删除位置: 6,  (节点类型:尾节点), 删除成功!
pop success! val: 34
--------------current linklist state-----------------
  Cursor:    4    7    6    9    5    3    1    8    0    2 
    Data:    8  333   31    0    0    0   32   33  344    5 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 333 33 344 
get success! val:344
尝试删除位置: 5,  (节点类型:尾节点), 删除成功!
pop success! val: 344
--------------current linklist state-----------------
  Cursor:    8    7    6    9    5    3    1    0    4    2 
    Data:    7  333   31    0    0    0   32   33    0    4 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 333 33 
get success! val:33
尝试删除位置: 4,  (节点类型:尾节点), 删除成功!
pop success! val: 33
get success! val:333
尝试删除位置: 3,  (节点类型:尾节点), 删除成功!
pop success! val: 333
--------------current linklist state-----------------
  Cursor:    1    7    6    9    5    3    0    8    4    2 
    Data:    6    0   31    0    0    0   32    0    0    2 
   index:    0    1    2    3    4    5    6    7    8    9 
链表元素:31 32 
get success! val:32
尝试删除位置: 2,  (节点类型:尾节点), 删除成功!
pop success! val: 32
get success! val:31
尝试删除位置: 1,  (节点类型:头节点 + 尾节点), 删除成功!
pop success! val: 31
pop error! linklist is empty.
--------------current linklist state-----------------
  Cursor:    2    7    6    9    5    3    1    8    4    2 
    Data:    0    0    0    0    0    0    0    0    0    0 
   index:    0    1    2    3    4    5    6    7    8    9 
链表为空!

C数组实现静态链表及常用操作(模拟无指针编程语言数组实现链表)

原文:https://blog.51cto.com/sndapk/2660754

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!