总所周知,C语言的数组是不可增加长度的,这就导致很多时候不能采取随机存储结构数组。这时很多人想到了链表,我们可以申请空间存放数据然后插入表中,确实可行,但是随机存储结构的优点可以在“O(1)”的时间内存就不存在了,得到的是一个可以很方便插入删除的链表。
但这时问题就来了,如果我并不需要频繁的做插入删除操作呢?链表的缺点是需要一个指针指向下一个节点,这浪费了很多的空间。
上图是顺序存储结构示意图,可以很容易得到,存放n个数据需要n*存放数据的数据类型的长度。比如int为一个字长,如果你是三十二位操作系统就是4个字节,六十四位就是8个字节。
上图可以很直观的看出,存放n个数据时它需要的空间是远远多于顺序存储结构的,相当于需要2倍的顺序存储结构需要的空间。
回归正题,可不可以实现动态的数组呢?答案是可以的。
#define init_list_length 26
#define num 10
struct arrayList{
char *element;
int length;
int maxLength;
};
typedef struct arrayList *List;
typedef struct arrayList Node;
需要一个结构体结构体,结构体中三个元素的作用分别是element相当于指向数组头节点的指针,数组的当前有效长度,和当前最大长度。详细说明一下什么是指向头节点的指针,对于c语言申请一个int类型的数组需要这样的语句int a[5];a就是指向头节点的指针,有些同学这时会有些疑问,不是数组吗怎么又变成指针了?你们可以尝试一下下面的代码。
int a[2]={2,3};
int *b;
b = a;
printf("%d\n",*b);
printf("%d\n",*(b+1));
运行结果是2,3(ps这里没考虑换行)。
解决了一个问题,但是还有一个问题,它怎么变成动态的了。话不多说关门,放代码。
void dilation(List list){//扩容
list->maxLength+=num;
realloc(list->element,list->maxLength);
}
每当你要插入或输入一个新的元素时,当前元素长度就加一了,length==maxLength就代表着已经到顶了,这时就要用上这个realloc语句。先将maxLength+=一个事先定义好的常数值,然后重新申请空间。realloc语句的好处是,会把原来的数据按序填入到新申请的数据空间中,这样就可以在保留原数据的基础上,进行了扩容的操作。
虽然这里没有实现JAVA中ArrayList的可以自由控制存储类型,但是要实现也不会太过复杂,根据不同的数据类型申请不同大小的空间就是了。JAVA中ArrayList见下图。
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
ArrayList<Integer> arrayList = new ArrayList<>();
ArrayList<Double> arrayList1 = new ArrayList<>();/*JavaArrayList存放类型可以是普通的数据类型,也可以是一个你自己写的类,相当于一个存放对象的可增长的数组*/
}
交并补差的实现:
1.需求分析
- 集合的元素限定为小写字母字符(‘a’..’z’),集合输入的形式为一个以“回车符”为结束标志的字符串,串中字符顺序不限,且允许出现重复字符或非法字符,程序应