注:只包含逐一操作的源码 无完整版本
蒟蒻一个,语言表达也很差,为了完成任务写的,希望可以帮到大家。
定义结构体
定义一个结构体,一个数据域,一个指针域
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
初始化
为L分配一个空间并且使其NULL(头指针)
Status Initlist(LinkList &L) {
L = new LNode;
L->next = NULL;
return OK;
}
创建链表:
这一步很简单,直接初始化一波链表,然后循环开辟新的空间,同时在数据域存储相应的。
指针域的操作:每次新申请的指针域指向NULL,同时使上一次的指针域指向这次申请的空间以达到在逻辑上连接的目的。
void CreatList(LinkList &L, int n) {
L = new LNode;
L->next = NULL;
LinkList r = L;
printf("请输入初始值");
for (int i = 0; i < n; i++) {
LinkList p = new LNode;
cin >> p->data;
p->next = NULL;
r->next = p;
r = p;
}
}
按值查找:
新创建一个指针结构体使其指向L第一个结点的地址,(从第一个结点元素开始遍历即可)while循环直到数据域的值与查找的值相同时结束循环同时返回地址。
LNode *LocateElem(LinkList &L, ElemType e) {
LinkList p = L->next;
while (p && p->data != e) {
p = p->next;
}
return p;
}
得到某个位置上的值:
新创建一个指针结构体使其指向L第一个结点的地址,while循环直到我们要查找的位置后停止循环(可以增加一个判断防止超出范围却继续执行程序的现象出现),之后为e赋值得到所需位置的值之后结束即可。
Status GetElem(LinkList L, int i, ElemType &e) {
LinkList p = L->next;
int j = 1;
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j > i)
return ERROR;
e = p->data;
return OK;
}
求链表长度:
这一步,很简单,只需要指针域逐渐向后移动直到NULL即可结束循环,每循环一次cont+1则循环的次数就是该链表的长度。最后直接返回cont即可
Status ListLength(LinkList L) {
LinkList p = L->next;
int cont = 0;
while (p) {
++cont;
p = p->next;
}
return cont;
}
链表的插入:
这一步,想较于其他操作较为复杂。我们可以以下图来加深理解。
(注:该图片我没有手画直接搬运于https://www.acwing.com/solution/content/16251/
该题解是关于用数组模拟单链表的一篇文章。
我们只需要通过循环找到我们需要插入的位置,然后按照上图new一个新的空间,在其数据域上输入我们要插入的一个值,此刻,p所值的位置是我们要插入位置的前一个位置为申请空间的指针域指向p->next然后在让p->next指新我们申请的空间即可达到插入效果。
Status ListInsert(LinkList &L, int i, ElemType e) {
LinkList p = L;
int j = 0;
while (p && (j < i - 1)) {
p = p->next;
++j;
}
if (!p || j > i - 1)
return ERROR;
LinkList s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
链表的删除:
链表的删除与插入思想相似,我们需要不断遍历循环到我们需要删除的值,此时遍历到了需要删除的域,实现一个跳跃即可,使p->next 指向我们需要删除的域的下一个指针域,然后直接delete
此时的s域
Status ListDelete(LinkList &L, int i) {
LinkList p = L;
int j = 0;
while ((p->next) && (j < (i - 1))) {
p = p->next;
++j;
}
if (!(p->next) || (j > i - 1))
return ERROR;
LinkList q = p->next;
p->next = q->next;
delete q;
return OK;
}
链表展示:
(不多说了)循环遍历输出即可
void DisplayList(LinkList L) {
LinkList p = L->next;
while (p) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
return;
}
链表的销毁:
通过其逻辑上相连的关系逐渐寻找下一个域找到一个delete一个即可,很简单。
Status DestroyList(LinkList &L) {
LinkList p;
while (L) {
p = L;
L = L->next;
delete p;
}
return OK;
}
此外还有寻找 前继与后继等基本操作,大家可以自行摸索,这篇水文到此结束