C语言单链表

C语言单链表

单向链表

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

typedef struct node
{
	int data;
	struct node *next;
}st,*pt;

pt node_init(void);					//初始化节点
void add_head(pt head,int data);	//头插
void add_tail(pt head,int data);	//尾插
void del_node(pt head,int data);	//删除
void show(pt head);					//查看


int main(int argc, char const *argv[])
{
	int num;
	pt head = node_init();

	while(1)
	{
		printf("请输入:");
		scanf("%d",&num);while(getchar() != '\n');
		printf("──────────────────────────────\n");
		if(num > 0)
		{
			add_tail(head,num);		//输入正数则添加
		}
		else if(num < 0)
		{
			del_node(head,-num);	//输入负数则删除
		}
		else
			return 0;

		printf("──────────────────────────────\n");
		show(head);
		printf("──────────────────────────────\n");

	}
	return 0;
}


//初始化一个新节点
pt node_init(void)
{
	pt head = (pt)malloc(sizeof(st));
	if(head == NULL)
	{
		perror("init failed");
		return NULL;
	}
	head->next = NULL;
	return head;

}


//头插
void add_head(pt head,int data)
{
	pt new_node = node_init();
	if(new_node == NULL)
	{
		perror("new_node failed");
		return;
	}
	new_node->data = data;

	new_node->next = head->next;	//偷偷指向头节点下一个
	head->next = new_node;			//顺序不能换,否则链表断开
	printf("加入成功\n");

}


//尾插
void add_tail(pt head,int data)
{
	pt new_node = node_init();
	if(new_node == NULL)		//判断分配空间是否成功
	{
		perror("new_node failed");
		return;
	}
	new_node->data = data;		//数据给新节点
	new_node->next = NULL;		//指向空

	pt pos = head;
	while(pos->next != NULL)	//遍历到末尾
	{
		pos = pos->next;
	}

	pos->next = new_node;		//原末尾指针指向新节点
	printf("加入成功\n");

}


//删除
void del_node(pt head,int data)
{
	if(head->next == NULL)
	{
		printf("空链表\n");
		return;
	}
		
	int flag = 0;
	pt pos = head->next;
	pt pre = head;
	while(pos != NULL)			//循环遍历查找
	{
		if(data == pos->data)
		{	
			flag++;				//每找到一个,加一
			pre->next = pos->next;
			pos->next = NULL;
			free(pos);			//释放空间(只是释放空间,不是删除变量)
			pos = pre;			//重新指向一个位置

		}
		pre = pos;			
		pos = pos->next;
	}
	if(flag)
	{
		printf("已删除%d个\n", flag);
		return ;
	}
	else
	{
		printf("删除失败,无此数据\n");
		return ;
	}
}


//显示
void show(pt head)
{
	pt pos = head->next;
	while(pos != NULL)
	{
		printf("%d\n", pos->data);
		pos = pos->next;
	}

}

### C语言单链表的实现与操作 #### 基本概念 在C语言中,单链表是一种动态数据结构,由一系列节点组成。每个节点包含两部分:一部分用于存储数据,另一部分是一个指向下一个节点的指针。 为了便于操作,通常会引入头结点的概念[^2]。头结点不存储实际的数据,仅作为辅助节点存在,可以简化边界条件处理。 #### 头文件的引入 使用单链表时,需包含必要的头文件以支持内存分配和字符串操作等功能: ```c #include "stdio.h" #include "stdlib.h" // 提供 malloc() 和 free() #include "string.h" // 提供 strcpy() 等函数 ``` 这些头文件提供了创建、初始化以及销毁链表所需的工具[^1]。 #### 节点定义 单链表的核心在于其节点的设计。以下是典型的节点定义方式: ```c typedef struct LNode { int data; // 数据域 struct LNode *next; // 指向下一节点的指针 } LNode, *LinkList; ``` 这里 `LNode` 定义了一个节点类型,而 `LinkList` 是指向该类型的指针变量。 #### 创建单链表 可以通过多种方法来构建单链表,常见的有 **尾插法** 和 **头插法**: ##### 尾插法 尾插法是从链表头部开始逐步插入新节点到链表末尾的方式。 ```c void CreateList_Tail(LinkList &L, int n) { LinkList p, r = L; // 初始化工作指针r为头结点 for(int i=0;i<n;i++) { p = (LinkList)malloc(sizeof(LNode)); scanf("%d", &(p->data)); // 输入数据 p->next = NULL; r->next = p; // 插入到最后一个节点之后 r = p; // 更新最后一个节点位置 } } ``` ##### 头插法 头插法则是在每次插入时都将新节点放置于当前链表的第一个有效节点之前。 ```c void CreateList_Head(LinkList &L, int n){ LinkList p; for(int i=0;i<n;i++){ p=(LinkList)malloc(sizeof(LNode)); scanf("%d",&(p->data)); // 输入数据 p->next=L->next; // 新节点连接至原首节点前 L->next=p; // 修改头结点指向新的第一个节点 } } ``` #### 查找操作 对于按位查找的功能,在已知索引的情况下可以直接遍历链表找到对应位置上的元素[^3]。时间复杂度一般为 O(n),其中 n 代表链表长度。 ```c int GetElem(LinkList L, int index){ if(index<0 || !L->next)return -1; // 判断输入合法性 LinkList p = L->next; while(p && --index>0)p=p->next; return p?p->data:-1; } ``` #### 删除操作 删除指定位置处的节点需要先定位目标节点及其前置节点,随后调整指针关系完成移除过程。 ```c bool DeleteElem(LinkList &L,int pos){ if(pos<=0||!L->next)return false; LinkList pre=L,p=L->next; for(int i=1;p&&i<pos;i++,pre=p,p=p->next); if(!p)return false; pre->next=p->next; free(p);return true; } ``` #### 存储应用实例——学生信息管理 利用上述基础功能可进一步扩展应用于具体场景下,比如建立一个简单的学生信息系统[^4]: ```c struct Student{ char name[20]; int score; struct Student *next; }; // 添加学生记录... ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值