数据结构之线性表
1. 线性表相关概念
定义:表示0个或者多个数据元素的线性序列。
可以是一个数字,一个字母或者一些数据项。
举例字母表,学生信息表。
有顺序存储结构和链式存储结构。
2. 线性表顺序存储结构
逻辑结构,存储结构,运算。
相关概念:使用连续的存储空间,按照数据元素在线性表里面的徐海依次存储数据元素。
采用顺序存储元素的表叫做线性表。
计算地址:如果第一个存储地址是loc(a0),每个元素占用k个存储单元,那么线性表里面ai的存储地址是:loc(ai) = loc(a0)+k*i
我们只需要通过loc(a0)和k,就可以知道任意一个元素的存储地址。这就是顺序表的随机存取。
我们可以采用一维数组表示顺序表的顺序存储结构。
顺序表的插入运算。
#include<stdio.h>
Status Insert(int *a,int maxLen,int index,int n,int x){
int i;
if(index<0 || index >maxLen || index>n) return ERROR;
for(i=n-1;i>index;i--){
a[i+1]=a[i];
}
a[i+1]=x;
maxLen += 1;
return OK;
}
删除运算
看看要删除元素是不是在里面
#include<stdio.h>
Status Delete(int *a,int maxLen,int idex,int n,int x){
if(index<0||index>maxLen-1||index>n)
return ERROR;
for(i = index+1;i<n;i++){
a[i-1]=a[i];
}
maxLen--;
return OK;
}
3. 线性表的链接存储
基本概念:顺序结构优点:随机存取,存储空间利用率高;
缺点:插入、删除效率低,必须按照事先分配的空间大小进行估计,难以临时扩大。
链表:链式存储的线性表,有单链表,双链表,循环链表。
单链表:不仅有数据域(存储数据),还有指针域(存储地址)。
first是头节点,指向链表的第一个节点。不能出现断链现象。我们要保护后继节点的域。
struct node{
ElemType element;//数据域
struct node *link;;//指针域
}Node;
struct singleList{
struct node *first;//头节点
int n;
}singleList;
插入运算:打五星
功能:在ai插入x
算法步骤:先生成一个新的结点,q指向新的节点,
从头节点开始,找到ai所在结点,p指向该节点;
把q插在p之后。
插入以后i=-1,在a0以前,i>-1,在中间位置,表长加一。
q->link = p->link;
p->link = q;
语句不能交换,否则会断链。
插入算法具体实现:
删除运算:
我们想要删除节点ai,我们不能直接释放ai,我们会把ai和ai+1同时删除。
步骤,我们先查找ai-1节点,我们用p指针指向它,q指向该前驱节点。i是0就删除头节点。
代码块如下:
q->link = p->link;
带表头结点的线性表:
我们把表头设置为空,就不用进行分情况讨论了。
单循环线性表:头尾相接的单链表,也可以增加头节点。
结构定义如下:
插入运算:在p所指向的节点以前插入值为x的节点。
核心步骤:
q->llink = p->llink;
q->rlink = p;
p_>llink->rlink = q;
p->llink = q;
删除运算:删除p指向节点:
p->llink->rlink = p->rlink;
p->rlink->llink = p->llink;
free p
k = p;
p_>llink->rlink = q;
p->llink = q;
删除运算:删除p指向节点:
p->llink->rlink = p->rlink;
p->rlink->llink = p->llink;
free p
## 4. 循环链表
从表上一个节点出发可以回到这个节点的链表。
双向链表也有这样的功能。
单链表为空的条件:first=NULL
尾节点为空,node->link = NULL
链表失去了随机查找的功能,不能随机存储,所以只能从头节点开始进行查找。