在學完動態順序表後,我個人的理解就是動態順序表就像是一包方便麪,
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();
}
?