王道考研408 | 数据结构 | 单链表实验代码

所有代码均经过测试,附运行截图

实验环境

vscode 2022 社区版
vscode 2022 社区版的搭建:
https://blog.youkuaiyun.com/lijiamingccc/article/details/123552207

1.初始化单链表

带头节点的单链表初始化

bool Init_HeadList(LinkList& L) {
	L = (LNode* )malloc(sizeof(LNode));//分配一个头节点
	if (!L) return false;
	L->next = NULL;
	return true;
}

不带头节点的单链表初始化

// 初始化单链表  不带头节点
bool InitList(LinkList &L){
	L = NULL;
	return true;
}

2.按位查找

j<=i 是定位到第i个,j<i是定位到i-1个

LNode* GetElem(LinkList L,int i){
	if (i<=0) return NULL;
	int j = 1;
	LNode *p = L;
	// 当结点P存在,并且j<=i
	// 在这里注意区分<=和<的区别
	while (p && j<=i){
		// 将下一个结点赋值给p
		p = p->next;
		j++;
	}
	return p; 
}

3.按值查找

LinkList LocateElem(LinkList L,int e){
	LNode *p = L;
	while (p && p ->data != e){
		p = p->next;
	}
	return p;
}

4.计算单链表长度

int Length(LinkList L){
	int len=0;
	LNode *p =L;
	while (p->next){
		len++;
		p = p->next;
	}
	return len;
}

5.插入操作

后插操作

后插操作 在结点p之后插入元素e

bool InsertNextNode(LNode *p,int e){
	if(!p) return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));
	// 内存空间不足,失败
	if(!s) return false;
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

前插操作

前插和后插的操作类似,前插是在后插的基础上交换了一下两个节点的数据域

bool InsertPriorNode(LNode *p,int e){
	if (!p) return false;
	LNode *s = (LNode *)malloc(sizeof(LNode));
	if (!s) return false;
	// 依然是在p结点之后插入一个结点s
	s ->next = p ->next;
	p ->next = s;
	// 将s和p结点的数据域互换
	s ->data = p->data;
	p ->data = e;
	return true;
}

结合插入和查找

在第i个位置插入元素e

// 便捷调用插入,带头节点的插入操作,在第i个位置插入元素e
bool ListInsert(LinkList& L, int i, int e) {
	if (i < 1) return false;
	LNode *p = GetElem(L, i-1);
	if (!p) return false;
	// InsertPriorNode也可以
	return InsertNextNode(p, e);
}

6.删除节点

注意为什么要i-1,因为i是位序,而i-1是下标

bool ListDelete(LinkList &L,int i,int &e){
	if(i<1) return false;
	LNode *p = GetElem(L,i-1);
	if(!p || !(p->next)) return false;
	LNode *q = p->next;
	e = q->data;
	p->next = q->next;
	free(q);
	return true;
}

7.建立链表

头插法建立链表

头插法,带头节点
当L是空表时,L是头节点,插入的第一个数据是在L后面的
开始插入第二个第三个…就是头插的方式

LinkList List_HeadInsert(LinkList &L){
	L = (LinkList)malloc(sizeof(LNode));
	L ->next = NULL;
	LNode *s; 
	int x;
	printf("正在使用头插法插入元素:\n");
	while(x!=9999){
		scanf("%d",&x);
		if(x==9999) break;
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		s->next = L->next;
		L->next = s;
	}
	return L;
}

尾插法建立链表

// 尾插法 带头节点
LinkList List_TailInsert(LinkList &L){
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	LNode* s, * r = L;	//r表示表尾指针
	int x;
	printf("正在使用尾插法插入元素:\n");
	while(x!=9999){
		scanf("%d",&x);
		if(x==9999) break;
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		r->next = s; //这一步不可以缺失,处于循环之中,缺失则错
		r = s;
	}
	r ->next = NULL;   // 将队尾元素置空
	return L;
}

tip:定义一个输出链表的函数


void print(LinkList L) {
	LNode* s = L;
	while (s->next!=NULL) {
		s = s->next;
		printf("%d  ",s->data);
	}	
}

主程序测试


int main(){
	LinkList L;
	Init_HeadList(L);
	//List_HeadInsert(L);
	//print(L);
	List_TailInsert(L);
	print(L);
	printf("\n链表的第1个元素是%d\n",GetElem(L, 1)->data);
	printf("链表的长度是%d\n",Length(L));
	int e;
	// 删除链表节点
	ListDelete(L, 3, e);
	printf("删除的第3个元素是%d\n",e);
	printf("当前的链表为");
	print(L);
	// 插入链表节点
	printf("\n请输入要插入的元素的值: ");
	scanf("%d",&e);
	ListInsert(L, 3, e);
	printf("删除的第3个元素是%d\n",e);
	printf("当前的链表为");
	print(L);
	return 0;
}

运行结果:

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

旭旭老师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值