C语言实现线性表的链式存储表示和实现

2021.08.15
1、记录自己学习数据结构中对于链式表的实现,实现了对于链式表的增插删改查
2、其中最难的是插入删除因为该操作都涉及到了指针的指向问题,

  1. 插入函数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结点的下一个位置指向本身自己!请自行体会!

  1. 删除函数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");
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小司卫理理参上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值