链表的基本操作(笔试重点)

链表是一种线性表,每个节点包含数据和指向下一个节点的指针。由于非顺序存储,链表的插入和删除操作具有O(1)的时间复杂度。本文将探讨单链表的结构及其基本操作,包括增加、删除、修改和查找元素。

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

链表(Linked list)是一种线性表,但是并不会在物理存储上按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表的插入和删除操作可以达到O(1)的复杂度

  • 单链表的结构:

在这里插入图片描述

  • 链表的基本操作(增,删,改,查)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef int data_t;//将int类型用data_t代替

//构造链表节点类型
typedef struct node{
	data_t data;//数据域: 保存链表元素的数值
	struct node* next;//指针域: 保存链表下一个节点的地址
}linklist;

//创建空链表,即链表中只有头节点
linklist *createLinklist(void)
{
	linklist *head = (linklist *)malloc(sizeof(linklist));//给结构体开空间
	if(NULL == head)
		return NULL;
	head->data = -1;//表示data域无效
	head->next = NULL;
	return head;
}
//判断链表是否为空
int linklist_is_empty(linklist *head)
{
	if(NULL != head)
		return ((head->next == NULL) ? 1: 0);
}
//求链表中节点个数
int getLengthLinklist(linklist *head)
{
	if(NULL == head)
		return -1;
	int num = 0;
	linklist *p = head->next;//p指针指向第一个有效节点
	while(p != NULL)
	{
		num++;
		p = p->next;
	}
	return num;
}

//按位置添加节点
/************************************************************
Descrption:按位置添加节点
	int insertLinklistByPos(linklist *head, int pos, data_t data)
Argument:
	head:链表头节点的地址
	pos:要插入节点的地址 pos:从0开始
	data:要插入节点的data值
Return:
	成功:0
	失败:-1
************************************************************/
int insertLinklistByPos(linklist *head, int pos, data_t data)
{
	if(NULL== head)
		return -1;
	int len = getLengthLinklist(head);//得到链表节点的个数

	//判断位置是否有效  
	if(pos < 0 || pos > len)//有效位置为 0 ~ len
		return -1;
	//给新节点开空间
	linklist *new = (linklist *)malloc(sizeof(linklist));
	new->data = data;//将要插入的data值赋给新节点的data
	new->next = NULL;
	linklist *p = head;
	
	//找到pos-1位置处节点的地址
	while(pos--)
		p = p->next;	
	//将新节点插入到p节点之后
	new->next = p->next;
	p->next = new;
	return 0;
}

//按位置删除链表中节点
/**********************************************
Description:按位置删除链表中节点
	int deleteLinklistByPos(linklist *head, int pos)
Argument:
	head:链表头节点的地址
	pos:指定要删除节点的位置
Return:
	成功:0
	失败:-1
**********************************************/
int deleteLinklistByPos(linklist *head, int pos)
{
	if(NULL == head)
		return -1;
	//判空
	if(linklist_is_empty(head))
		return -1;
	int len = getLengthLinklist(head);
	//判断位置是否有效
	if(pos < 0 || pos > len-1)//有效位置为 0 ~ len-1
		return -1;
	
	linklist *p = head;
	while(pos--) //找到 pos-1 位置处节点的地址
		p = p->next;
	linklist *q = p->next;//q指针用来保存要删除节点的地址
	p->next = q->next;//将q节点的前一个节点和后一个节点连接
	free(q);
	q = NULL;
	return 0;
}

//按值删除节点
int deleteLinklistByData(linklist *head, data_t data)
{
	if(NULL == head)
		return -1;
	if(linklist_is_empty(head))
		return -1;
	linklist *p = head;
	linklist *q = NULL;
	while(p->next != NULL)
	{
		if(p->next->data == data)
		{
			q = p->next;
			p->next = q->next;
			free(q);
			q = NULL;
		}
		else
			p = p->next;
	}
			return 0;
}

//按值查找节点,返回节点的地址
/*******************************************************
Descrption:按值查找节点,返回节点的地址
	linklist *findLinklistByData(linklist *head, data_t data)
Argument:
	head:链表头节点的地址
	data:要查找的节点的data值
Return:
	成功:查找到的值为data的节点的地址
	失败:NULL
*******************************************************/
linklist *findLinklistByData(linklist *head, data_t data)
{
	if(NULL == head)
		return NULL;
	if(linklist_is_empty(head))//判空
		return NULL;
	linklist *p = head->next;//p指针指向第一个有效节点	
	while(p != NULL)//循环遍历整个链表
	{
		if(p->data == data)//比较链表节点的值是否为 data
			return p;
		else
			p = p->next;
	}
	return NULL;
}

//按位置查找
data_t findLinklistByPos(linklist *head, int pos)
{
	if(head == NULL)
		return -1;
	int len = getLengthLinklist(head);
	if(pos < 0 || pos > len-1)
		return -1;
	linklist *p = head->next;
	while(pos--) //p指向pos位置节点
		p = p->next;
	return (p->data);

}

//按位置修改链表节点的值
int changeLinklistByPos(linklist *head, int pos, data_t data)
{
	if(NULL == head)
		return -1;
	int len = getLengthLinklist(head);
	if(pos < 0 || pos > len-1)
		return -1;

	linklist *p = head->next;
	while(pos--)
		p = p->next;
	p->data = data;
	return 0;

}

//按值修改链表节点的值
int changeLinklistByData(linklist *head, data_t old, data_t new)
{
	linklist *p = findLinklistByData(head, old);
	if(NULL == p)
		return -1;
	p->data = new;

	return 0;
}

//清空链表
int clearLinklist(linklist *head)
{
	if(NULL == head)
		return -1;
	linklist *p = head->next;
	head->next = NULL;
	linklist *q = NULL;

	while(p != NULL)
	{
		q = p->next;//q保存p的下一个节点的地址
		free(p);
		p = q;
	}
	return 0;
}

//销毁链表
void destoryLinklist(linklist **head)
{
	clearLinklist(*head);
	free(*head);
	*head = NULL;
}

//链表的逆序 基于头节点的插入  重点
int reverseLinklist(linklist *head)
{
	if(NULL == head)
		return -1;
	linklist *p = head->next;
	head->next = NULL;
	linklist *q = NULL;
	
	while(p != NULL)
	{
		q = p->next;
		p->next = head->next;
		head->next = p;
		p = q;
	}
	return 0;
}

//打印链表中各个节点的data值
void printLinklist(linklist *head)
{
	if(NULL == head)
		return;

	linklist *p = head->next;//p指针指向第一个有效节点
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
	return ;
}

//主函数
int main()
{
	linklist *head = createLinklist();
	if(NULL == head)
	{
		printf("malloc failed\n");
		return -1;
	}

	int i=0;
	while(i<10)
	{
		insertLinklistByPos(head, i, i+1);
		i++;
	}
	printLinklist(head);
	
	i=0;
	while(i < 5)
	{
		deleteLinklistByPos(head, 0);
		i++;
	}
	printLinklist(head);

	linklist *p = findLinklistByData(head, 8);
	if(NULL == p)
	{
		printf("No find data\n");
		return -1;
	}
	printf("p->data=%d\n",p->data);
	
	changeLinklistByPos(head, 1, 100);
	printLinklist(head);

	changeLinklistByData(head, 100, 7);
	printLinklist(head);

	reverseLinklist(head);
	printLinklist(head);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值