自己搭建的一个小型的数据库,有一些基本的运算功能。
//以下是头文件
#ifndef __DYNAMICARRAY_H_
#define __DYNAMICARRAY_H_
#define ElementType int
#define true 1
#define false 0
struct DynamicArray
{//定义一个结构体
ElementType * dp;
int size; //size里储存的是数组的大小
int len; //len里储存的是数组内存储的元素的数量
};
typedef struct DynamicArray DMArray;
int Initialize(DMArray *array);
void FreeArray(DMArray *array);
int ReallocArray(struct DynamicArray *array);
void Travel(struct DynamicArray *array );
void ReTrave(struct DynamicArray *array);
void InsertTail(struct DynamicArray *array,ElementType element);
void InsertHead(struct DynamicArray *array,ElementType element);
void InsertIndex(struct DynamicArray *array,ElementType element,int index);
void RemoveIndex(struct DynamicArray *array,int index);
void RemoveElement(struct DynamicArray *array,ElementType element);
ElementType FindByIndex(struct DynamicArray *array,int index);
int* FindByElement(struct DynamicArray *array,ElementType element);
int* FindByElement2(struct DynamicArray *array,ElementType element);
void SetvalueByIndex(struct DynamicArray *array,int index,ElementType element);
void SetvalueByElement(struct DynamicArray *array,ElementType oldValue,ElementType newValue);
struct DynamicArray* FindIntersection(struct DynamicArray *array1,struct DynamicArray *array2);
struct DynamicArray* FindUnionSet(struct DynamicArray *array1,struct DynamicArray *array2);
void Deduplingcation(struct DynamicArray *array);
struct DynamicArray* MergeArray(struct DynamicArray *array1,struct DynamicArray *array2);
void push(struct DynamicArray *s0,ElementType element);
ElementType pop(struct DynamicArray *s0);
#endif
//以下是.c文件
#include <stdlib.h>
#include <stdio.h> //因为我们这里要用到动态数组,所以引用这个库
#include "DynamicArray.h"
//算法里的快排,因为后面会用到,就提在前面写了,这个应该都知道功能。
void FastSort(int* a,int start,int end)
{
int right=end;
int left=start;
int temp=a[start];
while(left<right)
{
while(a[right]>temp&&left<right)
{
right--;
}
if(left<right)
{
a[left]=a[right];
left++;
}
while(left<right&&a[left]<temp)
{
left++;
}
if(left<right)
{
a[right]=a[left];
right--;
}
a[left]=temp;
FastSort(a,start,left-1);
FastSort(a,right+1,end);
}
}
//初始化函数
int Initialize(DMArray *array)
{
array->dp = (ElementType *)malloc(array->size * sizeof(ElementType));
//为结构体中的dp申请一个大小为size乘以ElemeType数据类型大小的空间
if(array->dp == NULL)
{
//进行判空,确定是否有申请到堆上的内存空间,没有申请到的话就返回false,申请到了就返回true。
printf("Init malloc Error!\n");
return false;
}
return true;
}
//动态数组申请了堆上内存,为了防止内存泄漏,我们肯定需要释放内存。
void FreeArray(DMArray *array)
{
//判断dp是否为空,不为空的话就先释放内存,再将dp置为空,养成置空的好习惯,同时将len重新记为0;
if(array->dp != NULL)
{
free(array->dp);
array->dp = NULL;
array->len = 0;
}
}
//对堆上申请的空间进行扩容,因为使用realloc扩容的话太不可控了,所以我们进行重新申请,并复制内容到新开辟的动态数组,然后再释放原动态数组。
int ReallocArray(DMArray *array)
{
ElementType *temp = array->dp; //存储原动态数组的地址,防止申请新地址之后找不到,无法释放原动态数组
array->dp = (ElementType *)malloc(sizeof(ElementType) * array->size * 2);
//在dp上重新申请一个新的动态数组空间。
if(array->dp == NULL)
{
//判断是否成功申请到新的堆上内存空间,未申请成功的话返还原地址
printf("ReallocArray Error!\n");
array->dp = temp;
return false;
}
//申请成功的话,将原动态数组里的值赋值到新开辟的空间里
for(int i = 0; i < array->len;i++)
{
array->dp[i] = temp[i];
}
//申请成功,数组的大小翻倍,所以size*2
array->size =array->size * 2;
free(temp);
return true;
}
//输出函数,按正序输出
void Travel(struct DynamicArray *array )
{
for(int i=0;i<array->len;i++)
{
printf("%d ",array->dp[i]);
}
printf("\n");
}
//输出函数,按逆序输出
void ReTrave(struct DynamicArray *array)
{
for(int i=array->len-1;i>=0;i--)
{
printf("%d ",array->dp[i]);
}
printf("\n");
}
//输入函数(尾插法)
void InsertTail(struct DynamicArray *array,ElementType element)
{
//判断数组中元素是否占满了开辟的内存
if(array->len == array->size)
{
//占满了的话就重新开辟一个大一点的内存
if(ReallocArray(array) == false)
{
//如果开辟失败就退出函数
printf("can not contain more elements!\n");
return;
}
}
//如果还有空间或重新开辟空间成功,就从数组尾部存入内容,并且元素数量加一。
array->dp[array->len] = element;
array->len++;
}
//输入函数(头部插入法)
void InsertHead(struct DynamicArray *array,ElementType element)
{
//判断数组中元素是否占满了开辟的内存
if(array->len == array->size)
{
//占满了的话就重新开辟一个大一点的内存
if(ReallocArray(array) == false)
{
//如果开辟失败就退出函数
printf("can not contain more elements!\n");
return ;
}
}
//如果还有空间或重新开辟空间成功,就将所有的元素往后挪一位。
for(int i = array->len-1;i>=0;i--)
{
array->dp[i+1] = array->dp[i];
}
//在数组头部插入元素,数组内元素数量加一。
array->dp[0] = element;
array->len++;
}
//输入函数(中间插入法),与前两个输入法的区别在于它还要传入一个插入的地址
void InsertIndex(struct DynamicArray *array,ElementType element,int index)
{
//判断数组中元素是否占满了开辟的内存
if(array->len == array->size)
{
//占满了的话就重新开辟一个大一点的内存
if(ReallocArray(array) == false)
{
//如果开辟失败就退出函数
printf("can not contain more elements!\n");
return ;
}
}
//判断需要插入的地址是否超出边界
if(index < 0 || index > array->len)
{
//如果超出边界就退出函数
printf("invalid place!!\n");
return;
}
//如果都没问题就从最后一位到插入的位置的元素依次往后挪一位
for(int i = array->len; i > index; i--)
{
array->dp[i] = array->dp[i-1];
}
//在插入位置输入要插入的元素,并且数组内元素数量加一
array->dp[index] = element;
array->len++;
}
删除函数(按位删除)
void RemoveIndex(struct DynamicArray *array,int index)
{
//判断需要删除的地址是否超出边界
if(index < 0 || index >= array->len)
{
//如果超出边界就退出函数
printf("invalid place!!\n");
return;
}
//从标志位的下一位到最后一位依次往前移一位,覆盖掉标志位
for(int i = index + 1; i < array->len; i++)
{
array->dp[i-1] = array->dp[i];
}
//数组内所存元素减一。
array->len--;
}
删除函数(按值删除)
void RemoveElement(struct DynamicArray *array,ElementType element)
{
for(int i = 0; i < array->len; i++)
{
//在数组中查找需要删除的值
if(array->dp[i] == element)
{
//如果找到了就用按位删除函数删除这个数,i为该元素传入的标志位,数组中含有元素的总量减一
RemoveIndex(array,i);
i--;
}
}
}
查找函数(按位查找)
ElementType FindByIndex(struct DynamicArray *array,int index)
{
//判断需要删除的地址是否超出边界
if(index < 0 || index >= array->len)
{
//如果超出边界就退出函数
printf("invalid place!!\n");
return 0;
}
//未超出边界就返回该数组标志位所存的值
return array->dp[index];
}
//查找函数(按值查找第一种方法)
int* FindByElement(struct DynamicArray *array,ElementType element)
{
//定义一个动态数组来承接所找到的值的下标
int *findVector = (int *)malloc((array->len+1) * sizeof(int));
int count = 0;
//定义一个变量来储存找到的值的个数
for(int i = 0; i < array->len; i++)
{
//遍历数组来查找数组内与所查值相同的元素
if(array->dp[i] == element)
{
//找到后数值加一,并将下标储存在新定义的数组内,(因为返回的数组需要知道边界,我们用第一个地址来存储边界)同时空出第一个地址,用来储存,找到的值的数量
count++;
findVector[count] = i;
}
}
//将找到的值的数量存在数组的第一位,并返回数组
findVector[0] = count;
return findVector;
}
//查找函数(按值查找第二种方法)
int* FindByElement2(struct DynamicArray *array,ElementType element)
{
//定义一个动态数组来承接所找到的值的下标
int *findVector = (int *)malloc((array->len+1) * sizeof(int));
int count = 0;
//定义一个变量来储存找到的值的个数
for(int i = 0; i < array->len; i++)
{
//遍历数组来查找数组内与所查值相同的元素
if(array->dp[i] == element)
{
//找到后将下标储存在新定义的数组内,然后数值加一
findVector[count] = i;
count++;
}
}
//因为返回的数组需要知道边界,我们在元素查找储存完之后,下一个指针存储为-1,由于指针不会有-1这个值,所以人为规定一个休止符来规定数组的边界。
findVector[count] = -1;
return findVector;
}
更改函数(按位置更改)
void SetvalueByIndex(struct DynamicArray *array,int index,ElementType element)
{
//判断需要删除的地址是否超出边界
if(index < 0 || index >= array->len)
{
//如果超出边界就退出函数
printf("invalid place!!\n");
return;
}
//未超出边界就将标志位的值替换为传入元素的值
array->dp[index] = element;
}
更改函数(按值更改)
void SetvalueByElement(struct DynamicArray *array,ElementType oldValue,ElementType newValue)
{
//遍历数组来查找数组内与所需替换的元素相同的元素
for(int i = 0; i < array->len; i++)
{ //找到需要替换的元素的下标
if(array->dp[i] == oldValue)
{//将该下标的值替换为传入的新值
array->dp[i] = newValue;
}
}
}
//逻辑与
struct DynamicArray* FindIntersection(struct DynamicArray *array1,struct DynamicArray *array2)
{ //定义一个结构体指针来储存逻辑与后剩下的元素
struct DynamicArray *intersection = (struct DynamicArray *)malloc(sizeof(struct DynamicArray));
if(intersection == NULL)
return NULL;
for(int i = 0; i < array1->len; i++)
{
for(int j = 0; j < array2->len; j++)
{
//遍历比较两个数组里的值,查找相等的值。
if(array1->dp[i] == array2->dp[j])
{
//定义一个标志位来判断该值是否在存储数组内已被存储
int flag = 0;
for(int k = 0; k < intersection->len; k++)
{
//遍历存储数组内是否有需要存入的值
if(intersection->dp[k] == array1->dp[i])
{
//有要存入的值,标志位定义为1
flag = 1;
}
}
//如果标志位为0,即存储数组内还没有需要存储的值,即录入该元素
if(flag == 0)
InsertTail(intersection,array1->dp[i]);
}
}
}
return intersection;
}
去重函数
void Deduplingcation(struct DynamicArray *array)
{
//先利用快排将数组进行排列
FastSort(array->dp,0,array->len-1);
for(int i = 0; i < array->len-1; i++)
{
//数组有序后判断前后函数是否相等
if(array->dp[i+1] == array->dp[i])
{
//删除后面相等的值,由于删除后后面的值会补上,但指针仍会向下走,这样会导致跳过函数,所以这里指针减一。确保判断完全部的函数
RemoveIndex(array,i+1);
i--;
}
}
}
逻辑并
struct DynamicArray *FindUnionSet(struct DynamicArray *array1,struct DynamicArray *array2)
{
定义一个结构体指针来储存逻辑并后剩下的元素
struct DynamicArray *UnionSet=(struct DynamicArray *)malloc(sizeof(struct DynamicArray ));
if(UnionSet==NULL);
return NULL;
for(int i=0;i<=array1->len;i++)
{
InsertTail(UnionSet,array1->dp[i]);
}
for(int i=0;i<=array2->len;i++)
{
InsertTail(UnionSet,array2->dp[i]);
}
//先将数组array1与array2里的所以元素全存在数组里,之后进行排序去重
Deduplingcation(UnionSet);
return UnionSet;
}
//数组合并
struct DynamicArray* MergeArray(struct DynamicArray *array1,struct DynamicArray *array2)
{
//先将数组全部排序
FastSort(array1->dp,0,array1->len-1);
FastSort(array2->dp,0,array2->len-1);
定义一个结构体指针来储存合并后的元素
struct DynamicArray* Merge = (struct DynamicArray*)malloc(sizeof(struct DynamicArray));
Merge->len = 0;
if(Merge == NULL)
{
return NULL;
}
int i= 0,j=0;
while( i < array1->len && j < array2->len)
{
if(array1->dp[i] <= array2->dp[j])
{
InsertTail(Merge,array1->dp[i]);
i++;
}
else
{
InsertTail(Merge,array2->dp[j]);
j++;
}
}
while(i < array1->len)
{
InsertTail(Merge,array1->dp[i]);
i++;
}
while(j < array2->len)
{
InsertTail(Merge,array2->dp[j]);
j++;
}
//将所以的元素按大小输入数组中
return Merge;
}
//栈的输入函数
void push(struct DynamicArray *s0,ElementType element)
{
//将数据按顺序一个个存入数组中
s0->dp[s0->len]=element;
s0->len++;
}
//栈的输出函数
ElementType pop(struct DynamicArray *s0)
{
if(s0->len==0)
{
printf("emty Stack!\n");
}
s0->len--;
return s0->dp[s0->len];
从底部开始一个个往前输出
}