线性表
定义参考线性表(1)
双向链表
为克服单链表这种单向性的缺点,可利用双向链表(Double Linked List).
双向链表:有两个指针域,一个指向直接后继,另一个指向直接前驱。
存储结构:
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode, *DuLinkList;
算法描述:
- 插入
Status ListInsert_DuL(DuLinkList &L, int i, ElemType e)
{
if(!(p = GetElemP_DuL(L, i)))
return ERROR;
if(!(s = (DuLinkList)malloc(sizeof(DuLNode)))) return ERROR;
s->data = e;
s->prior = p->prior; p->prior->next = s;
s->next = p; p->prior = s;
return OK;
}
- 删除
Status ListDelete_DuL(DuLinkList &L, int i)
{
if(!(p = GetElemP_DuL(L, i)))
return ERROR;
e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
}
附
由于链表在空间的合理利用上和插入、删除不需要移动等的优点,因此在很多场合下,它是线性表的首选存储结构。然而,它也存在着实现某些基本操作,如求线性表的长度时不如顺序存储结构的缺点;另一方面,由于在链表中,结点之间的关系用指针来表示,则数据元素在线性表中的“位序”的概念已淡化,而被数据元素在线性链表中的“位置”所代替。为此,从实际应用角度出发重新定义线性表及其基本操作
typedef struct LNode {
ElemType data;
struct LNode *next;
}*Link, *Position;
typedef struct {
Link head, tail;
int len;
}
Status ListInsert_L(LinkList &L, int i, ElemType e) {
if(!LocatePos(L, i-1, h)) return ERROR;
if(!MakeNode(s, e)) return ERROR;
InsFirst(h, s);
return OK;
}
Status MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc, int (*compare)(ElemType, ElemType)) {
// 已知单链线性表La和Lb的元素
if(!InitList(Lc)) return ERROR;
ha = GetHead(La); hb = GetHead(Lb);
pa = NextPos(La, ha); pb = NextPos(Lb, hb);
while(pa && pb) {
a = GetCurElem(pa); b = GetCurElem(pb);
if((*compare)(a, b) <= 0) {
DelFirst(ha, q); Append(Lc, q); pa = NextPos(La, ha);
else
DelFirst(hb, q); Append(Lc, q); pb = NextPos(Lb, hb);
}
if(pa) Append(Lc, pa);
else Append(Lc, pb);
FreeNode(ha); FreeNode(hb);
return OK;