动态数组也是数据结构中一种常见的存储和组织数据的方式,是在程序运行时动态分配内存空间的数组。
它与普通数组最大的区别是内存管理上的。
1.普通数组是静态的,分配在栈(Stack)上的,它大小是固定的(一旦确定,在操作时无法修改),因此需要预先知道数组的大小。
2.动态数组肯定是动态的,分配在堆(Heap)上的,它的大小可以根据需要自由的进行调整,但是需要手动管理内存,在不需要时释放内存。
综上,动态数组的优点主要有:
- 灵活性:像链表一样,可以不需要预先知道数组的大小
- 高效的随机访问:与普通数组一样,可以根据下标快速访问指定位置
动态数组的缺点主要有:
- 插入和删除元素的效率较低:与普通数组一样,在插入和删除元素时,均需要移动多个元素
- 内存浪费:动态数组的容量是固定的,无法自动收缩到实际需要的大小,因此可能出现未使用的内存空间
- 需要手动的分配和释放内存:手动添加,失误性大
接下来看一道题,具体了解动态数组的操作:
已知顺序表L长度为n,试编写算法实现在顺序表中删除值为elem的数据元素,其中n与elem从键盘输入。
Input:
10
1 3 2 5 7 8 8 4 6 8
8
Output:
L的长度为:10
L数据为:1 3 2 5 7 8 8 4 6 8
请输入删除的元素:8
L数据为:1 3 2 5 7 4 6
实现代码如下:
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
struct List
{
int *data;
int length;
};
void InitList(struct List* L,int n)
{
L->data = (int*)malloc(sizeof(L->data)*n);//动态分配数组内存
L->length = 0;
printf("L数据为:");
for(int i=0;i< n;i++)
{
scanf("%d",&(L->data[i]));
L->length++;
}
}
void ShowList(struct List* L)
{
for(int i=0;i<L->length;i++)
{
printf("%d ",L->data[i]);
}
printf("\n");
}
void DeleteElem(struct List* L,int elem)
{
int num = 0;
for(int i=0;i<L->length;i++)
{
if(L->data[i]!=elem)
{
L->data[num] = L->data[i];
num++;
}
}
if(num==L->length)
printf("没有该元素\n");
else
L->length = num;
printf("删改后的数据为:");
ShowList(L);
}
int main()
{
struct List* L;
L = (struct List*)malloc(sizeof(L));//指针初始化(这不是头指针)
int n,e;
printf("L的长度为:");
scanf("%d",&n);
InitList(L,n);
printf("请输入删除的元素:");
scanf("%d",&e);
DeleteElem(L,e);
//释放空间,切记!!!
free(L->data);
return 0;
}