线性表
一、线性表的类型定义
线性表:最常用的一种数据结构。
数据项:在复杂的线性表之中,一个数据元素可以由若干个数据项组成
记录:常用元素称为记录
文件:含有大量记录的线性表
二、线性表的顺序表示和实现
线性表的顺序:用一组地址连续的存储单元依次存储单元依次存储线性表的数据元素
它们有以下关系:l(为存储单元)
一般来说,线性表的第 i 个数据元素的 的存储位置为:
随机存储:只要确定了存储线性表的起始位置,线性表中任意一数据元素都可随机存储
重点一:线性表的动态分配顺序存储结构 P22
#include <stdio.h>
#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
#define LISTINCREMENT 10 // 线性表存储空间的分配增量
//设置表的基础属性:
typedef struct {
ElemType* elem; //存储空间头地址
int length; //当前长度
int listsize; // 当前分配的存储容量(以sizeof(ElemType))为单位
}; SqList;
重点二:线性表插入元素操作:
Status ListInstert_Sq(SqList& L, int i, ElemType e){
//插入一个元素会对表内进行改变,这个时候需要用&
//第一个为引用表,向L里写入,第二个是要插入的值的类型,第三个是插入的值
//插入一个值的时候先考虑插入值i的合法性:i应该大于1且小于length所以先对i的值进行一个判定
if (i < 1 || i > L.lenth + 1) return ERROR;
//判定之后再考虑第二种情况:如果这个表是满的怎么办?就要新开一个房间供他插入
if (L.lenth >= L.listsize) {
newbase = (ElemType*)realloc(L.elem, //新建的表的首地址
(L.listsize + LISTINCREMENT) * sizeof(ElemType));
//增加房间的时候realloc为新建命令 长度为(L.listsize + LISTINCREMENT)也就是原来的的表长加上要新建的表长然后乘以他的内存字节
if (!newbase) exit(OVERFLOW);//和上面建立新表一样,判断新建表是否为空
L.elem = newbase; //新的首地址
L.listsize += LISTINCREMENT; //增加存储容量
}
//以上操作都完成时,我们就可以正常插入元素了
q = &(L.elem[i - 1];//q 为插入位置
for (p = &(L.elem[L.lengh - 1]); p >= q; --p) *(p + 1) = *p;
//p赋初值为链表的最后一个元素地址,p>=q表示循环直到p<q的时候结束,--p是使p指针的指向往前移一位
*q = e; //插入e
++ L.lenghth;//表长加1
return OK;
}//ListInsert_Sq
重点三:删除元素操作
Status ListInstert_Sq(SqList &L, int i, ElemType &e) {
//在顺序表L中删除第i个元素,并用e返回值
//接下来我们还是要考虑数据的合法性,关于删除元素i的值的判定
if ((i < 1) || (i > L.lengh))return ERROR;
p = &(L.elem[i - 1]);
e = *p;//删除的值赋给e
q = L.elem + L.length - 1;//表尾元素位置
for (++p; p <= q; ++p)*(p - 1) = *p;
--L.lengh;//表长减一
return OK;
}//ListInsert_Sq
三、线性表链式表示和实现
数据域:存储数据元素信息的域
指针域:存储直接后继的存储位置的域
重点一:单链表的存储结构
typedef struct LNode{
Elemtype data; //线性表的存储:第一个存当前元素的值
struct LNode *next;//第二个存下一个元素的位置(关系)也就是指针
}LNode,*LinkList;
重点二:单链表的插入
Status ListInsert_L(LinkList &L,int i,Elemtype e){
//这里明确一下:第一个是表示对L这个表进行操作,因为会对这个表的值产生影响,所以要加&,第二个是你要插的值,类型是int,第三个是插入你找的元素e
p = L; j = 0;
while (p && j <i-1){p = p->next;++j;} //寻找第i个结点
if(!p|| j>i-1) return ERROR;//这里为判断插入的时候为空的条件如果你要插入之后超出了表长或者没有找到要插入的那个位置,那么就为空。
s=(LinkList)malloc(sizeof (LNode));//这个时候我们就需要给它新增房间供它使用
s->data =e ;s->next = p->next;//当我们插入之后,我们需要将插入的这个位置的值改成插入后的值所以有
s->data.
p->next=s;//变为插入的值e 这个时候插入的位置的后继发生变化,需要更改,将p->next指向s
return OK;
}//ListInsert_L
重点三:单链表的删除
Status ListDelete_L(LinkList &L,int i ,ElemType &e){
//这里的e为返回值,因为这个值是删除的值,对表有影响,所以加&
P = L;j = 0;
while(p->next && j< i-1){ //寻找第i个结点,并令p指向前驱
p=p->next;++j;
}
if (!(p->next)||j>i-1)return ERROR;//如果删除的位置不存在或者不合理
q = p-next; p->next = q->next;
e=q->data; free (q)
//删除并释放,这时因为已经删除了,所以应该把前一个的后继和后一个前驱更改
return OK;
}//ListDelete_L