说明:严蔚敏的《数据结构》(C语言版)学习笔记,记录一下,以备后面查看。
ElemType *elem记录第一个元素的地址,也就是数组的首地址(基地址)
int length 是实际数组中数据的长度
int listsize 是给数组分配的空间长度
#include <stdio.h> #include <malloc.h> #include <stdlib.h> #define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量 #define LISTINCREMENT 10 //线性表存储空间的分配增量 const int OK = 1; //定义正确返回 const int ERROR = -1; //定义错误的返回 const int OVERFLOW = -2; //定义溢出 //定义元素类型 typedef int ElemType; //定义返回类型 typedef int Status; //定义一个线性的数组结构 typedef struct{ ElemType *elem; int length; int listsize; } SqList; //初始化列表 Status InitList_Sq(SqList &L){ //构造一个空的线性表L L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if(!L.elem) exit(OVERFLOW); //存储分配失败 L.length = 0; //实际元素长度是0 L.listsize = LIST_INIT_SIZE;//分配的长度(字节) return OK; } //插入元素 //插入数组中下标为i的位置 Status ListInsert_Sq(SqList &L, int i, ElemType e){ ElemType *newbase; //在顺序线性表L中第i个位置之前插入新的元素e if(i<1 || i>L.length+1) return ERROR; //i 值不合法 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; //增加存储容量 } ElemType *q = &(L.elem[i - 1]); //取到数组中第i个元素的地址赋给指针q ElemType *p; //从i+1元素位置开始向后移动元素 for(p = &(L.elem[L.length - 1]); p>=q; --p) *(p+1) = *p; *q = e; ++L.length; return OK; } //添加元素 Status ListAdd_tail(SqList &L, ElemType e){ ElemType *newbase; 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; } L.elem[L.length] = e; ++L.length; return OK; } //删除元素 ElemType ListRemove_Sq(SqList &L, int i){ if(i<0 || i>=L.length) return ERROR; ElemType *p; //将第i个元素后面的所有元素向前移动一位 for(p = &(L.elem[i]); p<&(L.elem[L.length - 1]); ++p) *p = *(p+1); --L.length; return OK; } //遍历元素 void showList(const SqList &L){ int i; for(i=0; i<L.length; i++){ printf("%d ", L.elem[i]); } } int main(){ SqList sq; InitList_Sq(sq); ElemType et1 = 3; ElemType et2 = 4; ListInsert_Sq(sq,1,et1); ListInsert_Sq(sq,2,et2); ListAdd_tail(sq, et1); ListAdd_tail(sq, et1); ListAdd_tail(sq, et1); ListAdd_tail(sq, et2); ListRemove_Sq(sq, 1); showList(sq); scanf("%d"); return 0; }
值得思考的问题:
1、为什么传引用?
2、什么时候应该什么成const?
3、结构体的初始化
4、静态存储区和动态存储区的特点和区别