单向链表C语言实现

本文深入讲解了链表的基本操作,包括创建、插入、查找、删除、打印和销毁等,通过具体的C语言实现代码,帮助读者理解链表的工作原理和常见算法。

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

list.h

#pragma once
#ifndef _LIST_H
#define _LIST_H
struct Node
{
	int data;
	struct Node * next;
};

struct Header
{
	int length;
	struct Node * next;
};

typedef struct Node List;
typedef struct Header pHead;

pHead* createList();
int Size(pHead* ph);
int isEmpty(pHead* l);
int Insert(pHead* l, int pos, int val);
List* Delete(pHead* l, int ele);
List* find(pHead* l, int ele);
void Destory(pHead * l);
void print(pHead* l);


#endif // !_LIST_H

Operation.cpp

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

pHead* createList()
{
	pHead* ph = (pHead*)malloc(sizeof(pHead));//为头结点分配空间
	ph->length = 0;
	ph->next = NULL;
	return ph;
}

int Size(pHead* ph)//获取链表长度
{
	if (ph == NULL)
	{
		printf("传入参数有误");
		return 0;
	}
	return ph->length;
}

int Insert(pHead* ph, int pos, int val)
{
	//健壮性判断
	if (ph == NULL || pos < 0 || pos > ph->length)
	{
		printf("传入参数有误");
		return 0;
	}
	//向链表中插入元素时,首先要找到这个位置
	List * pval = (List*)malloc(sizeof(List));
	pval->data = val;
	List *pCur = ph->next;//当前指针指向头结点后的第一个结点
	if (pos == 0)
	{
		ph->next = pval;//如果插入位置是0,那么先将头结点指向新的结点
		pval->next = pCur;//新的结点指向原来的第一个结点
	}
	else
	{
		for (int i = 1; i < pos; i++)
		{
			pCur = pCur->next;//找到要插入的位置,使得当前指针指向插入位置
		}

		pval->next = pCur->next;//新结点的指针指向当前位置后一个
		pCur->next = pval;//当前指针(插入位置)指向新插入的节点。
	}
	ph->length++;
	return 1;
}

//查找某个元素的效率比较低,对于链表要遍历查找
List *find(pHead* ph, int val)
{
	//健壮性判断
	if (ph == NULL)
	{
		printf("传入参数有误");
		return 0;
	}
	//遍历链表查找元素val
	List *pTmp = ph->next;//使得pTmp指向链表的第一个结点
	do
	{
		if (pTmp->data == val)
		{
			return pTmp;
		}
		pTmp = pTmp->next;
	} while (pTmp->next != NULL);
	printf("没有值为%d的元素", val);
	return NULL;
}
//删除某个元素效率也比较高
List *Delete(pHead *ph, int val)
{
	if (ph == NULL)
	{
		printf("传入的链表有误");
		return 0;
	}
	//找到val所在的结点
	List *pval = find(ph, val);
	if (pval == NULL)
	{
		printf("没有值为%d的元素", val);
		return NULL;
	}

	//遍历链表找到要删除的结点,并找出其前驱及后继结点
	List *pRe = ph->next;//当前结点
	List *pCur = NULL;
	if (pRe->data == val)//如果删除的是第一个结点
	{
		ph->next = pRe->next;
		ph->length--;
		return pRe;
	}
	else
	{
		for (int i = 0; i < ph->length; i++)
		{
			pCur = pRe->next;
			if (pCur->data == val)
			{
				pRe->next = pCur->next;
				ph->length--;
				return pCur;
			}
			pRe = pRe->next;
		}
	}
}
//销毁链表
void Destory(pHead *ph)
{
	List * pCur = ph->next;//pCur指向第一个结点
	List *pTmp;
	if (ph == NULL)
	{
		printf("输入链表有误");
	}

	while (pCur->next != NULL)
	{
		pTmp = pCur->next;
		free(pCur);
		pCur = pTmp;
	}
	ph->length = 0;
	ph->next = NULL;
}

//遍历打印链表
void print(pHead *ph)
{
	if(ph == NULL)
		printf("输入链表有误");
	List *pTmp = ph->next;
	while (pTmp != NULL)
	{	
		printf("%d  ", pTmp->data);
		pTmp = pTmp->next;
	}
	printf("\n");
}

main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"list.h"

int main()
{
	List* ret;
	pHead* ph = createList();
	if (ph == NULL)
		printf("创建链表失败!\n");
	int arr[10] = { 1,2,3,4,56,76,7,4,36,34 };//定义一个int型数组

	for (int i = 0; i <= 6; i++)
	{
		Insert(ph, 0, arr[i]);
	}

	printf("链表长度:%d\n",Size(ph));
	printf("打印链表中的长度:\n");
	print(ph);
	printf("删除链表中的元素,请输入要删除的元素:\n");
	int num;
	scanf("%d", &num);
	Delete(ph, num);
	printf("元素删除成功,删除元素%d后,链表中元素为:\n",num);
	print(ph);

	ret = find(ph,3);
	if (ret)
		printf("Get!");
	else
		printf("NO!\n");
	system("pause");
	return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值