一、单链表基本操作
1、定义单链表结点类型
#define elemType char
struct LinkNode
{
elemType data;
LinkNode *next; //指向后继结点
};
2、创建单链表
- 头插法建表:创建头结点,新结点插入到当前链表的表头。
void CreateListF(LinkNode *&L, elemType a[], int n)
{
L = new LinkNode;
L->next = nullptr; //创建头结点,其next域置为NULL
for (int i = 0;i < n;i++) //循环建立数据结点
{
LinkNode * s = new LinkNode;
s->data = a[i]; //创建数据结点*s
s->next = L->next; //将*s插在原开始结点之前,头结点之后
L->next = s;
}
}
- 尾插法建表:创建头结点,新结点插入到当前链表的表尾。
void CreateListR(LinkNode *&L,elemType a[],int n)
{
L = new LinkNode; //创建头结点
LinkNode * r = L; //r始终指向尾结点,开始时指向头结点
for (int i = 0;i < n;i++) //循环建立数据结点
{
LinkNode * s = new LinkNode;
s->data = a[i]; //创建数据结点*s
r->next = s; //将*s插入*r之后
r = s;
}
r->next = nullptr; //尾结点next域置为NULL
}
3、销毁线性表
void DestroyList(LinkNode *&L)//参数为头结点
{
LinkNode * p = L->next;
LinkNode * pre = L;//pre指向*p的前驱结点
while (p) //扫描单链表L
{
delete pre;
pre = p;
p = pre->next;
}
delete pre; //循环结束时,p为NULL,pre指向尾结点,释放它
}
4、获取长度
int ListLength(LinkNode *L)//L为头结点
{
int n = 0;
LinkNode * p = L; //p指向头结点,n置为0(即头结点的序号为0)
while (p->next)
{
n++;
p=p->next;
}
return n;
}
5、遍历
void DispList(LinkNode *L)
{
LinkNode * p = L->next;
while (p)
{
qDebug()<<" "<<p->data<<" ";
p = p->next;
}
}
6、求索引 index 处的元素
bool GetElem(LinkNode *L,int index,elemType &e) //L为头结点
{
int j = 0;
LinkNode * p = L;
while (j < index && p)
{
j++;
p=p->next;
}
if (p)
{
e = p->data;
return true;
}
else
{
return false;
}
}
7、在 index 处插入元素
bool ListInsert(LinkNode *&L,int index,elemType e)
{
int j = 0;
LinkNode *p = L;
while (j < index - 1 && p)
{
j++;
p = p->next;
}
if (p)
{
LinkNode *s = new LinkNode;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
else
{
return false;
}
}
8、删除 index 处的元素
bool ListDelete(LinkNode *&L,int index,elemType &e)
{
int j = 0;
LinkNode *p = L;
while (j < index - 1 && p)
{
j++;
p = p->next;
}
if (!p)
return false;
else
{
LinkNode *q = p->next;
if (!q)
return false;
e = q->data;
p->next = q->next;
delete q;
return true;
}
}
二、双链表基本操作
1、定义双链表结点类型
#define elemType char
struct DLinkNode //双链表结点类型
{
elemType data;
struct DLinkNode *prior; //指向前驱结点
struct DLinkNode *next; //指向后继结点
};
2、建立双链表
- 头插法建表
void CreateListF(DLinkNode *&L,elemType a[],int n)
{
L = new DLinkNode; //创建头结点
L->prior = L->next = nullptr; //前后指针域置为NULL
for (int i = 0;i < n;i++)
{
DLinkNode * s = new DLinkNode;
s->data = a[i]; //创建数据结点*s
s->next = L->next;
if (L->next)
L->next->prior = s;
L->next = s;
s->prior = L;
}
}
- 尾插法建表
void CreateListR(DLinkNode *&L,elemType a[],int n)
{
L = new DLinkNode; //创建头结点
DLinkNode * r = L; //r始终指向尾结点,开始时指向头结点
for (int i = 0;i < n;i++)
{
DLinkNode * s = new DLinkNode;
s->data = a[i]; //创建数据结点*s
r->next = s;
s->prior = r; //将*s插入*r之后
r = s; //r指向尾结点
}
r->next=nullptr;
}
3、在 index 处插入元素
bool ListInsert(DLinkNode *&L,int index,elemType e)
{
int j = 0;
DLinkNode * p = L; //p指向头结点,j设置为0
while (j < index-1 && p) //查找第i-1个结点
{
j++;
p=p->next;
}
if (p)//找到第i-1个结点*p,在其后插入新结点*s
{
DLinkNode * s = new DLinkNode;
s->data = e; //创建新结点*s
s->next = p->next; //在*p之后插入*s结点
if (p->next) //若存在后继结点,修改其前驱指针
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
else
{
return false;
}
}
4、删除第 index 个元素
bool ListDelete(DLinkNode *&L,int index,elemType &e)
{
int j = 0;
DLinkNode * p = L; //p指向头结点,j设置为0
while (j < index - 1 && p) //查找第i-1个结点
{
j++;
p = p->next;
}
if (p)//找到第index-1个结点*p
{
DLinkNode * q = p->next; //q指向第i个结点
if (!q)
return false;
e = q->data;
p->next = q->next; //从双单链表中删除*q结点
if (p->next) //修改其前驱指针
p->next->prior = p;
delete q;
return true;
}
else
{
return false;
}
}
三、两个算法示例
例1
void InterSect(LinkList *ha,LinkList *hb,LinkList *&hc)
{
LinkList * pa = ha->next;
LinkList *pb = hb->next;
hc = new LinkList;
LinkList * r = hc; //r指向尾结点
while (pa && pb)
{
if (pa->data < pb->data)
pa = pa->next;
if (pa->data > pb->data)
pb = pb->next;
if (pa->data == pb->data) //相同元素
{
LinkList * s = new LinkList; //复制结点
s->data = pa->data;
r->next = s;
r = s;
pa = pa->next;
pb = pb->next;
}
}
r->next = nullptr;
}
例2
void UnionList(SqList *LA,SqList *LB,SqList *&LC)
{
int i = 0,j = 0,k = 0;//i、j分别为LA、LB的下标,k为LC中元素个数
LC = new SqList; //建立有序顺序表LC
while (i < LA->length && j < LB->length)
{
if (LA->data[i] < LB->data[j])
{
LC->data[k] = LA->data[i];
i++;
k++;
}
else
{
LC->data[k] = LB->data[j];
j++;
k++;
}
}
while (i < LA->length) //LA尚未扫描完,将其余元素插入LC中
{
LC->data[k] = LA->data[i];
i++;
k++;
}
while (j < LB->length) //LB尚未扫描完,将其余元素插入LC中
{
LC->data[k]=LB->data[j];
j++;
k++;
}
LC->length=k;
}