一个小目录
《数据结构》(C语言版)ch2 线性表学习笔记
数组篇
1.malloc()
https://blog.csdn.net/flowing_wind/article/details/81240910
malloc()分配内存后不初始化
分配成功:
若分配成功,其返回类型是void ,表示未确定类型的指针,c,c++规定void可以强转为任何其他类型的指针,关于void还有一种说法就是其他任何类型都可以直接赋值给它,无需进行强转,但是反过来不可以
其返回指向被分配内存空间的指针,即指向一段可用内存的起始地址
分配失败
https://blog.csdn.net/qq_31847339/article/details/81281841
内存不足分配失败则返回NULL ,程序使用malloc时可以借此进行判断是否分配成功
malloc后一定要free()
https://www.runoob.com/cprogramming/c-function-free.html
2.线性表宏定义
typedef int Status;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFAEASIBLE -1
#define OVERFLOW -2
数组
#define LIST_INIT_SIZE 100//线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef int ElemType;
typedef struct
{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位
} SqList;
3.init初始化与以前静态数组初始化区别
Status InitList(SqList *L){ //初始化线性表InitList(&L) 构造空表
L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)) ;
if(!L.elem)exit(OVERFLOW); //存储分配失败
L.length=0;
L.listsize=LIST_INIT_SIZE; //初始存储容量
return OK;
}
静态数组:长度固定,尽可能的长分配
init初始化,通过malloc动态分配数组,方便realloc修改数组空间分配大小
区别:结构不同
init优点:动态分配空间,避免空间浪费;L.length直接存储获取长度信息,牺牲少量空间,换取时间;L.listsize可以记录动态分配的内存空间
4.函数作为参数
C 语言规定函数名会被转换为指向这个函数的指针,除非这个函数名作为 & 操作符或 sizeof 操作符的操作数(注意:函数名用于 sizeof 的操作数是非法的)。也就是说 f = test; 中 test 被自动转换为 &test,而 f = &test; 中已经显示使用了 &test,所以 test 就不会再发生转换了。因此直接引用函数名等效于在函数名上应用 & 运算符,两种方法都会得到指向该函数的指针。
https://www.runoob.com/cprogramming/c-passing-pointers-to-functions.html
5.线性表查找_顺序存储
int LocateElem(SqList L, ElemType e,Status (*compare)(ElemType,ElemType)){ //按元素值查找LocateElem(L,e,compare),查找第一个值与e满足compare()关系的元素的位序
int i=1;
ElemType *p=L.elem;
while(i<=L.length&&!(*compare)(*p++,e)) ++i;
//*p++指先将*p与e比较后,p++ ,当找到第一次满足关系或者一直到数组末尾时候循环结束
if(i<=L.length) return i;
else return 0;
}
Status equal(ElemType a,ElemType b); {
//判断两元素是否满足相关关系
if(a==b)
return TRUE;
else
return FALSE;
}
6.线性表插入_顺序存储
C语言中数组下标从“0”开始,若L是SqList类型线性表,表中第i个元素是L.elem[i-1]
顺序存储中,物理位置上与逻辑位置相符,因此有插入有两种情况:
线性表末尾:i=n+1(n=L.length),可以直接插入
i != n-1 ,需要移动元素,移动恰为顺序存储最多耗时区域
脑筋急转弯:
插入到第5个位置(顺序表长度为8),其插入位置的下标为4,需将第5至8的元素后移,移动下标为4-7的元素。
一般情况下,在第i(1≤ i ≤ n)个元素之前插入一个元素时,需要将第n至第i(共n-i+1)个元素后移
Status ListInsert(SqList *L,int i,ElemType e){ //插入数据元素ListInsert(&L,i,e)
ElemType *p,*q,*newbase;
//判断i的合法性
if(i<1||i>ListLength(*L)+1) return ERROR
//存储空间是否已满
if(L.length>=L.listsize){ //若已满,增加内存
newbase = (ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType)) ;
if(!newbase)exit(OVERFLOW);//存储分配失败
L.elem=newbase
}
L.listsize += LISTINCREMENT;//增加存储容量
q=&(L.elem[i-1]); //插入位置
for(p = &(L.elem[L.length-1]);p>=q;--p) //q位置元素有被移动,--p先减后使用,此处无影响
*(p+1)=*p;
*q=e;
++L.length;
return OK;
}
7.realloc
该函数返回一个指针 ,指向重新分配大小的内存。如果请求失败,则返回 NULL。
void *realloc(void *ptr, size_t size)
https://www.runoob.com/cprogramming/c-function-realloc.html
8.线性表删除_顺序存储
长度-1;
删除第i(1≤ i ≤ n)个元素,需将从第i+1至第n(共n-i)个元素依次前移,元素下标为第i 至 n-1
Status ListDelete(SqList *L,int i,ElemType *e){ //删除数据元素ListDelete(&L,i,&e)
ElemType *p,*q,*newbase;
//检查i的合法性
if(i<1||i>ListLength(*L)) return ERROR;
p=&(L.elem[i-1]); //删除元素的位置
e=*p;
q=&L.elem[length-1];
for(++p;p<=q;++p){
*(p-1)=*p;
}
--L.length;
return OK;
}