最近进行数据结构的复习,并将重点的一些线性表的知识点用图的方式进行总结,以方便进行复习、查看。
在此做一个总结记录。后续会更新上算法程序部分。
1,线性表的知识结构图
1.1线性表定义
线性表是一个具有相同特性的数据元素的有限序列。
相同特性
:所有元素属于同一数据类型。
有限
:数据元素个数是有限的。
序列
:数据元素由逻辑序号唯一确定。一个线性表中可以有相同值的元素。
1.2 线性表的抽象数据类型定义、数学表示及含义
:
线性表ADT=逻辑结构(逻辑特性)+ 基本运算
1.3 线性表常用的基本运算;
1 初始化线性表InitList(&L):构造一个空的线性表L。【第一类】
2 销毁线性表DestroyList(&L):释放线性表L占用的内存空间。【第二类】
3 判线性表是否为空表ListEmpty(L):若L为空表,则返回真,否则返回假。
4 求线性表的长度ListLength(L):返回L中元素个数n。
5 输出线性表DispList(L):线性表L不为空时,顺序显示L中各结点的值域。
6 求线性表L中指定位置的某个数据元素GetElem(L,i,&e):用e返回L中第 i(1≤i≤n)个元素的值。
7 定位查找LocateElem(L,e):返回L中第一个值域与e相等的逻辑位序。若这样的元素不存在,则返回值为0。
8 插入一个数据元素ListInsert(&L,i,e):在L的第i(1≤i≤n)个元素之前插入新的元素e,L的长度增1。
9 删除数据元素ListDelete(&L,i,&e):删除L的第i(1≤i≤n)个元素,并用e返回其值,L的长度减1。【第四类】
1.4 线性表的顺序存储结构及基本运算的实现
线性表的顺序存储结构:把线性表中的所有元素按照顺序存储方法进行存储。按逻辑顺序依次存储到存储器中
一片连续的存储空间
中。
类型定义及常用运算:
typedef struct
{ ElemType data[MaxSize];
int length;
} SqList; //顺序表类型
void CreateList(SqList * &L,ElemType a[],int n) //*引用参数:将执行结果回传给实参
//整体建立顺序表
{ int i=0,k=0;
L=(SqList *)malloc(sizeof(SqList));//分配存放线性表的顺序表空间
while (i<n) //i扫描a中元素
{ L->data[k]=a[i];
k++; i++; //k记录插入到L中的元素个数
}
L->length=k;
}
//该运算返回L中第 i(1≤i≤ListLength(L))个元素的值,存放在e中。
bool GetElem(SqList *L,int i,ElemType &e)
{
if (i<1 || i>L->length) return false;
e=L->data[i-1];
return true;
}
//在顺序表L的第i(1≤i≤ListLength(L)+1)个位置上插入新的元素e。
bool ListInsert(SqList *&L,int i,ElemType e)
{ int j;
if (i<1 || i>L->length+1)
return false; //参数错误时返回false
i--; //将顺序表逻辑序号转化为物理序号
for (j=L->length;j>i;j--) //将data[i..n]元素后移一个位置
L->data[j]=L->data[j-1];
L->data[i]=e; //插入元素e
L->length++; //顺序表长度增1
return true; //成功插入返回true
}
1.5 线性表的链式存储结构及基本运算的实现
设计链式存储结构时,每个逻辑结点存储单独存储,为了表示逻辑关系,增加
指针域
。
每个物理结点增加一个指向后继结点的指针域 —>单链表。
每个物理结点增加一个指向后继结点的指针域和一个指向前驱结点的指针域—>双链表。
单链表中结点类型LinkNode的定义如下:
typedef struct LNode //定义单链表结点类型
{ ElemType data;
struct LNode *next; //指向后继结点
} LinkNode;
2.单链表
单链表
特点
:当访问过一个结点后,只能接着访问它的后继结点,而无法访问它的前驱结点。
2.1 单链表插入操作
将值为x的新结点插入到p结点之后。
特点:只需修改相关结点的指针域,不需要移动结点。
2.2 单链表删除操作
删除操作:删除p结点之后的一个结点。
特点:只需要修改相关结点的指针域,不需要移动结点。
2.3 单链表初始化操作、输出线性表操作:
//初始化线性表,建立一个空的单链表,即创建一个头结点
void InitList(LinkNode *&L)
{
L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next=NULL;
}
//输出线性表,逐一扫描单链表每个数据域,并显示各结点的data域值
void DispList(LinkNode *L)
{
LinkNode *p=L->next; //p指向开始结点
while (p!=NULL) //p不为NULL,输出p结点的data域
{ printf("%d ",p->data);
p=p->next; //p移向下一个结点
}
printf("\n");
}
3,双链表
双链表因为每个结点有指向前、后相邻结点的指针域,导致:通常情况下,存储密度低于单链表。
优点
:从任一结点出发可以快速找到其前驱结点和后继结点;从任一结点出发可以访问其他结点。
缺点
:通常存储密度低于单链表。
初始化结点类型:
typedef struct DNode //双链表结点类型
{ ElemType data;
struct DNode *prior; //指向前驱结点
struct DNode *next; //指向后继结点
} DLinkNode;
3.1双链表插入
3.2双链表删除
4. 循环链表
4.1循环单链表
:
将表中尾结点的指针域改为指向表头结点,整个链表形成一个环。由此从表中任一结点出发均可找到链表中其他结点。 可以
循环查找
。
4.2 循环双链表
:形成两个环。
特点
:可以循环查找;可以
通过头结点快速找到尾结点
。
4.3 与非循环双链表相比,循环双链表
:1,链表中没有空指针域;2,p所指结点为尾结点的条件:p->next==L;3,一步操作即L->prior可以找到尾结点
5.有序表
所谓有序表,是指这样的线性表,其中所有元素以
递增
或递减方式有序排列。
有序表属于线性表,有序表是从
逻辑结构
来说与线性表相同;从
存储结构
来说,有序表包含顺序存储结构的顺序表和链式存储结构的链表。
6.考试要求
了解
线性表的
逻辑结构
和常用的一些运算,
掌握
线性表的两种存储结构及其用法,
掌握
这两种存储结构各自的优缺点。
比较,各自优缺点:
顺序表:
优点
:1,存储密度大:无须为表示线性表中元素之间的逻辑关系而增加额外的存储空间。2,具有随机存取特性。
缺点
:1,插入和删除操作需要移动大量元素。2,初始空间大小分配难以掌握。
链表:
优点
:1,由于采用结点的动态分配方式,具有良好的适应性。2,插入和删除操作只需修改相关指针域,不需要移动元素。
缺点
:1,存储密度小:为表示线性表中元素之间的逻辑关系而需要增加额外的存储空间(指针域)。2,不具有随机存取特性。
注意:顺序表——―用数组表示 —–>借鉴数组处理方法(存、取元素)
顺序表——―不同于数组—–> 顺序表是线性表的一种存储结构
在
算法实现
方面要求,能够根据实际问题的需求来决定采用何种存储结构并给出具体的算法,如:
插入、删除
满足条件的链表节点,在链表上排序等。