不定长顺序表,顾名思义,就是顺序表的长度不定,可以存放任意多个数据。与定长顺序表相比,它可以在顺序表长度不够用时自己进行扩容。那么在设计不定长的顺序表时,存放数据的数组就不能是固定长度的了,这时我们可以考虑用动态数组elem来代替,进行扩容时就可以动态申请内存,将数据存放到动态数组中。同时加入一个变量size来存放总的格子数(总容量)。
接下来是代码:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<memory.h>
#include"DSeqList.h"
//初始化
void Init(PDSeqList pl)
{
if (pl == NULL)
{
return;
}
pl->parr = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE)*INITSIZE); //动态开辟空间
assert(pl->parr != NULL);
pl->cursize = 0; //数组长度为0
pl->totalsize = INITSIZE; //数组总长度为宏定义数据5
}
//第一种扩容方式 利用realloc函数
static void resize1(PDSeqList pl)
{
pl->parr = (ELEM_TYPE*)realloc(pl->parr,sizeof(ELEM_TYPE)*(pl->totalsize + INITSIZE)); //realloc函数
assert(pl->parr != NULL);
pl->totalsize += INITSIZE; //总长度变长
}
//第二种扩容方式 直接开辟更大的数组
static void resize(PDSeqList pl)
{
ELEM_TYPE* newarr = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE)*(pl->totalsize + INITSIZE)); //开辟更大的空间
assert(newarr != NULL);
memcpy(newarr,pl->parr, sizeof(ELEM_TYPE)*pl->totalsize); //利用memcpy将原先数据复制进去
free(pl->parr); //将原先开辟的动态空间释放掉
pl->parr = newarr;
pl->totalsize += INITSIZE;
}
//插入数据
int InsertPos(PDSeqList pl, int pos, ELEM_TYPE val)
{
if (pl == NULL)
{
return 0;
}
if (pos < 0 || pos > pl->cursize)
{
return -1;
}
if (IsFull(pl))
{
resize(pl);
}
for (int i = pl->cursize; i > pos; --i) //先将数据往后移
{
pl->parr[i] = pl->parr[i - 1];
}
pl->parr[pos] = val; //将数据插入进去
pl->cursize++;
return 1;
}
//按位置删除
int DeletePos(PDSeqList pl, int pos)
{
if (pl == NULL)
{
return 0;
}
if (pos < 0 || pos > pl->cursize - 1)
{
return -1;
}
for (int i = pos; i < pl->cursize - 1; ++i) //数据往前挪,直接覆盖
{
pl->parr[i] = pl->parr[i + 1];
}
pl->cursize--;
return 1;
}
//按元素删除
int DeleteKey(PDSeqList pl, ELEM_TYPE key)
{
int index = Search(pl, key);
if (index < 0)
{
return -1;
}
for (int j = index; j < pl->cursize; ++j)
{
if (pl->parr[j] == key)
{
for (int k = j; k < pl->cursize - 1; ++k)
{
pl->parr[k] = pl->parr[k + 1];
}
pl->cursize--;
j--;
}
}
return 1;
}
int Search(PDSeqList pl, ELEM_TYPE key)
{
int rt = -1;
if (pl != NULL)
{
for (int i = 0; i < pl->cursize; ++i)
{
if (key == pl->parr[i])
{
rt = i;
break;
}
}
}
return rt;
}
bool IsFull(PDSeqList pl)
{
return pl->cursize == pl->totalsize;
}
void Show(PDSeqList pl)
{
for (int i = 0; i < pl->cursize; ++i)
{
printf("%d ", pl->parr[i]);
}
printf("\n");
}
void Clear(PDSeqList pl)//清空数据
{
pl->cursize = 0;
}
void Destroy(PDSeqList pl)//销毁顺序表
{
Clear(pl);
free(pl->parr);
}
头文件DSeqList:
#define INITSIZE 5
typedef int ELEM_TYPE;
typedef struct DSeqList
{
ELEM_TYPE *parr;
int cursize;
int totalsize;
}DSeqList,*PDSeqList;
void Init(PDSeqList pl);
static void resize2(PDSeqList pl);
static void resize(PDSeqList pl);
int InsertPos(PDSeqList pl, int pos, ELEM_TYPE val);
int DeletePos(PDSeqList pl, int pos);
int DeleteKey(PDSeqList pl, ELEM_TYPE key);
int Search(PDSeqList pl, ELEM_TYPE key);
bool IsFull(PDSeqList pl);
void Show(PDSeqList pl);
void Clear(PDSeqList pl);
void Destroy(PDSeqList pl);
主函数main():(基本操作)
#include<stdio.h>
#include<stdlib.h>
#include"DSeqList.h"
int main()
{
DSeqList sl;
Init(&sl);
for (int i = 0; i < 10; ++i)
{
int rt = InsertPos(&sl, i, i + 1);
printf("rt %d:%d\n", i + 1, rt);
}
Show(&sl);
DeletePos(&sl, 2);
Show(&sl);
int rt1 = InsertPos(&sl, 1, 4);
printf("rt %d:%d\n", 11, rt1);
Show(&sl);
int rt2 = DeleteKey(&sl, 4);
printf("rt %d:%d\n", 12, rt2);
Show(&sl);
Clear(&sl);
Destroy(&sl);
system("pause");
return 0;
}