单链表中按位置查找
查找算法:
1.工作指针P初始化,计数器初始化
2.执行下列操作,直到p为空或指向第i个节点,工作指针后移,计数器增1
3.若p为空,则第i个元素不存在,抛出位置异常;否则查找成功,返回节点p的数据元素
具体实现:
template
T LinkList::Get(int i) {
Node *p; int j;
p=first->next; j=1; //或p=first; j=0;
while (p && j<i) {
p=p->next; //工作指针p后移
j++;
}
if (!p) throw “位置”;
else return p->data;
}
单链表的插入操作(按位置进行插入)
算法描述:
1.工作指针p初始化,计数器初始化
2.查找第i-1个节点,并使工作指针p指向该节点
3.若查找不成功(P==NULL),说明位置错误,抛出位置异常,否则:生成一个元素值为x的新节点s,并将s插入到p之后
具体实现:
template
void LinkList::Insert(int i, T x){
Node *p; int j;
p=first ; j=0; //工作指针p初始化
while (p && j<i-1) {
p=p->next; //工作指针p后移
j++;
}
if (!p) throw “位置”;
else {
Node *s;
s=new Node;
s->data=x; //向内存申请一个结点s,其数据域为x
s->next=p->next; //将结点s插入到结点p之后
p->next=s;
}
}
单链表的删除操作:
template
T LinkList::Delete(int i){
Node *p; int j;
p=first ; j=0; //工作指针p初始化
while (p && j<i-1) { //查找第i-1个结点
p=p->next;
j++;
}
if (!p || !p->next) throw “位置”; //结点p不存在或结点p的后继结点不存在
else {
Node *q; T x;
q=p->next; x=q->data; //暂存被删结点
p->next=q->next; //摘链
delete q;
return x;
}
}
析构函数://带头结点的
template
LinkList:: ~LinkList()
{
Node *q;
while (first)
{
q=first->next;
delete first;
first=q;
}
}
顺序表和单链表的比较:
用顺序表:
若线性表的操作主要是进行查找,很少做插入和删除时,宜采用顺序表做存储结构
用单链表:
因此,对于频繁进行插入和删除的线性表, 宜采用链表做存储结构。
循环链表
将单链表或者双链表的头尾结点链接起来,就是一个循环链表。
不增加额外存储花销,却给不少操作带来了方便
从循环表中任一结点出发,都能访问到表中其他结点。
特点:
判断循环链表中尾结点:
q->next==first
建造空表:
template
CycleLinkList:: CycleLinkList( )
{
first=new Node; first->next=first;
}
尾插法建造:
template
CycleLinkList:: CycleLinkList(T a[ ], int n) {
first=new Node; //生成头结点
Node *r,*s;
r=first; //尾指针初始化
for (int i=0; i<n; i++) {
s=new Node;
s->data=a[i];
r->next=s;
r=s;
}
r->next=first; //单链表建立完毕,将终端结点的指针域指向头结点
}
头插法建造:
template
CycleLinkList:: CycleLinkList(T a[ ], int n,int k)
{
first=new Node; //生成头结点
first->next=first;
Node *s;
for (int i=1; i<n; i++)
{
s=new Node;
s->data=a[i]; //为每个数组元素建立一个结点
s->next=first->next;
first->next=s;
}
}
改造成循环的:
p=first;
while(p->next)
{
p=p->next;
}
p->next=first