目录
1.顺序表的存储结构及基本知识点:
//采用动态一维数组
typedef struct
{
ElemType *elem; //指针域,指向顺序表的基地址
int length; //顺序表长度
int listsize; //顺序表当前分配的空间大小
}SeqList;
1.当指针elem指向一块分配的存储空间后就可以当成一个数组来使用。第一个元素存放在下标为0的存储单元中。
2.关键字typedef语法:
typedef 的真正意思是给一个已经存在的数据类型(注意:是类型不是变量)取一个别名,而非定义一个新的数据类型。这里的数据类型包括内部数据类(int,char等)和自定义的数据类型(struct等)。
如:
1、typedef int ElemType,即int类型的别名为ElemType;
2、又如上述顺序表的存储结构中可以用SeqList作为类型声明新的结构体变量;
3.强制转换
//强制类型转换是把变量从一种类型转换为另一种数据类型。例如,如果您想存储一个 long 类型的值到一个简单的整型中,您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符实现一种类型转换为另一种类型。
(type_name) expression;
//如:
int sum = 17, count = 5;
double mean;
mean = (double) sum / count; //强制类型转换运算符的优先级大于除法,因此 sum 的值首先被转换为 double型,然后除以count,得到一个类型为double的值。
(void *)malloc(unsigned int size) //内存分配成功之后,malloc 函数返回这块内存的首地址。你需要一个指针来接收这个地址并需要强制转化为所需要的指针类型.
4.内存管理
(void *)malloc(int num);
//在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
(void *)calloc(int num, int size);
//在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。
(void *)realloc(void *address, int newsize);
//该函数重新分配内存,把内存扩展到 newsize。
2.初始化操作
(1).给顺序表分配存储空间
(2).将表长置为0,将顺序表的存储空间大小置为LISTINITSIZE
int InitList(SeqList *L)
{
L->elem=(ElemType *)malloc(sizeof(ElemType)*LISTINITSIZE); //申请LISTINITSIZE大小的存储空间
if(!(L->elem)) //判定空间是否申请成功
{
return ERROR;
}
else
{
L->length=0;
L->listsize=LISTINITSIZE;
}
return OK;
}
2.顺序表的创建操作
(1)for循环将元素放入顺序表中
(2)将表长置为n,即创建元素的个数
int PutList(SeqList *L,ElemType n) //创建长度为n的线性表L
{
int i;
printf("请输入%d个元素:",n);
for(i=0;i<n;i++)
{
scanf("%d",&(L->elem[i])); //scanf("%d",L->elem+i); 这两语句等价
}
L->length=n;
return OK;
}
3.顺序表的打印操作
打印顺序表的存储空间大小,表长,以及表中的元素
void PrintList(SeqList L)
{
int i;
printf("顺序表的储存空间大小为:%d.\n",L.listsize);
printf("顺序表中共有元素 %d 个,各个元素是:\n",L.length);
for(i=0;i<=L.length-1;i++)
{
printf("%d\t",L.elem[i]); // printf("%d\t",*(L.elem+i)); 这两语句等价
}
4.顺序表的插入操作
(1).判断插入位置是否合法
(2).判断表是否已满
(3).为插入元素腾位置,即第i个元素(包括第i个元素)以后的元素向后走一步
(4).将插入元素放入插入位置并表长加1
int InsertElem(SeqList *L,int i,ElemType e) //在顺序表的第i个位置插入元素e
{
int j,newsize;
ElemType *newbase;
if(i<1||i>L->length+1) //判断插入位置是否合法
{
return ERROR;
}
if(L->length>=L->listsize) //表满则扩充存储空间
{
newsize=(L->listsize+LISTINCREAMENT)*sizeof(ElemType); //新的空间大小
newbase=(ElemType *)realloc(L->elem,newsize); // 以上二条语句等价于语句newbase=(ElemType *)realloc(L->elem,(L->listsize+LISTINCREAMENT)*sizeof(ElemType));
if(!(newbase))
{
return ERROR;
}
else
{
L->elem=newbase;
L->listsize+=LISTINCREAMENT;
}
}
for(j=L->length-1;j>=i-1;j--) //元素后移 ,为插入元素腾位置
{
L->elem[j+1]=L->elem[j];
}
L->elem[i-1]=e; //将插入元素放入到第i个位置,即在表中的下标为i-1
L->length++; //表长加1
return OK;
}
5.顺序表的删除操作
(1).判断删除位置
(2).带出元素
(3).其后剩余元素往前挪位置
(4).表长减1
int DeleteElem(SeqList *L,int i,ElemType *e) //将顺序表中的第i个元素删除,并用e带出来
{
int j;
if((i<=0)||(i>L->length)) //判断删除位置是否合法
{
return ERROR;
}
*e=L->elem[i-1]; //用e带出删除元素
for(j=i;j<=L->length-1;j++) //将第i个元素(不包括第i个元素)以后的每个元素从前往后依次前进一步
{
L->elem[j-1]=L->elem[j];
}
L->length--; //表长减1
return OK;
}
6.元素的定位
即在顺序表遍历过程中判断元素是否满足条件
int LocateElem(SeqList L,ElemType e) //返回元素e在顺序表中的位置
{
int i;
for(i=0;i<=L.length-1;i++) //遍历顺序表
{
if(L.elem[i]==e) //判断是否满足要求
{
return i+1; //返回位置,即下标加1
}
}
return ERROR; //否则表中没有找到此元素
}
7.顺序表中取某一位置上的元素
int GetElem(SeqList L,int i,ElemType *e) //将顺序表中的第i个元素用e带出来
{
if(i<1||i>L.length) //判断取元素位置是否合法
{
return ERROR;
}
*e=L.elem[i-1]; //将目标元素用e带出来
return OK;
}
8.求某元素的前驱
先定位该元素
int PriorElem(SeqList L,ElemType e,ElemType *pre_e) //求出顺序表L中元素e的前驱结点pre_e
{
int i;
for(i=L.length-1;i>=1;i--) //第一个元素无前驱 ,遍历过程不考虑第一个元素
{
if(e==L.elem[i])
{
*pre_e=L.elem[i-1]; //前驱结点为该结点的前一个元素,故减1
return OK;
}
}
return ERROR;
}
9.求某元素的后继
先定位该元素
int NextElem(SeqList L,ElemType e,ElemType *next_e) //求出顺序表L中第e个元素的后继结点next_e
{
int i;
for(i=0;i<L.length-1;i++) //最后一个元素无后继 ,无需考虑
{
if(e==L.elem[i])
{
*next_e=L.elem[i+1]; //后继结点为该结点的后一个结点,故加1
return OK;
}
}
return ERROR;
}
以上内容仅个人学习总结,如有错误请指正