[ 2020年7月6号]
一.线性表基本概念
1.基本概念
- 线性表(List):零个或多个数据元素的有限序列
- 性质①:第一个元素无前驱,最后一个元素无后继
- 性质②:线性表的长度都是有限的
- 性质③:在较复杂的线性表中,一个数据元素可以由若干个数据项组成,例如:
| 学号 | 姓名 | 性别 |
|---|---|---|
| 1 | CLAY | 男 |
| 2 | Codes | 男 |
| 3 | 1024 | 男 |
| … | … | … |
- 线性表的抽象数据类型如下
ADT List
DATA
......
Operation
InitList(&L): 初始化操作,建立一个空的线性表
ListEmpty(L): 若线性表为空,返回True,否则返回False
ClearList(&L): 清空线性表
GetElem(L, i, *e): 查找线性表中第i个位置的元素并将值返还给e
LocateElem(L, e): 在线性表中查找值为e的元素
ListInsert(&L, i, e): 在线性表L中第i个位置插入值为e的新元素
ListDelete(&L, i, *e): 删除线性表L中第i个位置的元素,并用e存储其值
ListLength(L): 返回线性表L的的元素个数
endADT
2.数组和线性表的关系
- 数组是物理结构,线性表是逻辑结构
- 数据是线性表顺序存储的结果
- 线性表不仅有顺序存储,还有链式存储两种物理结构
二.线性表的顺序存储结构
- 定义:指的是用一段地址连续的存储单元依次存储线性表的数据元素。
- 线性表顺序存储的结构代码
const int MAXSIZE = 20; //分配存储空间
typedef int ElemType;
typedef struct
{
/*注意:MAXSIZE是数组的最大长度,length是线性表的长度*/
ElemType *data; //数组存储数据元素
int length; //线性表当前长度
int size; //顺序表当前容量
}SqList;
-
地址计算方法:LOC(ai) = LOC(a1) + (n-1)*c
其中LOC表示获取存储位置的函数,c表示一个数据元素占用的存储单元的个数。 -
初始化操作
#define OK 1
#define ERROR 0
#define OVERFOLW -2
typedef int Status;
Status InitList(SqList &L)
{
L.data = new ElemType[MAXSIZE];//给动态数组分配空间
if(!L.data) exit(OVERFOLW);
L.length = 0;//置表长为0
L.size = MAXSIZE;
renturn OK;
}
- 获取元素操作
Status GetElem(SqList L,int i,ElemType *e)
{
if(L.length == 0 || i < 1 ||i > L.length) //异常处理
return ERROR;
*e = L.data[i-1]; //i从1开始算,但是数组从0开始算,所以第i个位置对应数组下标i-1
return OK;
}
- 插入操作
算法思路啊如下:
Status ListInsert(SqList &L,int i,ElemType e)
{
ElemType *base;
if(L.length == MAXSIZE)//异常处理
return ERROR;
if(i < 1 || i > L.length + 1)//异常处理
return ERROR;
if(L.length > L.size)//动态扩容
{
base = new ElemType;
L.data = base;
L.size += 1;
}
if(i <= L.length)//若插入的位置不在表尾
{
//在将要插入的位置后数据元素向后移动一位
for(int j = L.length - 1;j >= i-1;--j)
L.data[j+1] = L.data[j];
}
L.data[i-1] = e;//插入新元素
L.length++;//表长加一
return OK;
}
- 删除操作
算法思路啊如下:
Status ListDelete(SqList &L,int i,ElemType *e)
{
if(L.length == 0)//异常处理
return ERROR;
if(i < 1 || i > L.length)//异常处理
return ERROR;
*e = L.data[i-1];//取出数据
if(i < L.length)//如果删除的不是表尾数据
{
//将删除位置后继元素前移
for(int j = i;j < L.length;j++)
L.data[j-1] = L.data[j];
}
L.length--;
return OK;
}
- 求取表长
Status ListLength(SqList L)
{
return L.length;
}
- 查找操作
Status ListSearch(SqList L,int i)
{
if(i < 1 || i > MAXSIZE)//异常处理
return ERROR;
for(int j = 0;j < L.length;j++)//遍历循环顺序表中的元素
{
if(L.data[j] == i)
return (j+1);//若存在,返回数据元素在顺序表中的位置(从1开始算)
}
return 0;
}
三.线性表的链式存储结构
- 结点:由指针域和数据域组成

- 线性链表:n个结点链接成一个链表
- 单链表:链表中的每个结点都只含有一个指针域

- 头指针:链表中第一个结点存储的位置
- 头节点:在单链表的第一个结点前附设一个结点,不存储信息,存在的意义就是为了是空链表的插入删除和非空链表一致。

- 线性表的单链表存储结构代码
typedef struct Node
{
ElemType data;//数据域
struct Node *next;//指针域
}Node,*LinkList;//LinkList是指向结点的指针
- 单链表的初始化
Status InitList(LinkList &L)
{
L = new Node;
L->next = NULL;
return OK;
}
- 单链表的读取
算法思路啊如下:
Status GetElem(LinkList L.int i,ElemType *e)
{
int count = 1;//count为计数器
LinkList p;
p = L->next;//L表示的是头结点。L->next表示的才是第一个结点
while(p != NULL && count < i)
{
p = p -> next;
++count;
}
if(!p || count > i)//若第i个结点不存在
return ERROR;
*e = p -> data;
return OK;
}
- 单链表的插入

算法思路啊如下:
Status ListInsert(LinkList &L,int i,ElemType e)
{
int count = 1;
LinkList p,s;
p = L;
while(p != NULL && count < i)
{
p = p -> next;
++count;
}
if(!p || j > i)
return ERROR;
s = new Node;
s -> data = e;
s -> next = p -> next;
p -> next = s;
return OK;
}
- 单链表的删除操作
算法思路啊如下:
Status ListDelete(LinkList &L,int i,ElemType *e)
{
int count = 1;
LinkList p,s;
p = L;
while(p != NULL && count < i)
{
p = p -> next;
++count;
}
if(!(p->next) || count > i)
{
return ERROR;
}
q = p->next;
p->next = q->next;
*e = q->data;
delete q;
return OK;
}
- 单链表的整表创建
void CreateListHead(LinkList &L,int n)
{
ElemType elem
InitList(L);
/*我们可以把单链表的插入细致分为两种,一种是头插法,一种是尾插法*/
//头插法(并不推荐)
LinkList p;
for(int i = 0;i < n;i++)
{
std::cin>>L->data;
p->next = L->next;
L->next = p;
}
//头插法
LinkList p,r;
r = L;
for(int i = 0;i < n;i++)
{
p = new Node;
std::cin>>p->data;
r->next = p;
r = p;
}
r->next = NULL;
}
- 单链表的整表删除
Status ClearList(LinkList &L)
{
LinkList p,q;
p = L->next;
while(p)
{
q = p->next;
delete p;
p = q;
}
L-next = NULL;
return OK;
}
本人也在学习中,如果有什么错误,希望大家多多指教,互相学习!
本文深入讲解线性表的基本概念,包括其性质、顺序存储和链式存储结构。探讨了线性表的抽象数据类型,以及如何通过数组和链表实现线性表的存储。详细介绍了线性表的基本操作,如初始化、查找、插入、删除和求表长。
1549

被折叠的 条评论
为什么被折叠?



