新增功能: - q_addpro 任意位置插入,含位置合法性检查(0 <= num <= end) - q_reducepro 任意位置删除,含位置合法性检查(0 <= num <= end-1) - q_reduce 出队,一行复用 q_reducepro(q, 0, x) 修复: - q_add 的扩容判断改用 end。原先用未初始化的 length, 导致 "length == max" 永远不成立,扩容代码从未执行过,是潜在的堆越界 结构调整: - 去掉 length 字段 —— 它与 end 表示同一件事,并存必然产生不一致 - 1.c 改名为 seqlist.c(顺序表 sequential list) 调试记录.md 改名为 seqlist-debug-notes.md 验收: - gcc -Wall -Wextra 零 warning 零 error - 18 个用例全绿(含 0 号位 / 末尾 / 末尾+1 / 负数 / 空表 / 自动扩容) 详见 seqlist-debug-notes.md 中记录的 8 个坑及沉淀的原则。
124 lines
2.3 KiB
C
124 lines
2.3 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct {
|
|
int max; //列表最大长度
|
|
//int length; //列表现在的长度
|
|
int *start; //内存地址起始位置
|
|
int front; //列表起始索引
|
|
int end; //列表下一个空位置的索引
|
|
|
|
}queue;
|
|
|
|
|
|
int q_init(queue *q,int length){ //就是普通的初始化。要给他什么参数呢?首先就是queue的地址,然后是一个初始长度。然后初始化全0就行了。
|
|
q->start=malloc(length*sizeof(int));
|
|
q->max=length;
|
|
q->front=0;
|
|
q->end=0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int q_add(queue *q,int num){ //最后边加上元素
|
|
if(q->end==q->max){ //容量不够了的自动扩容
|
|
q->max+=5;
|
|
q->start=realloc(q->start,q->max*sizeof(int));
|
|
}
|
|
q->start[q->end]=num;
|
|
q->end++;
|
|
return 0;
|
|
}
|
|
|
|
int q_addpro(queue *q,int num,int x){ //num是插入位置,x是插入的元素。任意地方加上元素,要进去一个索引编号和数值
|
|
//先判断够不够位置加上去先
|
|
//根据进一步检查,这里要加一个非法参数拦截--索引过大直接报错。如果只是最后一位在追加,那也接受,但是就调用q_add就行了似乎。
|
|
if (num>q->end||num<0){
|
|
return -1; //超出了直接报错
|
|
}
|
|
// if (num==q->max){
|
|
// q_add(q,x);
|
|
// } 这里下面的循环已经可以处理了,不需要
|
|
if(q->end>=q->max){
|
|
q->max=q->max+5;
|
|
q->start=realloc(q->start,q->max*sizeof(int));//这里就是扩容代码,把max也一起增加了
|
|
}
|
|
//然后写平移的代码段,把加入的位置的东西到end的所有东西往后平移一个
|
|
for (int i = q->end-1; i >= num; i--)
|
|
{
|
|
/* code */
|
|
q->start[i+1]=q->start[i];
|
|
|
|
|
|
}
|
|
q->end++;
|
|
q->start[num]=x;
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int q_reducepro(queue *q,int num ,int *x){ //任意地方拿走元素,也是索引号+数值
|
|
if(num>=q->end||num<0){return -1;}
|
|
*x=q->start[num];
|
|
|
|
for (int i = num; i < q->end-1; i++)
|
|
{
|
|
/* code */
|
|
q->start[i]=q->start[i+1];
|
|
|
|
|
|
}
|
|
q->end--;
|
|
return 0;
|
|
}
|
|
|
|
int q_reduce(queue *q,int *x){ //最前面拿走元素
|
|
return q_reducepro(q,0,x);
|
|
}
|
|
|
|
int printall(queue *q){ //打印全部东西
|
|
printf("下面是依次打印");
|
|
for (int i = 0; i < q->end; i++)
|
|
{
|
|
/* code */
|
|
|
|
printf("\n%d\n",q->start[i]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(){
|
|
queue q;
|
|
printf("输入整个列表长度");
|
|
int length;
|
|
scanf("%d",&length);
|
|
int b;
|
|
q_init(&q,length);
|
|
printf("接下来依次输入放进列表的东西");
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
/* code */
|
|
scanf("%d",&b);
|
|
q_add(&q,b);
|
|
}
|
|
printall(&q);
|
|
printf("\n接下来测试中间插入: 3号位置插入666,5号位置插入-77,11号位置插入1919810");
|
|
|
|
q_addpro(&q,3,666);
|
|
q_addpro(&q,5,-77);
|
|
q_addpro(&q,11,1919810);
|
|
printall(&q);
|
|
|
|
|
|
return 0;
|
|
}
|
|
|