线性表:必须有顺序:数据之间有关系
1.顺序表:
静态顺序表
顺序表的容量是在编译期间(静态期间)决定
写死在代码里的
Typedef struct SeqList{
Int array[100];//容量是100
Int size;//当前顺序表里已经有的数据个数
//顺便表示了顺序表最后插入的数据下标
} SeqList;
size =0 初始化的时候
size =-1 最后一个有效数据的下标
动态顺序表
顺序表的容量是在运行期间(动态期间)决定
Typedef int SLDateType;//定义数据类型为int
Typedef struct SeqList{
SLDateType *array;
Int capacity;//容量
Int size;
} SeqList;
顺序表:
头插+中间插入+尾插
头删+中间删除+尾删
最大的优势:支持随机下标访问(想取第几个,可以用O(1)取到第几个)
顺序表的尾插,时间复杂度是平均O(1)
什么时候用assert,什么时候用if 判断
传给我不知道该怎么办用assert,在定义域之外
在定义域之内的用if
static的作用:
static修饰函数更改链接属性,只有这个.c文件可以使用,从外部链接属性改变为内部链接属性,对外不可见
代码如下:
#pragma once
#include
#include
#include
typedef int SLDateType;//定义数据类型为int
typedef struct SeqList{
SLDateType *array;
int capacity;//容量
int size;
} SeqList;
//static修饰函数更改链接属性,只有这个.c文件可以使用,从外部链接属性改变为内部链接属性,对外不可见
//检查数据插入时,是否需要扩容,如果需要,则扩容
static void CheckCapacit(SeqList *seqlist);//扩容
void SeqListInit(SeqList *seqlist, int capacity);//初始化,把SeqList地址和容量传进去
void SeqListDestroy(SeqList *seqlist);//销毁
//增删改查
/*增*/
void SeqListPushBack(SeqList *seqlist, SLDateType v);//尾插
void SeqListPushFront(SeqList *seqlist, SLDateType v);//头插
void SeqListInsert(SeqList *seqlist, SLDateType pos, SLDateType v);//根据pos下标做插入
/*删*/
void SeqListPopBack(SeqList *seqlist);//尾删
void SeqListPopFront(SeqList *seqlist);//头删
void SeqListErase(SeqList *seqlist, SLDateType pos);//根据pos下标做删除
/*改*/
//inline 内联函数
void SeqListModify(SeqList *seqlist, SLDateType pos, SLDateType v);
/*查*/
//返回遇到的第一个v的下标,如果没找到,返回-1
int SeqListFind(const SeqList *seqlist, SLDateType v);
//打印
int SeqListPrint(const SeqList *seqlist);
//删除第一次遇见的v
void SeqListRemove(SeqList *seqlist, SLDateType v);
//删除遇见的所有v
void SeqListRemoveAll(SeqList *seqlist, SLDateType v);
#include"SeqList.h"
static void CheckCapacit(SeqList *seqlist){
if (seqlist->size < seqlist->capacity){//不需要扩容
return;
}
//需要扩容的情况
//申请新空间
int newCapacity = 2 * seqlist->capacity;
SLDateType *newArray = (SLDateType *)malloc(sizeof(SLDateType)* newCapacity);
//copy老数据到新空间
for (int i = 0; i < seqlist->size; i++){
newArray[i] = seqlist->array[i];
}
//释放老空间,把新空间绑定到顺序表结构体
free(seqlist->array);
seqlist->array = newArray;
//更新容量
seqlist->capacity = newCapacity;
}
void SeqListInit(SeqList *seqlist, SLDateType capacity){
assert(seqlist != NULL);
seqlist->array = (SLDateType *)malloc(sizeof(SLDateType)*capacity);//在堆上分配顺序表的空间,给SeqList中的array分配SLDateType*类型的空间
seqlist->capacity = capacity;//初始化容量
seqlist->size = 0;//初始化
}
void SeqListDestroy(SeqList *seqlist){//释放//销毁顺序表的存储空间
//释放顺序表的存储空间
//额外的工作,把字段reset为初始值
assert(seqlist != NULL);
assert(seqlist->array != NULL);
free(seqlist->array);
//锦上添花
seqlist->array = NULL;
seqlist->capacity = seqlist->size = 0;
}
void SeqListPushBack(SeqList *seqlist, SLDateType v){//尾插
CheckCapacit(seqlist);
seqlist->array[seqlist->size] = v;
seqlist->size++;
}
void SeqListPushFront(SeqList *seqlist, SLDateType v){ //头插
CheckCapacit(seqlist);
for (int i = seqlist->size - 1; i >= 0; i--){//数据
seqlist->array[i+1] = seqlist->array[i];
}
seqlist->array[0] = v;
seqlist->size++;
}
JAVA写法:
void pushfront(int v){//头插 if(this.size==this.array.length){//需要扩容 int capacity=this.array.length*2; int [] newarray=new int [capacity]; //搬家 for(int i=0;ivoid SeqListInsert(SeqList *seqlist, SLDateType pos, SLDateType v){//根据pos下标做插入
CheckCapacit(seqlist);
for (int i = seqlist->size - 1; i >= pos; i--){//数据
seqlist->array[i + 1] = seqlist->array[i];
}
seqlist->array[pos] = v;
seqlist->size++;
}
void SeqListPopBack(SeqList *seqlist){ //尾删
assert(seqlist != NULL);
assert(seqlist->size > 0);
seqlist->size--;
}
void SeqListPopFront(SeqList *seqlist){//头删
assert(seqlist != NULL);
assert(seqlist->size > 0);
for (int i = 0; i <= seqlist->size - 2; i++){//空间,从前往后移动
seqlist->array[i] = seqlist->array[i + 1];
}
seqlist->size--;
}
void SeqListErase(SeqList *seqlist, int pos){//根据pos下标做删除
assert(seqlist != NULL);
assert(seqlist->size > 0);
assert(pos >= 0 && pos <= seqlist->size - 1);
for (int i = pos; isize - 1; i++){//空间
seqlist->array[i] = seqlist->array[i+1];
}
seqlist->size--;
}
void SeqListModify(SeqList *seqlist, SLDateType pos, SLDateType v){
seqlist->array[pos] = v;
}
int SeqListFind(const SeqList *seqlist, SLDateType v){
//遍历
for (int i = 0; i < seqlist->size; i++){
if (seqlist->array[i] == v){
return i;
}
}
return -1;
}
int SeqListPrint(const SeqList *seqlist){
for (int i = 0; i < seqlist->size; i++){
printf("%d ", seqlist->array[i]);
}
printf("\n");
}
void SeqListRemove(SeqList *seqlist, SLDateType v){//删除第一次遇见的v
int pos = SeqListFind(seqlist, v);//先找到v的下标
if (pos == -1){
return;
}
SeqListErase(seqlist, pos);//删掉
}
void SeqListRemoveAll(SeqList *seqlist, SLDateType v){//删除遇见的所有v,重点
int i,j;
for ( i = 0, j = 0; i < seqlist->size; i++){
if (seqlist->array[i] != v){
seqlist->array[j] = seqlist->array[i];
j++;
}
}
seqlist->size = j;
}main.c
#include"SeqList.h"
int main(){
#if 1
SeqList seqlist;
SeqListInit(&seqlist,10);
SeqListPrint(&seqlist);SeqListPushBack(&seqlist, 1);
SeqListPushBack(&seqlist, 2);
SeqListPushBack(&seqlist, 3);
SeqListPushBack(&seqlist, 4);
SeqListPushBack(&seqlist, 5);
SeqListPrint(&seqlist);
//1 2 3 4 5SeqListPushFront(&seqlist, 10);
SeqListPushFront(&seqlist, 20);
SeqListPushFront(&seqlist, 30);
SeqListPushFront(&seqlist, 40);
SeqListPushFront(&seqlist, 50);
SeqListPrint(&seqlist);
//50 40 30 20 10 1 2 3 4 5//再插入应该要扩容
SeqListInsert(&seqlist, 5, 100);
SeqListPrint(&seqlist);
//50 40 30 20 10 100 1 2 3 4 5SeqListPopFront(&seqlist);
SeqListPopFront(&seqlist);
SeqListPrint(&seqlist);
//30 20 10 100 1 2 3 4 5SeqListPopBack(&seqlist);
SeqListPrint(&seqlist);
//30 20 10 100 1 2 3 4
SeqListErase(&seqlist, 3);
SeqListPrint(&seqlist);
//30 20 10 1 2 3 4
SeqListPushBack(&seqlist, 20);
SeqListPrint(&seqlist);
//30 20 10 1 2 3 4 20
SeqListRemoveAll(&seqlist, 20);
SeqListPrint(&seqlist);
//30 10 1 2 3 4
SeqListDestroy(&seqlist);
system("pause");
#else
SeqList *pSeqList = SeqListInit(&seqlist);//需要在堆上再申请一块空间
#endif
}结果:
1 2 3 4 5
50 40 30 20 10 1 2 3 4 5
50 40 30 20 10 100 1 2 3 4 5
30 20 10 100 1 2 3 4 5
30 20 10 100 1 2 3 4
30 20 10 1 2 3 4
30 20 10 1 2 3 4 20
30 10 1 2 3 4
请按任意键继续. . .