在学完动态顺序表后,我个人的理解就是动态顺序表就像是一包方便面,
typedef struct seqlist//方便面的组成
{
SLDataType *_arry;// 面饼
size_t _size;//有效数据个数,同时也是插入的下一个下标 面饼重量
size_t _capcity;//容量空间的大小 包装袋
} seqlist;
比如 我们设置一个顺序表变量,例如seqlist fbm 可以看到它的组成成员一共有三个,我们实际需要的元素存在_arry指向的空间,
(一般用malloc函数分配),就像是我们吃方便面不可能连外边的袋子都吃了,所以我们访问的元素在_arry指向的空间,而不是fbm指向的空间
但是方便面除了面饼还有装面饼的袋子,以及面饼的质量,如果面饼太重了会撑破袋子,这个时候我们需要把袋子扩大,需要
realloc函数,我一般是把容量扩大成二倍即
fbm->__capcity*=2;
fbm->_arry = (SLDataType*)relloc(fbm->_arry ,sizeof(SLDataType)*_capcity);
剩下的增删改查基本和静态顺序表即数组元素的访问相同就不细说了以下是动态顺序表的接口以及测试函数的c语言源代码
?
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
//动态开辟顺序表
/*
这是静态顺序表不常用
typedef struct seqlist
{
int array[5];
int size'//有效数据个数
} seqlsit;
*/
typedef int SLDataType;
typedef struct seqlist//方便面的组成
{
SLDataType *_arry;// 面饼
size_t _size;//有效数据个数,同时也是插入的下一个下标 辣椒粉
size_t _capcity;//容量空间的大小 油包
} seqlist;
void seqlistInit(seqlist *ps,size_t size);//初始化
void seqlistDestory(seqlist *ps) ;//销毁
int seqlistFind(seqlist *ps,SLDataType x); //找到这个值
void seqlistPushBack(seqlist *ps,SLDataType X);//尾插入新的元素 X
void seqlistPopBack(seqlist *ps);// 尾删元素
void seqlistPushFront(seqlist *ps,SLDataType X);//头插入新元素
void seqlistPopFront(seqlist *ps);// 头删元素
void seqlistInsert(seqlist *ps,size_t pos,SLDataType x);//插入新元素到下标为pos的地址
void seqlistErase(seqlist *ps,size_t pos); //删除下标为pos的元素
void seqlistPrint(seqlist *ps);//显示所有数字
size_t seqlistsize(seqlist *ps);//有效数据个数
int seqlistEmpty(seqlist *ps); //非空返回一空返回0
void seqlistModify(seqlist*ps,size_t pos,SLDataType x);//修改把第pos个值修改为x
void seqlistBubbleSort(seqlist* psl); //冒泡排序
int seqlistBinaryFind(seqlist*psl, SLDataType x);//二分查找
// 本题要求:时间复杂度:O(N) 空间复杂度 O(1)
void seqlistRemoveAll(seqlist* psl, SLDataType x);
void test();
void CheckCapacity(seqlist *ps);
void seqlistInit(seqlist *ps,size_t capcity)
{
ps->_arry = (SLDataType *)malloc(sizeof(SLDataType)*capcity);//不同类型的指针
ps->_capcity = capcity;
ps->_size = 0;
}
void seqlistDestory(seqlist *ps)
{
assert(ps);
if(ps!=NULL)
{
if(ps->_arry)
{free(ps->_arry);
ps->_capcity = 0;
ps->_size = 0;
ps->_arry = NULL;//将指针立即置空
}
}
}
void CheckCapacity(seqlist *ps)
{
assert(ps);
if(ps->_capcity==ps->_size)
{
ps->_capcity*=2;
ps->_arry =(SLDataType*)realloc(ps->_arry,ps->_capcity*sizeof(SLDataType ));//增容注意
assert(ps->_arry);
}
}
void seqlistPushBack(seqlist *ps,SLDataType X)//如果不够应该增容
{
assert(ps);
if(ps->_capcity==ps->_size)
{
CheckCapacity(ps);
}
ps->_arry[ps->_size] = X;
ps->_size++;
}
void seqlistPopBack(seqlist *ps)
{
assert(ps&&ps->_size>0);
ps->_size--;
}
void seqlistPushFront(seqlist *ps,SLDataType X)
{
assert(ps);
if(ps->_capcity==ps->_size)
{
CheckCapacity(ps);
}
for(int i=ps->_size-1;i>=0;i--)
ps->_arry[i+1] =ps->_arry[i] ;
ps->_arry[0] = X;
ps->_size++;
}
void seqlistPopFront(seqlist *ps)
{
assert(ps&&ps->_size>0);
for(int i=1;i<ps->_size;i++)
{
ps->_arry[i-1] = ps->_arry[i];
}
ps->_size--;
}
void seqlistPrint(seqlist *ps)
{
assert(ps->_arry);
for(int i =0;i<ps->_size;i++)
{
printf("%d ",ps->_arry[i]);
}
printf("\n");
}
void seqlistInsert(seqlist *ps,size_t pos,SLDataType x)
{
assert(ps&&pos<=ps->_size);
if(ps->_size==ps->_capcity)
{
CheckCapacity(ps);
}
{
for(int n=ps->_size-1;n>=(int)pos;n--)//有错误,类型提升会把int换成size_t
{
ps->_arry[n+1] = ps->_arry[n];
}
ps->_arry[pos] = x;
ps->_size++;
}
}
void seqlistErase(seqlist *ps,size_t pos)
{
assert(ps&&ps->_arry&&pos<ps->_size);
for(int n=pos;n<(int)ps->_size-1;n++)//有错误,类型提升会把int换成size_t
{
ps->_arry[n] = ps->_arry[n+1];
}
ps->_size--;
}
int seqlistFind(seqlist *ps,SLDataType x)
{
assert(ps&&ps->_arry);
for(int n=0;n<ps->_size;n++)
{
if(ps->_arry[n] == x)
{
return n;
}
}
return -1;
}
size_t seqlistsize(seqlist* ps)
{
assert(ps&&ps->_arry);
return ps->_size;
}
int seqlistEmpty(seqlist* ps)
{
assert(ps&&ps->_arry);
return ps->_size>0?1:0;
}
void seqlistModify(seqlist*ps,size_t pos,SLDataType x)
{
assert(ps&&ps->_arry);
ps->_arry[pos] = x;
}
void seqlistBubbleSort(seqlist* ps)
{
assert(ps->_arry&&ps);
for(int i=0;i<ps->_size-1;i++)//进行ps->_size-1趟排序
for(int m=0;m<ps->_size-1-i;m++)//每次排序进行的次数为ps->_size
{
if(ps->_arry[m]>ps->_arry[m+1])
{
int tem =ps->_arry[m];
ps->_arry[m] = ps->_arry[m+1];
ps->_arry[m+1] = tem ;
}
}
}
int seqlistBinaryFind(seqlist* ps, SLDataType x)
{
assert(ps&&ps->_arry);
int left=0;
int right = ps->_size-1;
if(x>ps->_arry[right]||x<ps->_arry[left])
return -1;
int mid = (left+right)/2;
while(left<right)
{
printf("1: %d\n",mid);
if(x==ps->_arry[mid])
{
return mid;
}
if(x>ps->_arry[mid])
{
printf("2: %d %d %d\n",mid,left,right);
left = mid+1;
mid = (left+right)/2;
}
if(x<ps->_arry[mid])
{
printf("3: %d %d %d\n",mid,left,right);
right = mid-1;
mid = (left+right)/2;
}
}
return -1;
}
void seqlistRemoveAll(seqlist* ps, SLDataType x)
{
int i ;
int j = 0;//记录删除多少个数字
for(i=0;i<ps->_size;i++)
{
if(ps->_arry[i]== x)
{
//seqlistErase(ps,i);
for(int m=ps->_size-1;m>i;m--)
{
ps->_arry[m-1] = ps->_arry[m];
}
seqlistPrint(ps);
j++;
printf("%d \n",j);
}
}
ps->_size-=j;
}
void test()
{
seqlist head ;//指针必须初始化否则会指向一个未知的地址,十分危险
seqlistInit(&head,10);
/*for(int i=10;i>0;i--)
{
seqlistPushBack(&head,1);
}*/
for(int i=10;i>0;i--)
{
seqlistPushBack(&head,i);
}
//seqlistPrint(&head);
//seqlistPopBack(&head);
//seqlistPushFront(&head,2);
//seqlistPopFront(&head);
//seqlistInsert(&head,0, 5);
//seqlistErase(&head,9);
//printf("%d",seqlistFind(&head,5));
//printf("%d",seqlistEmpty(&head));
//seqlistModify(&head,2,300);
//seqlistBubbleSort( &head);
//seqlistRemoveAll(&head, 1);
seqlistPrint(&head);
//printf("%d\n",seqlistBinaryFind(&head, 6));
seqlistDestory(&head);
}
int main()
{
test();
}
?