STL中Vector的代码实现,用动态数组实现
常用的容器包括vector, list, deque, queue, stack, map等,这些容器都是用基本的数据结构实现的。vector是用动态数组实现的;list是用双向循环链表实现的;deque有些特别,他是用一个个缓冲器组成的,把这些缓冲区的头指针放在数组中,使得使用者用迭代器+1就可以不停地遍历下一个元素,给使用者造成queue是顺序存储的假象,而这正是stl想要的,因为使用者不必去关心它复杂的实现过程;deque头尾都可插入弹出, queue, stack的实现是直接调用部分deque的接口,来完成各自的特性;map则是用红黑树来去实现的,是一种associate容器,它的查找速度相对于以上的sequence容器要快很多。
数据结构和算法无疑是大学最枯燥的课程之一,相比于其他的不同,其他的枯燥可以不必认真学,因为这门课的重要性,使得它是一门味同嚼蜡且还要去嚼的课程。话说到这了,不好意思的是对于半路出家的我来说,大学并没学过,哈哈哈。。。。。可是我要自学啊,这。。。。。
没的办法,想要练成《辟邪剑谱》,又不愿意自宫,哪有的事,男人要对自己狠一点(手动狗头)。。。。。。凡是要成为武学宗师必身怀些个威震江湖的神功,东邪的桃花影落飞神剑,碧海潮生按玉箫;西毒的蛤蟆功与逆行九阴真经 ;南帝的一阳指;北丐那至阳至刚的降龙十八掌与打狗棒法;中神通的先天功。如果已经学完了C,C++的基本语法(或看过《C++ Primer》),想要再精进一步,那就要该接触数组结构了。此外,若一门语言是一套剑的招式,数据结构更像是内功。不管学什么语言都用得到数组结构的基础。
vector是用动态数组实现的,所谓动态是指当存储在数组中的元素个数接近数组的容量时,vector机制会另外malloc一片空间,此空间的大小是原空间的两倍,然后再将原空间的数据复制过来,最后将原空间释放,这就是vector全部的机制。具体实现是结构体加上一些维护这些结构体的接口。
上代码,亲测有效!
DynamicArray.h:
#ifndef DYNAMIC_ARRAY_H
#define DYNAMIC_ARRAY_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//动态增长内存,策略,将存放的数据放到堆上
//申请内存,拷贝数据,释放内存
//capacity 总共空间
//size,记录当前数组中具体的元素个数
//动态数组结构体
typedef struct DYNAMICARRAY{
int* pAddr;//存放数据的地址
int size;//当前有多少个元素
int capacity;//容量
}Dynamic_Array;
//写一些列相关对结构体操作大的函数
//初始化,返回结构体指针
Dynamic_Array* Init_Array();
//尾插入,value为插入的值
void PushBack_Array(Dynamic_Array* arr, int value);
//删除,pos为要删除的位置
void RemoveByPos__Array(Dynamic_Array* arr, int pos);
//根据值删除
void RemoveByValue_Array(Dynamic_Array* arr, int value);
//查找,根据值查
int Find_Array(Dynamic_Array* arr, int value);
//打印
void Print_Array(Dynamic_Array* arr);
//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr);
//清空数组
void Clear_Array(Dynamic_Array* arr);
//获得数组容量
int Capacity_Array_1(Dynamic_Array* arr);
//获取当前元素个数
int Size_Array(Dynamic_Array* arr);
//根据位置获得某个位置元素
int At_Array(Dynamic_Array* arr, int pos);
#endif
DynamicArray.c:
#include "DynamicArray.h"
//写一些列相关对结构体操作大的函数
//初始化,返回结构体指针
Dynamic_Array* Init_Array()
{
//malloc()返回的是void*,在前面强转换类型
Dynamic_Array* myArray = (Dynamic_Array*)malloc(sizeof(Dynamic_Array));
//初始化
myArray->size = 0;
myArray->capacity = 20;
myArray->pAddr = (int*)malloc(sizeof(int)*myArray->capacity);
return myArray;
}
//尾插入,value为插入的值
void PushBack_Array(Dynamic_Array* arr, int value)
{
if (arr == NULL)//如果还没有初始化动态数组
{
return;
}
//判断空间是否足够
if (arr->size == arr->capacity)
{
//第一步 申请一块更大的内存空间,新空间是旧空间的2倍
int* newSpace = malloc(sizeof(int) * arr->capacity * 2);
//第二步骤 拷贝数据到新的空间
memcpy(newSpace, arr->pAddr, arr->capacity * sizeof(int));
//第三步 释放旧空间
free(arr->pAddr);
//更新容量
arr->capacity = arr->capacity * 2;
//执行新空间
arr->pAddr = newSpace;
}
//插入新元素
arr->pAddr[arr->size] = value;
arr->size++;
}
//删除,pos为要删除的位置
void RemoveByPos__Array(Dynamic_Array* arr, int pos)
{
if (arr == NULL)
{
return;
}
//判断位置是否有效
if (pos < 0 || pos >= arr->size)
{
return;
}
//删除元素,pos为数组中的标识
for (int i = pos; i < arr->size - 1; i++)
{
arr->pAddr[i] = arr->pAddr[i + 1];
}
arr->size--;
}
//根据值删除value第一次出现的位置
void RemoveByValue_Array(Dynamic_Array* arr, int value)
{
if (arr == NULL)
{
return;
}
//找到值的位置
int pos = Find_Array(arr,value);
//根据位置判断
RemoveByPos__Array(arr, pos);
}
//查找,根据值查
int Find_Array(Dynamic_Array* arr, int value)
{
if (arr == NULL)
{
//返回-1表出错
return -1;
}
//找到值的位置
int pos = -1;
for (int i = 0; i < arr->size; i++)
{
if (arr->pAddr[i] == value)
{
pos = i;
break;
}
}
return pos;
}
//打印
void Print_Array(Dynamic_Array* arr)
{
if (arr == NULL)
{
return;
}
for (int i = 0; i < arr->size; i++)
{
printf(" %d", arr->pAddr[i]);
}
printf("\n");
}
//释放动态数组的内存
void FreeSpace_Array(Dynamic_Array* arr)
{
if (arr == NULL)
{
return;
}
if (arr->pAddr != NULL)
{
free(arr->pAddr);
}
free(arr);
}
//获得数组容量
int Capacity_Array(Dynamic_Array* arr)
{
return 0;
}
//清空数组
void Clear_Array(Dynamic_Array* arr)
{
if (arr == NULL)
{
return;
}
//aAddr->空间
arr->size = 0;
}
//获得数组容量
int Capacity_Array_1(Dynamic_Array* arr)
{
if (arr == NULL)
{
return 0;
}
return arr->capacity;
}
//获取当前元素个数
int Size_Array(Dynamic_Array* arr)
{
if (arr == NULL)
{
return 0;
}
return arr->size;
}
//根据位置获得某个位置元素
int At_Array(Dynamic_Array* arr, int pos)
{
//会把错误码-1当做返回值
/*if (arr == NULL)
{
return 0;
}*/
//不在位置会返回越界,不崩?
return arr->pAddr[pos];
}
01动态数组.c:
#include "DynamicArray.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void test01()
{
//初始化动态数组
Dynamic_Array* myArray = Init_Array();
//打印容量和现有容量
printf("数组容量:%d\n", Capacity_Array_1(myArray));
printf("数组大小:%d\n", Size_Array(myArray));
//插入元素
for (int i = 0; i < 30; i++)
{
PushBack_Array(myArray, i);
}
//打印容量和现有容量
printf("数组容量:%d\n", Capacity_Array_1(myArray));
printf("数组大小:%d\n", Size_Array(myArray));
//删除
RemoveByPos__Array(myArray, 0);
RemoveByValue_Array(myArray, 27);
//打印
Print_Array(myArray);
//查找位置为5的值
int pos = Find_Array(myArray, 5);
printf("5查找到pos: %d %d\n", pos, At_Array(myArray, pos));
//销毁
FreeSpace_Array(myArray);
}
int main(void)
{
test01();
system("pause");
return 0;
}