查找
要求
输入要查找的值x,调用按值查找单链表函数,输出它的位序(可能多个)
思路
基础查找函数:
Status QueryNode(LinkList L,ElemType x)
{
LinkList p;int i=0;
p=L->next;
while(p!=NULL)
{
if(p->data=x)
{
i++;
printf("元素%d在链表第%d位\n",x,i);
return OK;
}
p=p->next;
}
return ERROR;
}
在这个函数中,只要找到一个x值,立刻打印其位序并返回OK,退出函数。现在我们既要返回函数的ERROR或OK,又要打印出所有的i值,不妨先把所有的i值存储起来,循环结束后统一打印,打印结束后返回OK。
那么,ERROR该何时返回呢?由于i值个数不确定,考虑用链表存储i值,参考尾插法。若没有i值,则该链表为空表。在循环结束后判断其是否为空表,是则返回ERROR,否则打印并返回OK。
然而,在编译器中,若不在函数外对B初始化(包括data域和next域),会报错。这样一来,就不存在空表B了。易知i不可能为小于等于0的数,那么可对B进行如下初始化:
LinkList B;
B = (LinkList)malloc(sizeof(LNode));
B->data = 0;
B->next = NULL;
这样一来,就解决了存储位序值、判空返回正误、未初始化报错的问题。
查找函数:
Status QueryNode(LinkList L, ElemType x, LinkList B)//查找
{
LinkList p;
/*B的尾插指针*/LinkList s, r;
/*B的尾插操作*/B = (LinkList)malloc(sizeof(LNode)); r = B;
p = L->next;
int i = 1;
while (p != NULL)
{
if (p->data == x)
{
/*B的尾插操作*/s = (LinkList)malloc(sizeof(LNode));
s->data = i;
r->next = s;
r = s;
}
p = p->next;
i++;
}
/*B的尾插操作*/r->next = NULL;
if (B->data == 0) return ERROR;
printf("元素%d在如下位置:\n", x);
DisplayLink(B);
return OK;
}
代码及运行结果
#include <stdio.h>
#include <stdlib.h>
constexpr auto ERROR = 0;
constexpr auto OK = 1;
typedef int ElemType;
typedef int Status;
typedef struct Node {
ElemType data;
struct Node* next;
}LNode, * LinkList;
void CreateList(LinkList& L, int n)//尾插法
{
LinkList p, q; int i;
L = (LinkList)malloc(sizeof(LNode));
q = L;
for (i = 0; i < n; ++i) {
p = (LinkList)malloc(sizeof(LNode));
scanf_s("%d", &p->data);
q->next = p;
q = p;
}
q->next = NULL;
}
void DisplayLink(LinkList L)//输出
{
LinkList p;
p = L->next;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->next;
}
}
Status QueryNode(LinkList L, ElemType x, LinkList B)//查找
{
LinkList p;
/*B的尾插指针*/LinkList s, r;
/*B的尾插操作*/B = (LinkList)malloc(sizeof(LNode)); r = B;
p = L->next;
int i = 1;
while (p != NULL)
{
if (p->data == x)
{
s = (LinkList)malloc(sizeof(LNode));
s->data = i;
r->next = s;
r = s;
}
p = p->next;
i++;
}
r->next = NULL;
if (B->data == 0) return ERROR;
printf("元素%d在如下位置:\n", x);
DisplayLink(B);
return OK;
}
int main(void)
{
LinkList A; LinkList B; B = (LinkList)malloc(sizeof(LNode)); B->data = 0; B->next = NULL;
int m;
printf("您要创建几位的链表\n");
scanf_s("%d", &m);
printf("请输入%d个元素\n", m);
CreateList(A, m);
printf("您已创建链表如下:\n");
DisplayLink(A);
int x;
printf("要查找的元素:\n");
scanf_s("%d", &x);
QueryNode(A, x, B);
return 0;
}
删除
要求
输入要删除的值g,调用按值删除函数,输出更新后的链表。(可能多个)
思路
基本删除函数
Status DeletList(LinkList &L,int i,ElemType &e)//删除第i个结点
{
LinkList p,q;//q指向第i个结点。循环结束时,p指向第i-1个结点
p=L;//p存储头结点的地址
int j=0;
while(p->next&&j<i-1)
{
p=p->next;
i++;
}
if(!p->next||j>i-1) return ERROR;
//*****************************
q=p->next;
p->next=q->next;//第i-1个结点的指针域指向第i+1个结点
//*****************************
e=q->data;//用e存放q的数据域
free(q);//释放第i个结点
return OK;
}
改进如下
Status ListDelete(LinkList &L, int x)//删除
{
LinkList j, k;
k = L;//避免因k未初始化而报错
j = L;
while (j->next!= NULL)
{
k = j->next;//每次循环都重新对k赋值
if (k->data == x)
{
j->next = k->next;
free(k);
}
else j = j->next;
}
if (k==L) return ERROR;
return OK;
}
图解
代码及运行结果
#include <stdio.h>
#include <stdlib.h>
constexpr auto ERROR = 0;
constexpr auto OK = 1;
typedef int ElemType;
typedef int Status;
typedef struct Node {
ElemType data;
struct Node* next;
}LNode, * LinkList;
void CreateList(LinkList& L, int n)//尾插法
{
LinkList p, q; int i;
L = (LinkList)malloc(sizeof(LNode));
q = L;
for (i = 0; i < n; ++i) {
p = (LinkList)malloc(sizeof(LNode));
scanf_s("%d", &p->data);
q->next = p;
q = p;
}
q->next = NULL;
}
void DisplayLink(LinkList L)//输出
{
LinkList p;
p = L->next;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->next;
}
}
Status ListDelete(LinkList &L, int x)//删除
{
LinkList j, k;
k = L;//避免因k未初始化而报错
j = L;
while (j->next!= NULL)
{
k = j->next;
if (k->data == x)
{
j->next = k->next;
free(k);
}
else
{
j = j->next;
}
}
if (k==L) return ERROR;
return OK;
}
int main(void)
{
LinkList A;
int c,g;
printf("要创建几位的链表\n");
scanf_s("%d", &c);
printf("输入表中元素\n");
CreateList(A, c);
printf("您已创建链表如下\n");
DisplayLink(A);
printf("要删除几\n");
scanf_s("%d", &g);
ListDelete(A, g);
printf("更新链表如下:\n");
DisplayLink(A);
return 0;
}
运行结果如下: