(五)线性类型----数组结构类型及数据操作

来源:互联网 发布:语音信箱软件 编辑:程序博客网 时间:2024/05/17 09:39

数组结构的特点

  1.数组是在内存中的一段连续的存储空间,并且第一个元素的内存地址,就是数组的地址,这是数组类型的最明显的特点。
  2.相对于链表结构来说,因为数组的元素是连续的,它的查找速度就非常快,缺点就是插入和删除速度就非常慢。
  除了普通的数组是数组类型外,java中的ArrayList集合内部也是这种类型。

数组结构常用算法

  那java中ArrayList来举例,一般常用的算法有add(),get(),remove()等

// 定义一个数组类型的结构体// 为以下所有方法实现的公用结构体struct Arr{    int *pBase; // 存储数组元素的地址    int len;    // 数组所能容纳的最大元素的个数    int cnt;    // 当前数组有效元素的个数    int increment; // 自动增长因子 };// 以下是算法中用到的公有的函数// 1.初始化数组 void init(struct Arr *pArr, int length){    pArr->pBase = (int *)malloc(sizeof(int) * length);    if(NULL == pArr->pBase){        // 如果malloc分配内存失败         // 终止整个程序         printf("动态内存分配失败!\n");        exit(-1);      }else{        pArr->len = length;        pArr-> cnt = 0;    }     return;}// 2.判断数组是否已满bool isFull(struct Arr * pArr){    if(pArr->cnt == pArr->len){        return true;    }else{        return false;    }}// 3.判断数组是否为空,如果为空返回true,否则false bool isEmpty(struct Arr * pArr){    if(0 == pArr->cnt){        return true;    }else{        return false;    }   }

  1.add()算法
  这个实现比较简单,因为数组是连续存储的内存空间,所以在存储空间不满的情况下,只要将元素添加在最后一个元素地址的后面即可。

// 添加元素// val为要添加的元素// 返回一个bool类型,如果添加成功返回true,添加失败返回falsebool add(struct Arr * pArr, int val){    // 判断存储空间是否已满,    // 满返回false    if(isFull(pArr)){      return false;    } else{    // 不满时添加元素      pArr->pBase[pArr->cnt] = val;      (pArr->cnt)++;      return true;    }}

  
  
  2.insert()插入算法
  这个函数的功能是将元素插入到数组的第n个下标
  因为数组的连续存储,如果将一个元素插入到数组的第n个元素之前,那么假设这个插入的位置不是第1个,也不是最后一个,而是中间的某个位置,那么在这个位置上原本的元素和后面的元素都要向后移一位,并且顺序是先将元素向后移,然后再插入元素。

// 将元素插入在数组的某个下标中,并返回bool,如果成功就返回true,失败就为false// pos 要// val 要插入的元素 bool insert(struct Arr *pArr, int pos, int val){    int i;    // 判断数组空间是否已满    if(isFull(pArr)){        return false;    }    // 如果pos<1,即下标小于0,    // 或要插入的位置为有效个数+1个,即如果有效个数为3,但要在第5个位置插入元素    // 那么就不是连续的存储,就为非法的存储形式    // 返回false    if(pos < 1 || pos > pArr->cnt+1){        return false;    }    // 将要插入的位置的元素以及后面元素向后移位    for(i = pArr->cnt - 1; i >= pos - 1; i--){        pArr->pBase[i+1] = pArr->pBase[i];    }    // 将元素存入要插入的位置的内存空间    pArr->pBase[pos-1] = val;    // 有效个数+1    (pArr->cnt)++;    return true;}


  
  3.remove()移除
  该方法就是将所要移除第pos个元素位置的后面的元素值,赋值给前一个内存空间即可。
  比如
  总共有5个元素,想要移除第3个,那么就将
    第4个的值赋值给第3个元素的内存地址,
    第5个的值赋值给第4个元素的内存地址
  再将有效元素个数减1即可。

// 删除指定下标的元素 // pos 要移除的第几个元素// pVal 将删除的值放入到该地址下,以便能知道删除的是哪一个元素。bool remove(struct Arr *pArr, int pos, int * pVal){    // 判断是否为空    if(isEmpty(pArr)){        return false;    }     // 判断要移除的元素位置是否合法    if(pos < 1 || pos>pArr->cnt){        return false;    }    // 将删除的值赋值给变量    *pVal = pArr->pBase[pos-1];    // 将元素逐个向前偏移    for(int i = pos; i < pArr->cnt; i++){        pArr->pBase[i-1] = pArr->pBase[i];    }   // 有效元素个数减1    pArr->cnt--;    return true; }

  4.inversion()倒置
  只要使用循环,来将两个元素交换位置即可。
  第1次 第1个和第cnt个元素交换
  第2次 第2个和第cnt-1个元素交换
        ……
  第n次 第n个和第cnt-n个元素交换

// 倒序 void inversion(struct Arr *pArr){// 首元素的下标int i = 0;// 末元素的下标int j = pArr->cnt-1;// 第三方临时变量int temp;// 只要i<j,就不断循环交换while(i < j){    temp = pArr->pBase[i];    pArr->pBase[i] = pArr->pBase[j];    pArr->pBase[j] = temp;    i++;    j--;}return;

}

原创粉丝点击