数据结构笔记(一)——线性表
线性表就是一个一维的表,其中各个元素之间是一对一的。
对线性表的定义:
ADT 线性表(list)
Data
线性表的数据对象集合{a1,a2,……,an},每个元素的类型均为DataType。其中,出来第一个元素a1外,每一个元素有且只有一个直接前驱元素,出来最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation
InitList(*L): 初始化操作,建立一个空的线性表L。
ListEmpty(L): 若线性表为空,返回true,否则返回false。
ClearList(*L): 将线性表清空。
GetElem(L,i,*e): 将线性表L中的第i个元素返回给e。
LocateElem(L,e): 在线性表L中查找与给定值e相等的元素,如果找到了这个元素则返回此元素的位
置,否则返回0表示失败。
ListInsert(*L,i,e): 在线性表L的第i个位置插入元素e。
ListDelete(*L,i,*e): 删除线性表L中的第i个元素,使用e作为返回值。
ListLength(L): 返回线性表L的长度。
写完了一个线性表,那么如果要做两个线性表元素的并集则可用如下代码实现:
void unionL(List *La,List*Lb)
{
int La_len,Lb_len,i;
ElemType e; //声明La和Lb相同的数据元素e
La_len = ListLength(*La); //获得线性表的长度
Lb_len = ListLength(*Lb);
for(i=1;i<=Lb_len;i++)
{
GetElem(Lb,i,&e); //取出Lb中的第i个元素赋值给e
if(!LocateElem(*La,e)) //La中不存在和e相同的数据元素
ListInsert(La,++la_len,e); //插入到La的尾部
}
}
线性表有两种存储结构,一是顺序存储,二是链式存储。其中顺序存储可以用C语言中的一维数组来实现。其中需要注意的是估算最大存储容量,建立一个数组,此容量不能超过总存储空间的最大存储容量,还需要注意建立这个数组的起始存储空间,而这个数组的最大存储容量自然不能超过从此位置到中存储空间末尾的空间。
下为顺序存储的结构代码:
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length;
}SqList;
顺序存储结构的插入与删除
#define OK 1
#define ERROR 0
#difine TRUE 1
#define FALSE 0
typedef int Status;
//初始条件:顺序线性表L存在,1<=i<=ListLength(L)
//操作结果:用e返回L中第i个数据元素的值
Status GetElem(Sqlist L,int i,ElemType *e)
{
if(L.length==0||i<1||i>L.length)
return ERROR;
*e=L.data[i-1];
return OK;
}
插入操作:
//初始条件:顺序线性表L已经存在,1<i<ListLength(L)
//操作结果:在L中的第i个位置之前插入新的数据元素e,L的长度+1
Status ListInsert(SqList *L,int i,ElemType e)
{
int k;
if(L->length==MAXSIZE)
return ERROR;
if(i<1||i>L->length)
return ERROR;
if(i<L->length)
{
for(k=L->length-1;k>=i-1;k--)
L->data[k+1]=L->data[k];
}
L->data[i-1]=e;
L->length++;
return OK;
}
删除操作:
//操作结果:删除L的第i个数据元素,并用e做返回值,L的长度减1。
Status ListDelete(SqList *L,int i,ElemType *e)
{
int k;
if(L->length==0)
return ERROR;
if(i<1||i>L->length)
return ERROR;
*e=L->data[i-1];
if(i<L->length)
{
for(k=i;k<L->length;k++)
L->data[k-1]=L->data[k];
}
l->length--;
return OK;
}
现在开始线性表的链式存储
//线性表的单链表存储结构
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
插入操作:
//操作结果:在L中第i个节点位置之前插入新的数据元素e,L的长度加1
Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,s;
p = *L;
j = 1;
while(p && j < i)
{
p = p->next;
++j;
}
if(!p || j > i)
return ERROR;
s = (LinkList)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
删除操作:
//操作结果:删除Ld第ige结点,并用e作为返回值,L的长度减1.
Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,q;
p = *L;
j = 1;
while(p->next && j<i) //寻找第i-1个结点
{
p = p->next;
++j;
}
if(!(p->next) || j>i)
return ERROR;
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return OK;
}
线性表中还包含有静态链表、双向链表、循环链表等,有了上述基础,实现比较简单,此处不加赘述。