02.数据结构——无头非循环单链表(增删改查)


前言

提示:个人学习/复习 笔记使用,仅供参考


一、单链表

概念
链表是一种物理存储结构上不连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,可以实现更加灵活的动态内存管理。

链表在物理结构上不一定是线性的,而在逻辑结构上是线性的

链表的构成
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分:
1、数据域:存储数据元素
2、指针域:存储下一个结点地址

链表的定义

//无头非循环单链表
typedef int SingleListDataType;

typedef struct SingleList {

	SingleListDataType data;   //数据域
	struct SingleList* next;   //指针域

}SingleList;

注意:下面接口中,如需修改链表的内容,则传二级指针

二、申请节点

//申请节点
SingleList* BuySingleListNode(SingleListDataType x) {

	SingleList* newNode = (SingleList*)malloc(sizeof(SingleList));
	if (newNode==NULL) {
		perror("malloc");
		return NULL;
	}
	newNode->data = x;
	newNode->next = NULL;
	return newNode;
};

三、打印链表

//打印
void SingleListPrint(SingleList* ps) {   //打印不会修改链表,所以一级指针就行
	if (ps==NULL) {
		printf("空链表\n");
	}
	else {
		while (ps!=NULL) {
			printf("%d->",ps->data);
			ps = ps->next;
		}
		printf("NULL\n");
	}
};

四、尾插

//尾插
void SingleListPushBack(SingleList** pps, SingleListDataType x) {

	assert(pps);
	SingleList* newNode = BuySingleListNode(x);
	
	if (*pps ==NULL) {    //如果单链表为空,直接就插入了
		*pps = newNode;
	}
	else {            //如果单链表不为空,需要遍历找到尾,再插入
		SingleList* tail = *pps;
		while (tail->next != NULL) {
			tail = tail->next;
		}
		tail->next = newNode;
	}
};

五、尾删

//尾删
void SingleListPopBack(SingleList** pps) {

	assert(pps);
	
	if (*pps ==NULL) {
		printf("链表为空\n");
	}
	else {
		SingleList* tail = *pps;
		SingleList* prev = tail;
		while (tail->next!=NULL) {
			prev = tail;
			tail = tail->next;
		}
		prev->next = NULL;
	}
};

六、头插

//头插
void SingleListPushFront(SingleList** pps, SingleListDataType x) {

	assert(pps);
	
	SingleList* newNode = BuySingleListNode(x);
	
	if (*pps ==NULL) {
		*pps = newNode;
	}
	else {
		SingleList* next = (*pps);
		*pps = newNode;
		newNode->next=next;
	}
};

七、头删

//头删
void SingleListPopFront(SingleList** pps) {

	if (*pps ==NULL) {
		printf("空链表\n");
		return;
	}
	else {
		*pps = (*pps)->next;
	}
};

八、指定位置后插入

//指定位置结点后插入
void SingleListInsertAfter(SingleList** pps, int pos, SingleListDataType x) {
	assert(pps);
	assert(*pps);
	
	SingleList* cur = *pps;
	SingleList* newNode = BuySingleListNode(x);
	while (--pos) {
		cur = cur->next;
	}
	newNode->next = cur->next;
	cur->next = newNode;
};

九、指定位置后删除

//指定位置结点后删除
void SingleListEraseAfter(SingleList** pps, int pos) {

	assert(pps);
	assert(*pps);
	
	SingleList* cur = *pps;
	while (--pos) {
		cur = cur->next;
	}
	cur->next = cur->next->next;
};

十、指定位置删除

//删除指定位置节点
void SingleListErase(SingleList** pps, int pos) {

	assert(pps);
	assert(*pps);

	SingleList* cur = *pps;
	SingleList* prev = *pps;

	while (--pos) {
		prev = cur;
		cur = cur->next;
	}
	prev->next = cur->next;
};

十一、查找指定值,返回地址

//查找指定值,返回地址
void SingleListFind(SingleList** pps, int x) {

	assert(pps);
	assert(*pps);

	SingleList* cur = *pps;
	while (cur!=NULL) {
		if (x==cur->data) {
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
};

十二、求链表长度

//返回链表长度
int  SingleListSize(SingleList* ps) {

	SingleList* cur = ps;
	int count = 0;
	while (cur != NULL) {
		count++;
		cur = cur->next;
	}
	return count;
};

十三、销毁

//销毁
void SingleListDestory(SingleList** pps) {

	assert(pps);
	
	SingleList* cur = *pps;
	SingleList* next = *pps;
	while (cur!=NULL) {
		
		next = cur->next;
		free(cur);
		cur = next;
	}
	*pps = NULL;

};

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值