2021.08.15
1、记录自己学习数据结构中对于链式表的实现,实现了对于链式表的增插删改查
2、其中最难的是插入和删除因为该操作都涉及到了指针的指向问题,
- 插入函数
ListInsert_L
代码片段+详解
Status ListInsert_L(LinkList& L, int i, ElemType e) {
int index = 0;
LinkList P = L;
LNode* newnode;
while (P && index < i - 1) {
P = P->next;
index++;
}
if (!P || index > i - 1) {
return ERROR;
}
newnode = (LinkList)malloc(sizeof(LNode));
newnode->data = e;
newnode->next = P->next;
P->next = newnode;
return OK;
}
详解部分:
1、首先需要找到要插入的位序,对于链式存储的方式并不能像顺序表那样通过下标的方式定位,而是通过指针的移动确认位序,这里需要注意的是我们要找到插入位序的前一个位置,而不是找到插入的位置!所以 while 循环在 index 等于 i-1 的情况就要退出循环!
2、新建一个结点供于使用,newnode->next = P->next; P->next = newnode;
这两句代码不能颠倒,需要先让新结点的下一个位置指向P结点的下一个位置,然后再让P的下一个位置指向新结点!如果代码顺序颠倒了,那么就会使得newdata结点的下一个位置指向本身自己!请自行体会!
- 删除函数
ListDelete_L
代码片段+详解
Status ListDelete_L(LinkList& L, int i) {
int index = 0;
LinkList P = L;
LinkList Q;
ElemType e;
while (index < i - 1 && P) {
P = P->next;
index++;
}
if (!P) {
return ERROR;
}
Q = P->next;
e = Q->data;
P->next = Q->next;
free(Q);
return e;
}
详解部分:
1、首先一样,需要找到要删除的结点的前一个位序,在 index = i -1 的情况退出,
2、P指向的是被删除结点的前一个结点,Q = P->next;
该代码执行完后,Q指向了要删除的那个结点了!
3、所以让P的下一个位置指向Q的下一个位置就实现了对于Q结点的删除,然后在释放内存free(Q);
完整代码展示如下
#include<stdio.h>
#include<stdlib.h>
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int ElemType;
typedef int Status;
typedef struct LNode {
ElemType data;
struct LNode* next;
} LNode, * LinkList;
Status InitLinkList_L(LinkList& L); //初始化一个链表的头结点
void ShowList_L(LinkList L); //展示当前的链式表
Status ClearList_L(LinkList& L); //清空链式表
Status LintAdd_L(LinkList& L, ElemType e); //添,添加一个值为e的数据
Status ListInsert_L(LinkList& L, int i, ElemType e); //插,插入一个位序为i,值为e的节点
Status ListDelete_L(LinkList& L, int i); //删,删除一个位序为 i 的节点
Status ListAlter_L(LinkList& L, int i, ElemType e); //改,修改位序为i的值为e
Status ListWacth_L(LinkList& L, int i); //查,查看位序为i的值
void ShowInterface(); //展示界面信息
int main() {
LinkList mylinklist;
InitLinkList_L(mylinklist);
char switch_on;
bool isFlag = true;
ShowInterface();
while (isFlag) {
printf("请输入你想要实现功能的次序号:");
scanf("%c", &switch_on);
getchar();
int i, number;
switch (switch_on)
{
case'1':
printf("请输入需要增加的数字的值:");
scanf("%d", &number);
getchar();
system("cls");
ShowInterface();
if (LintAdd_L(mylinklist, number) == OK) {
printf("添加成功!\n");
}
else {
printf("添加失败!\n");
}
break;
case'2':
printf("请输入需要插入的位序和数值,空格分隔:");
scanf("%d %d", &i, &number);
getchar();
system("cls");
ShowInterface();
if (ListInsert_L(mylinklist, i, number) == OK) {
printf("插入成功!\n");
}
else {
printf("插入失败!\n");
}
break;
case'3':
printf("请输入你想要查看的位序:");
scanf("%d", &i);
getchar();
system("cls");
ShowInterface();
printf("当前位序为:%d,的值为:%d\n", i, ListWacth_L(mylinklist, i));
break;
case'4':
printf("请输入你想要删除的位序:");
scanf("%d", &i);
getchar();
system("cls");
ShowInterface();
printf("你删除的位序为:%d的值为:%d\n", i, ListDelete_L(mylinklist, i));
break;
case'5':
printf("请输入你想要修改的位序和值(空格隔开):");
scanf("%d %d", &i, &number);
getchar();
system("cls");
ShowInterface();
if (ListAlter_L(mylinklist, i, number) == OK) {
printf("修改成功!\n");
}
else {
printf("修改失败!\n");
}
break;
case'6':
system("cls");
ShowInterface();
ShowList_L(mylinklist);
break;
case'7':
if (ClearList_L(mylinklist) == OK)
{
printf("清空成功!\n");
}
else {
printf("清空失败!\n");
}
break;
case'0':
isFlag = false;
system("cls");
printf("程序退出成功!欢迎下次使用!");
ClearList_L(mylinklist);
free(mylinklist);
break;
default:
break;
}
}
return 0;
}
Status InitLinkList_L(LinkList& L) {
L = (LinkList)malloc(sizeof(LNode));
if (!L) {
exit(OVERFLOW);
}
L->next = NULL;
return OK;
}
void ShowList_L(LinkList L) {
LinkList Q = L->next;
printf("当前链式表:");
while (Q) {
printf("%d\t", Q->data);
Q = Q->next;
}
printf("\n");
}
Status LintAdd_L(LinkList& L, ElemType e) {
LinkList Q;
LinkList P = L;
Q = (LinkList)malloc(sizeof(LNode));
if (!Q) {
return ERROR;
}
while (P->next) {
P = P->next;
}
Q->data = e;
Q->next = NULL;
P->next = Q;
return OK;
}
Status ClearList_L(LinkList& L) {
LinkList Q;
while (L->next)
{
Q = L->next;
L->next = Q->next;
free(Q);
}
return OK;
}
Status ListInsert_L(LinkList& L, int i, ElemType e) {
int index = 0;
LinkList P = L;
LNode* newnode;
while (P && index < i - 1) {
P = P->next;
index++;
}
if (!P || index > i - 1) {
return ERROR;
}
newnode = (LinkList)malloc(sizeof(LNode));
newnode->data = e;
newnode->next = P->next;
P->next = newnode;
return OK;
}
Status ListDelete_L(LinkList& L, int i) {
int index = 0;
LinkList P = L;
LinkList Q;
ElemType e;
while (index < i - 1 && P) {
P = P->next;
index++;
}
if (!P) {
return ERROR;
}
Q = P->next;
e = Q->data;
P->next = Q->next;
free(Q);
return e;
}
Status ListAlter_L(LinkList& L, int i, ElemType e) {
LinkList Q = L;
int index = 0;
while (index < i && Q) {
Q = Q->next;
index++;
}
Q->data = e;
return OK;
}
Status ListWacth_L(LinkList& L, int i) {
LinkList Q = L;
int index = 0;
while (index < i && Q) {
Q = Q->next;
index++;
}
if (!Q) {
return ERROR;
}
return Q->data;
}
void ShowInterface() {
printf("输入 1 实现对链式表的-增加-数据\n");
printf("输入 2 实现对链式表的-插入-数据\n");
printf("输入 3 实现对链式表的-查看-数据\n");
printf("输入 4 实现对链式表的-删除-数据\n");
printf("输入 5 实现对链式表的-修改-数据\n");
printf("输入 6 实现展示当前链式表\n");
printf("输入 7 实现清空当前链式表\n");
printf("输入 0 实现退出程序\n");
}