单链表(算法与数据结构)

特点:逻辑相邻,物理不一定相邻

具体实现之前有几点需要注意

适用于带前驱的操作,比如插入,删除等

for(struct Node *p=pn;p->next!=NULL;p=p->next);//从头节点开始遍历
适用于不带前驱的操作,如打印,查找,获取有效值个数等
for(struct Node *p=pn->next;p!=NULL;p=p->next);//从第一个有效节点开始遍历
 插入  1.准备新节点  2.找合适的插入位置 3.插入
 删除  1.判空   2.申请一个临时指针,指向待删除节点 3.跨越指向(待删除节点的上一个节点保存待删除节点下一个节点的地址)4.将待删除节点释放

代码实现:头文件(这里的指针域保存着下一个节点的地址)

#pragma once

//单链表有效节点的结构体设计
typedef int ELEM_TYPE;
typedef struct Node {
	ELEM_TYPE data;//数据域
	struct Node* next;//指针域
}Node,*PNode;
//头节点借助有效节点的结构体设计
//初始化
void Init_List(PNode pn);
//头插
bool Insert_head(PNode pn,ELEM_TYPE value);
//尾插
bool Inseret_tail(PNode pn, ELEM_TYPE value);
//按位置插入
bool Inseret_pos(PNode pn,int pos, ELEM_TYPE value);
//头删
bool Del_head(PNode pn);
//尾删
bool Del_tail(PNode pn);
//按位置删
bool Del_pos(PNode pn,int pos);
//按值删
bool Del_val(PNode pn, ELEM_TYPE value);
//查找
struct Node* Search(PNode pn, ELEM_TYPE value);
//判空
bool IsEmpty(PNode pn);
//获取有效值个数
int Get_length(PNode pn);
//清空
void Clear(PNode pn);
//销毁1
void Destroy1(PNode pn);
//销毁2
void Destroy2(PNode pn);
//打印
void show(PNode pn);

函数的具体实现:

这里需要注意的是:单链表是插入数据是才去申请新节点,且每次只申请一个,所以不存在满的情况,也就不需要扩容。删除之前,需要先将上一个有效节点指向自身的下一个有效节点,然后再去释放自身(如果不这样的话就会导致后面的有效节点丢失,使用的时候无法找到)

#include"list.h"
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>

//初始化
void Init_List(PNode pn) {
	assert(pn!=NULL);
	pn->next = NULL;
}
//头插
bool Insert_head(PNode pn, ELEM_TYPE value) {
	assert(pn != NULL);
	struct Node* pnewnode=(struct Node*)malloc(sizeof(struct Node));//准备新节点
	assert(pnewnode!=NULL);
	pnewnode->data = value;
	pnewnode->next = NULL;


	pnewnode->next = pn->next;
	pn->next = pnewnode;
	return true;
}
//尾插
bool Inseret_tail(PNode pn, ELEM_TYPE value) {
	assert(pn != NULL);
	struct Node* pnewnode = (struct Node*)malloc(sizeof(struct Node));//准备新节点
	assert(pnewnode != NULL);
	pnewnode->data = value;
	pnewnode->next = NULL;
	struct Node* p=pn;//让指针p也指向头节点
	for (p; p->next != NULL; p = p->next);

	pnewnode->next = p->next;
	p->next = pnewnode;
	return true;
}
//按位置插入
bool Inseret_pos(PNode pn, int pos, ELEM_TYPE value) {
	assert(pn != NULL);
	assert(pos >= 0 && pos <=Get_length(pn));
	struct Node* pnewnode = (struct Node*)malloc(sizeof(struct Node));//准备新节点
	assert(pnewnode != NULL);
	pnewnode->data = value;
	struct Node* p = pn;
	for (int i = 0; i < pos; i++) {
		p = p->next;
	}
	pnewnode->next = p->next;
	p->next = pnewnode;
	return true;
}
//头删
bool Del_head(PNode pn) {
	assert(pn!=NULL);
	if (IsEmpty(pn)) {
		return false;
	}
	struct Node* p = pn->next;
	//跨越指向
	pn->next=p->next;
	free(p);
	p = NULL;
	return 0;
}
//尾删
bool Del_tail(PNode pn) {
	assert(pn != NULL);
	int length = Get_length(pn);
	if (IsEmpty(pn)) {
		return false;
	}
	Del_pos(pn,length-1);
	/*struct Node* p = pn;
	for (p; p->next != NULL; p = p->next);
	struct Node* q = pn;
	for (q; q ->next!= p; q = q->next);
	q->next = NULL;
	free(p);
	p = NULL;*/
	return true;
}
//按位置删
bool Del_pos(PNode pn, int pos) {
	assert(pn != NULL);
	assert(pos>=0&&pos<Get_length(pn));
	if (IsEmpty(pn)) {
		return false;
	}
	struct Node* p = pn;
	for (int i = 0; i < pos; i++) {
		p = p->next;
	}
	struct Node* q = p->next;
	p->next = q->next;
	free(q);
	return true;
}
//按值删
bool Del_val(PNode pn, ELEM_TYPE value) {
	assert(pn != NULL);
	if (IsEmpty(pn)) {
		return false;
	}
	struct Node *p=Search(pn,value);
	if (p == NULL) {
		return false;
	}
	struct Node* q = pn;
	for (q; q->next != p; q = q->next);
	q->next = p->next;
	free(p);
	p = NULL;
	return true;
}
//查找
struct Node* Search(PNode pn, ELEM_TYPE value) {
	assert(pn!=NULL);
	for (struct Node* p = pn->next; p != NULL; p = p->next) {
		if (p->data == value) {
			return p;
		}
	}
	return NULL;
}
//判空
bool IsEmpty(PNode pn) {
	assert(pn!=NULL);
	return pn->next == NULL;
}
//获取有效值个数
int Get_length(PNode pn) {
	assert(pn!=NULL);
	int count = 0;
	for (struct Node* p = pn->next; p != NULL; p = p->next) {
		count++;
	}
	return count;
}
//清空
void Clear(PNode pn) {
	Destroy1(pn);
}
//销毁1  无限头删
void Destroy1(PNode pn) {
	while (!IsEmpty(pn)) {
		Del_head(pn);
	}
	pn->next = NULL;
}
//销毁2  
void Destroy2(PNode pn) {
	assert(pn!=NULL);
	struct Node* p = pn->next;
	struct Node* q;
	pn->next = NULL;
	while (p != NULL) {
		q = p->next;
		free(p);
		p = q;
	}
}
//打印
void show(PNode pn) {
	for (struct Node* p = pn->next; p != NULL; p = p->next) {
		printf("%5d",p->data);
	}
	printf("\n");
}

测试文件:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值