单链表的C代码实现(根据书本进行了部分修改,修改部分代码有注解)

本文详细介绍了一种基于单链表的抽象数据类型(ADT)实现,包括初始化、判断是否为空、获取长度、清空、获取指定位置元素、查找元素、插入元素、删除元素等操作的具体算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单链表抽象数据类型
ADT 线性表(List)
Data
线性表的数据对象集合为{a1,a2,…,an},每个元素的类型均为DataType。其中,除了第一个元素a1外,
每个元素有且只有一个直接的前驱,除了最后一个元素,每个元素有且只有一个直接后继元素。数据
元素之间的关系是一对一的关系。
Operator
InitList(*L):初始化操作,建立一个空的线性表L
ListEmpty(L):若线性表为空,返回true,否则返回false
ClearList(*L):将线性表清空
GetElem(L,I,*e):将线性表L中第i个位置元素值返回给e
LocateElem(L,e):在线性表L中查找与给定值e相等的元素;查找成功,返回该元素在表中序号表示成功,
否则返回0表示失败,
ListInsert(*L,i,e):在线性表中的第i个位置插入新元素e
ListDelet(*L,i,*e):删除线性表L中第i个位置元素,并用e返回其值
ListLength(L):返回线性表L的元素个数
.hpp

#ifndef TEST_H_
#define TEST_H_
#include<malloc.h>
typedef int ElemType;

typedef struct Node
{
	ElemType data;
	struct Node * next;
}Node;
typedef struct Node * Linklist;

//InitList(*L) :初始化操作,建立一个空的线性表L
Linklist initList();
//ListEmpty(L) : 若线性表为空,返回true, 否则返回false
bool listEmpty(const Linklist L);
//ListLength(L) : 返回线性表L的元素个数
int listLength(Linklist L);
//ClearList(*L) : 将线性表清空
void clearList(Linklist L);
//GetElem(L, I, *e) : 将线性表L中第i个位置元素值返回给e
bool getElem(const Linklist L, const int i, ElemType * e);
//LocateElem(L, e) : 在线性表L中查找与给定值e相等的元素;查找成功,返回该元素在表中序号表示成功,否则返回0表示失败
bool locateElem(const Linklist L, ElemType e);
//ListInsert(*L, i, e) : 在线性表中的第i个位置插入新元素e
bool listInsert(Linklist L, const int i, ElemType e);
//ListDelet(*L,i,*e) : 删除线性表L中第i个位置元素,并用e返回其值
bool listDelete(Linklist L, const int i);

#endif // !TEST_H_

#pragma once

.cpp

#include"test.h"

//InitList(*L) :初始化操作,建立一个空的线性表L
Linklist initList() {

	Linklist temp = (Linklist)malloc(sizeof(Linklist));
	temp->next = nullptr;
	return temp;
}

//ListEmpty(L) : 若线性表为空,返回true, 否则返回false
bool listEmpty(const Linklist L) {

	Linklist p = L->next;
	int length = 0;
	while (p != nullptr)
	{
		p = p->next;
		++length;
	}

	if (length == 0)
		return true;
	else
		return false;

}

//ListLength(L) : 返回线性表L的元素个数
int listLength(Linklist L) {

	Linklist p = L->next;
	int length = 0;
	while (p != nullptr)
	{
		p = p->next;
		++length;
	}
	return length;
}

//ClearList(*L) : 将线性表清空
//(1)声明一个节点p和q
//(2)将第一个节点赋值给p
//(3)循环
//	将下一个节点赋给q
//	释放p
//	将q赋给p
void clearList(Linklist L) {

	Linklist p, q;
	p = L->next;
	while (p != nullptr)
	{
		q = p->next;
		free(p);
		p = q;
	}
	L->next = nullptr;
}

//GetElem(L, I, *e) : 将线性表L中第i个位置元素值返回给e
//(1)声明一个指针p指向链表第一个结点,初始化j从1开始
//(2)当j<i时就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1
//(3)若到链表末尾P为空,则说明第i个结点不存在
//(4)否则查找成功,返回结点p的数据
bool getElem(const Linklist L, const int i, ElemType * e) {

	Linklist p = L->next;
	int j = 1;
	while ((p != nullptr) && (j < i))
	{
		p = p->next;
		++j;
	}
	if (p == nullptr || j > i)
		return false;
	*e = p->data;
	return true;
}

//LocateElem(L, e) : 在线性表L中查找与给定值e相等的元素;查找成功,返回该元素在表中序号表示成功,否则返回0表示失败
bool locateElem(const Linklist L, ElemType e) {

	Linklist p = L->next;
	int j = 1;
	while (p != nullptr)
	{
		if (e == p->data)
		{
			return j;
			break;
		}
		p = p->next;
		++j;
	}
	if (p == nullptr)
		return 0;

}

//ListInsert(*L, i, e) : 在线性表中的第i个位置插入新元素e
//(1)声明一指针p指向链表头结点,初始化j从1开始
//(2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1
//(3)若到链表末尾p为空,则说明第i个结点不存在
//(4)否则查找成功,在系统中生成一个空结点s
//(5)将数据元素e赋给s->data
//(6)单链表插人标准语句s->next = p->next;p->next = s;
//(7)返回成功
bool listInsert(Linklist L, const int i, ElemType e) {

	Linklist p = L,s;
	int j = 1;
	while (p != nullptr && j < i)
	{
		p = p->next;
		++j;
	}
	if (p == nullptr || j > i)
		return false;
	s = (Linklist)malloc(sizeof(Linklist));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

//ListDelet(*L,i,*e) : 删除线性表L中第i个位置元素,并用e返回其值
//(1)声明一指针p指向链表头指针,初始化j从1开始
//(2)当j<i开始,就遍历链表,rangp的指针向后移动,不断指向下一个结点,j累加1
//(3)若到链表末尾p为空,这说明第i个结点不存在
//(4)否则查找成功,将欲删除的界定啊p->next赋值给q
//(5)单链表的删除标准语句p->next = q->next;
//(6)将q结点中的数据值赋给e,作为返回
//(7)释放q结点
//(8)返回成功
bool listDelete(Linklist L, const int i) {
	
	Linklist p = L;
	Linklist s;
	int j = 1;
	while (p != nullptr && j < i)
	{
		p = p->next;
		++j;
	}
	if (p == nullptr || j > i)
		return false;
	s = p->next;
	p->next = s->next;
	free(s);
	return true;
}

main函数

#include<iostream>
#include"test.h"

void showList(const Linklist L);

int main()
{
	Linklist root = initList();
	std::cout<<listEmpty(root)<<std::endl;
	std::cout << listLength(root) << std::endl;
	listInsert(root, 0, 1);
	listInsert(root, 1, 2);
	listInsert(root, 2, 3);
	listInsert(root, 3, 4);
	listInsert(root, 4, 5);
	listInsert(root, 5, 6);
	std::cout << "表的当前长度为: " << listLength(root) << std::endl;
	std::cout << listEmpty(root) << std::endl;
	showList(root);
	clearList(root);
	std::cout << "表的当前长度为: " << listLength(root) << std::endl;
	std::cout << listEmpty(root) << std::endl;
	listDelete(root, 2);
	showList(root);

	return 0;
}

void showList(const Linklist L) {

	if(listLength(L) < 1)
		std::cerr << "线性表为空表!\n";
	else
	{
		Linklist p = L->next;
		while (p != nullptr)
		{
			std::cout << p->data << " ";
			p = p->next;
			
		}
		std::cout << std::endl;
	}
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值