在定长顺序表的基础上进行改动:
1、结构体设计
2、
typedef int ELEM_TYPE;
#define INIT_SIZE 10
//不定长顺序表的结构体设计:
typedef struct Dsqlist
{
ELEM_TYPE *elem;//指针,用来接收malloc返回值
int length;//当前有效值个数(当前有多少个格子被占用)
int list_size;//当前总空间个数(当前一共有多少个格子)
}Dsqlist, *PDsqlist;
2、不定长顺序表的基本操作
(1)初始化
void Init_Dsqlist(struct Dsqlist * p)//void Init_sqlist(PDsqlist p);
{
assert(p != NULL);//断言
if(p == NULL)
return;
p->elem = (ELEM_TYPE*)malloc(INIT_SIZE * sizeof(ELEM_TYPE));//动态申请内存,申请的内存指针为p->elem
assert(p->elem != NULL);
if(p->elem == NULL)
return;
p->length = 0;
p->list_size = INIT_SIZE;
}
(2)按位置插入
//按位置插入
bool Insert_pos(PDsqlist p, int pos, int val)
{
//assert p
//assert pos
//判满 扩容
if(IsFull(p))
{
Inc(p);
}
//此时,肯定p不为NULL, 并且pos位置合法, 并且还用空闲位置让我插入
//4.首先挪动数据,让待插入位置空出来,再将值val放进去即可
//(插入,挪动数据,从后先前挪)
for(int i=p->length-1; i>=pos; i--)//i一开始指向最后一个元素下标,最后挪动的数据下标是pos
{
p->elem[i+1] = p->elem[i];
}
//此时,for循环执行结束 标识着挪动数据完成 现在只需要将插入的值val赋值进去
p->elem[pos] = val;
//别忘了 插入操作最后还有一个有效值个数length++
p->length++;
return true;
}
(3)按位置删除
//按位置删除
bool Del_pos(PDsqlist p, int pos)
{
//1.判空 p!=NULL 判断定长顺序表是否存在
assert(p!=NULL);
if(p == NULL)
return false;
//2.判断删除位置 是否合法
assert(pos >=0 && pos<p->length);// 删除的时候pos==p->length不合法
if(pos<0 || pos>=p->length)
return false;
//3.判空操作
if(IsEmpty(p))
return false;
//4.将待删除位置后面的有效值,一次向前挪动一位,将删除位置覆盖掉即可
//(删除,向前覆盖数据,离待删除位置最近的元素先挪动)
for(int i=pos+1; i<=p->length-1; i++)
{
p->elem[i-1] = p->elem[i];
}
//此时,for循环执行结束 标识着数据向前覆盖完成 现在只需要将p->length--
p->length--;
return true;
}
(4)按值删除
//按值删除
bool Del_val(PDsqlist p, int val)
{
//assert p
//判断val这个值 存不存在
int index = Search(p, val);
if(index == -1)
{
return false;
}
return Del_pos(p, index);
}
(5)获取有效长度、获取值所在的下标
//获取其有效长度
int Get_length(PDsqlist p)
{
//assert
return p->length;
}
//获取值所在下标(如果数据重复,则返回val第一次出现的位置)
int Search(PDsqlist p, int val)
{
//assert
for(int i=0; i<p->length; i++)
{
if(p->elem[i] == val)
{
return i;
}
}
return -1;
}
(6)以2倍扩容
//扩容 以2倍扩容
void Inc(PDsqlist p)
{
//assert p 这个断言需不需要? 不需要
p->elem = (ELEM_TYPE*)realloc(p->elem, p->list_size*sizeof(ELEM_TYPE) * 2);
assert(p->elem != NULL);
if(p->elem == NULL)
{
printf("realloc error\n");
return;
}
//p->length;//扩容之后 有效值个数不变
p->list_size *= 2;//扩容之后 总格子个数需要*2
}
(7)判空、判满、清空、销毁、打印
//判空
bool IsEmpty(PDsqlist p)
{
//assert
return p->length == 0;
}
//判满
bool IsFull(PDsqlist p)
{
//assert
return p->length == p->list_size;
}
//清空
void Clear(PDsqlist p)
{
//assert
p->length = 0;
}
//销毁 主要处理内存泄露
void Destroy(PDsqlist p)
{
//assert
free(p->elem);
}
//打印
void Show(PDsqlist p)
{
//assert
for(int i=0; i<p->length; i++)
{
printf("%d ", p->elem[i]);
}
printf("\n");
}
3、主函数调用测试
//不定长顺序表测试用例
int main()
{
struct Dsqlist head;
Init_Dsqlist(&head);
printf("maxsize: %d\n", head.list_size);
printf("length = %d\n", Get_length(&head));
for(int i=0; i<10; i++)
{
Insert_pos(&head, i, i+1);
}
Insert_pos(&head, 0, 100);
Insert_pos(&head, head.length, 200);
printf("maxsize: %d\n", head.list_size);
printf("length = %d\n", Get_length(&head));
Show(&head);
Del_pos(&head, 3);
Show(&head);
Del_val(&head, 9);
Show(&head);
printf("%d\n", Search(&head, 5));
printf("%d\n", Search(&head, 300));
Clear(&head);
printf("length = %d\n", Get_length(&head));
Show(&head);
Destroy(&head);
return 0;
}