2021-04-23

这篇博客详细介绍了链表的基础知识,包括如何创建节点、建立空链表、在不同位置插入和删除元素、清空链表、计算链表长度等操作。此外,还提供了带头结点和不带头结点的链表实现源码,以及查找、删除特定值的节点等高级操作。这些内容对于理解和操作链表非常有帮助。
摘要由CSDN通过智能技术生成

链表最全的相关知识及源码(包括如何创建结点、建立一个空链表、插入、删除、清空、求长度等等)

均采用函数封装形式给出,望各位大佬批评指正:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int Element;
typedef struct node {       //结点结构体定义
	Element data;
	struct node* next;
}ListNode;
typedef ListNode* LinkList;     //链表指针定义
void InsertLinkList(LinkList& first, int x, int i) {   //不带头结点的链表,在链表第i个节点处前插入新元素x
	ListNode* p = first;
	int k = 0;
	while (p != NULL && k < i - 1) {                  //找到第i-1个结点
		p = p->next;
		k++;
	}
	if (p == NULL && first != NULL) {                 //位置无效
		printf("无效的插入位置!\n");
	}
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));  //建立新结点
	newnode->data = x;       //完成赋值
	if (first == NULL || i == 1) {     //插入空表或非空表第一个结点之前
		newnode->next = first;
		first = newnode;
	}
	else {                            //在中间插入
		newnode->next = p->next;
		p->next = newnode;
	}
}
int DeleteLinkList(LinkList& first, int i) {       //不带头结点的链表,删除第i个结点
	ListNode* p, * q;
	if (i == 0) {                                   //默认第1个结点是首元结点,头结点不算一个结点
		q = first;
		first = first->next;
	}
	else {                    
		p = first;
		int k = 0;
		while (p != NULL && k < i - 1) {            //先找到第i-1个结点
			p = p->next;
			k++;
			return 0;
		}
		if (p == NULL || p->next == NULL) {         //没有找到结点
			printf("无效位置\n");
			exit(1);
		}
		else {                                        //改变链表路径
			q = p->next;
			p->next = q->next;
		}
	}
	int k = q->data;                                //设置k为一个存储器,保存被删掉结点的数据
	free(q);                                        //释放被删掉的结点
	return k;                                       //返回被删掉结点的值
}
int insertl(LinkList first, Element x, int i) {      //带头结点的链表插入元素1
	int k = 0;
	ListNode* p = first;
	while (k < i-1) {                               //找寻第i-1个结点
		p = p->next;
	}
	if (p == NULL) {                                //无效位置
		printf("输入的位置无效!\n");
		return 0;
	}
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));      //建立新结点
	newnode->data = x;                                            //为新结点赋值
	newnode->next = p->next;                                      //插入新结点
	p->next = newnode;
	return 1;
}
int deletel (LinkList first, int i) {               //删除带头结点的链表
	ListNode* q, * p = first;
	int k = 0;
	while (k < i-1) {                               //找到第i-1个结点
		p = p->next;
	}
	if (p == NULL || p->next == NULL) {             //无效位置进行退出并返回0
		printf("输入的位置无效!\n");
		return 0;
		exit(1);
	}
	q = p->next;                                    //删除目标结点
	p->next = q->next;
	free(q);                                        //释放目标结点
	return 1;
}
int LengthLinkList(LinkList first) {                //求线性链表的长度
	ListNode* p;
	p = first->next;                                //从首元结点处开始计数
	int count = 0;
	while (p == NULL) {
		p = p->next;
		count++;
	}
	return count;
}
void MakeEmpty(LinkList first) {                    //删去链表中除表头结点外的所有其他结点
	ListNode* q;
	while (first->next != NULL) {                   //当链不空时,循环逐个删去所有结点
		q = first->next;
		first->next = q->next;
		free(q);
	}
}
ListNode* FindLinkList(LinkList first, Element value) {      //按值查找
	ListNode* p;
	p = first->next;                                 //指向首元结点
	while (p != NULL && p->data != value) {
		p = p->next;
	}
	if (p->data == value) return p;
	else {
		printf("woc,没找到!\n");
		exit(1);
	}
}
ListNode* Locate(LinkList first, int i) {            //返回表中第i个元素的地址1(带头结点)
	ListNode* p;
	int k = 0;
	if (i < 0) {
		printf("输入的位置无效!\n");
		exit(1);
	}
	p = first;
	while (k < i) {
		p = p->next;
		k++;
	}
	if (k = i) return p;
	else return NULL;
}
void CreateLinkList(LinkList* first, int n) {         //创建链表,类似于尾插
	int i;
	(*first) = (LinkList)malloc(sizeof(ListNode));    //建立头结点
	ListNode* p = *first;
	for (i = 0; i < n; i++) {
		ListNode* q = (ListNode*)malloc(sizeof(ListNode));      //动态内存分配
		scanf("%d", &q->data);
		p->next = q;                           //尾插法建立新链表
		p = q;
	}
	p->next = NULL;
}
//设计一个算法,在带头结点的单链表L中删除所有值为x的结点并释放空结点   注:x不唯一
void del(LinkList* first,int x) {
	ListNode* p = (*first)->next;
	ListNode* pre = *first;
	while (p != NULL) {
		if (p->data == x) {
			ListNode* q = p->next;
			pre->next = q->next;
			free(q);
		}
		else {
			pre = p;
			p = p->next;
		}
	}
}
//设计一个算法,在带头结点的单链表L中删除一个最小值结点,假设其唯一
void MinDel(LinkList* first) {
	ListNode* minp = (*first)->next, * minpre = (*first);
	ListNode* pre = *first,* p = minp;
	while (p != NULL) {
		if (p->data < minp->data) {
			minp = p;
			minpre = pre;
		}
			pre = p;
			p = p->next;
	}
	minpre->next = minp->next;
	free(minp);
}
//设计一个算法,将线性链表a,分解成为b和c  注:a的结构为{b1,c1,b2,c2,b3,c3.....}
void split(LinkList* a, LinkList* b, LinkList* c) {
	ListNode* p = (*a)->next;
	b = a;
	(*c) = (ListNode*)malloc(sizeof(ListNode));
	if (b == NULL || c == NULL) {
		printf("拆分算法分配头结点失败,自动退出!\n");
		exit(1);
	}
	ListNode* q = (*c), * pre = (*a);
	while (p != NULL) {
		p = p->next;
		if (p != NULL) {
			q->next = p;
			q = p;
		}
	}
}
void PrintfLinkList(LinkList* first) {                //输出新链表
	ListNode* q = (*first)->next;
	if ((*first)->next == NULL) {
		printf("注意,此链表为空!\n");
	}
	while (q != NULL) {
		printf("%d\n", q->data);
		q = q->next;
	}
}

我会一直保持更新的,

如果对大家有所帮助的话,可以评论、点赞、收藏和转发哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值