算法与数据结构-2.线性表
2.1 线性表的定义与特点
由n(n≥0)个数据特性相同的元素构成的有限序列称为线性表。
线性表中元素的个数n定义为线性表的长度,n=0时为空表。
查找直接后继结点的执行时间为O(1),查找直接前驱的执行时间为O(n)。
特点:
(1)存在唯一的一个被称为“第一个”的数据元素。
(2)存在唯一的一个被称为“最后一个”的数据元素。
(3)除第一个之外,结构中的每个数据元素均只有一个前驱。
(4)除最后一个之外,结构中的每个数据元素均只有一个后继。
2.2 线性表的顺序表示和实现
逻辑上相邻的数据元素,其物理次序也是相邻的。
线性表中任一数据元素都可随机存取。
2.3 线性表的链式表示和实现
单链表
头指针→(头结点→)首元结点。
首元结点是指链表中存储第一个数据元素的结点。
头结点指向首元结点,头结点可以不存储信息或存储与数据元素类型相同的其他附加信息。作用:便于首元结点的处理,便于空表和非空表的统一处理。
- 初始化
void init(LinkList &l){
l=new Lnode;
l->next=NULL;
}
- 前插法创建(按输入逆序创建
void createHead(LinkList &l,int n){
Lnode *t;
l=new Lnode;
l->next=NULL;
for(int i=0;i<n;i++){
t=new Lnode;
cin>>t->data;
t->next=l->next;
l->next=t;
}
}
- 后插法创建(按输入正序创建
void createHou(LinkList &l,int n){
Lnode *p,*t;
p=new Lnode;
p->next=NULL;
p=l;
for(int i=0;i<n;i++){
t=new Lnode;
cin>>t->data;
t->next=NULL;
p->next=t;
p=t;
}
}
循环链表
表中最后一个结点的指针域指向头结点,整个链表形成一个环。
从表中任一点出发均可找到表中其他结点。
判定表尾结点的终止条件: p!=L 或p->next!=L
双向链表
结点中有两个指针域,一个指向直接前驱,一个指向直接后继。
typedef struct DuLnode{
int data;
struct DuLnode *prior,*next;
}DuLnode,*DuLinkList;
若d为指向表中某一结点的指针,则有d->next->prior=d->prior->next=d
以下转载至:双向链表的插入及删除图解 (侵权删)
双向链表的插入
第一步:首先找到插入位置,节点 s 将插入到节点 p 之前
第二步:将节点 s 的前驱指向节点 p 的前驱,即 s->prior = p->prior;
第三步:将节点 p 的前驱的后继指向节点 s 即 p->prior->next = s;
第四步:将节点 s 的后继指向节点 p 即 s->next = p;
第五步:将节点 p 的前驱指向节点 s 即 p->prior = s;
双向链表的删除
第一步:找到即将被删除的节点 p
第二步:将 p 的前驱的后继指向 p 的后继,即 p->prior->next = p->next;
第三步:将 p 的后继的前驱指向 p 的前驱,即 p->next->prior = p->prior;
第四步:删除节点 p 即 delete p;
2.4 顺序表和链表的比较
空间性能的比较
(1)存储空间的分配
顺序表的存储空间必须预先分配,而链表不需要。
(2)存储密度的大小
存储密度,在计算机中是指结点数据本身所占的存储量和整个结点结构所占的存储量之比。
存储密度 = (结点数据本身所占的存储量)/(结点结构所占的存储总量)
存储密度越大,存储空间的利用率就越高。
顺序表的存储密度为1,链表的存储密度小于1。
时间性能的比较
(1)存取元素的效率
顺序表为O(1),链表为O(n)
(2)插入和删除操作的效率
顺序表为O(n),链表为O(1)
※上机操作!!!
#include<iostream>
using namespace std;
typedef struct Lnode{
int data;
struct Lnode *next;
}Lnode,*LinkList;
单链表相关
初始化
void init(LinkList &L){
L=new Lnode;
L->next=NULL;
}
创建单链表
void create(LinkList &L,int n){
Lnode *t,*p;
t=L;
int x,i;
for(i=0;i<n;i++){
p=new Lnode;
p->next=NULL;
cin>>x;
p->data=x;
t->next=p;
t=p;
}
}
打印单链表
void print(LinkList L){
Lnode *q=L->next;
while(q){
if(q->next==NULL)
cout<<q->data;
else
cout<<q->data<<" ";
q=q->next;
}
}
单链表按位查找
int findAsNum(LinkList &l,int i,int n){
Lnode *p=l->next;
int num=1;
while(p){
if(num==i){
return 1;
}
num++;
p=p->next;
}
if(i>n||i<=0)
return 0;
}
单链表按值查找
int findAsX(LinkList l,int n,char x){
Lnode *p;
p=l->next;
int num=1;
while(p){
if(p->data==x){
cout<<num<<endl;
return 1;
}
num++;
p=p->next;
}
return 0;
}
单链表按位插入
int insertAsNum