C语言使用数组实现链表功能

工作原理

直白的说该代码原理就是通过两个数组,一个数组1存放数据,一个数组2存放地址,数组1和数组2的第n个数据共同组成一个链表节点

代码实现初始化:

c 复制代码
/*存储链表数据的数组*/
char s_data[1024] = {0};
/*存储链表下一位成员地址的数组*/
char s_next[1024] = {-1};
/*记录当前链表长度*/
int Q_len = 0; 
/*记录链表头*/
int head = -1 ,tail = -1; 

/*
#名  称# initStack
#作  用# 初始化地址数组,全部为-1,为无指向 
#参  数# 无
#返回值# 无 
*/ 
void initStack(void)
{
	memset(s_next,-1,sizeof(s_next));
} 

头插

实现思路

假设链表数组如上图所示

数组2为该节点指向的下一个节点的地址,-1表示该节点为尾节点

以上述链表做头插操作,插入数据4有以下结果:

假设1地址的值为原链表的头,我们将新插入的数据放入4地址(数组1[4] = 4),并将他的下一个节点指向地址1(数组2[4] = 1)

代码实现头插操作

c 复制代码
/*
#名  称# add_Head_Stack
#作  用# 由链表头插入链表 
#参  数# 需要插入的数据 
#返回值# 无 
*/ 
void add_Head_Stack(char data)
{
	/*无论如何新加入的节点都是数组的第Q_len个*/ 
	s_data[Q_len] = data;
	/*将新节点的下一个地址指向旧的头地址*/ 
	s_next[Q_len] = head;
	/*头地址更新*/ 
	head = Q_len;
	/*如果是第一个节点,既是头也是尾*/ 
	if(head == 0)tail=0;
	/*每次加完节点,链表长度++*/ 
	Q_len++;
} 

尾插

实现思路

仍然以这张图为基础进行尾插操作,有以下结果:

将原来尾节点的,下一个节点地址赋值为4(数组2[3] = 4),在4地址新加入一个节点,因为尾节点故下一个节点的地址为-1(数组2[4] = -1)

代码实现尾插操作

c 复制代码
/*
#名  称# add_Tail_Stack
#作  用# 由链表头插入链表 
#参  数# 需要插入的数据 
#返回值# 无 
*/ 
void add_Tail_Stack(char data)
{
	s_data[Q_len] = data;
	s_next[tail] = Q_len;
	tail = Q_len;
	if(tail == 0)head=0;
	Q_len++;
} 

遍历

实现思路

1、判断链表是否为空

2、由链表头开始,如果该节点有后继节点进入循环

3、输出节点的数据,并将当前节点赋值为当前节点的后继节点

4、当跳出循环,则当前为尾节点,输出尾节点

5、遍历完成

代码实现

c 复制代码
/*
#名  称# read_Stack
#作  用# 遍历链表 
#参  数# 链表头地址 
#返回值# 无 
*/ 
void read_Stack(int p)
{
	/*判断链表是否为空*/ 
	if(p == -1)
	{
		return; 
	} 
	/*循环遍历链表,链表尾跳出循环*/ 
	while(s_next[p] != -1)
	{
		printf("%d ",s_data[p]);
		p = s_next[p];
	}
	/*打印链表尾*/ 
	printf("%d ",s_data[p]);
}

将节点插入指定节点的后面

实现思路

1、我们需要先找到链表的第n个节点存在数组的哪个地址

2、找到地址后,我们需要将新节点的后继节点地址赋值为找到的节点的后继节点地址

3、找到的节点的后继节点地址改变为新节点地址

代码实现

c 复制代码
/*
#名  称# find_Stack
#作  用# 找到第n个节点 
#参  数# p链表头地址   node_n需要找的第node_n个节点
#返回值# 找到的地址 
*/ 
int find_Stack(int p,int node_n)
{
	int i;
	if(p==-1)return -1; 
	
	for(i = 1;i<node_n;i++)
	{
		p = s_next[p];
	} 
	
	return p;
} 

/*
#名  称# add_find_Stack
#作  用# 插入到第n个node后面 
#参  数# data 需要插入的数据  node_n插到第几个数后面 
#返回值# 无 
*/ 
void add_Find_Stack(int p,char data,int node_n)
{
	/*取出插入地址前一个节点的地址*/
	int p_node = find_Stack(p,node_n);
	
	if(p_node==-1)return;
	
	s_data[Q_len] = data; 
	s_next[Q_len] = s_next[p_node]; 
	s_next[p_node] = Q_len;
	
	Q_len++;
} 

验证代码

c 复制代码
#include <stdio.h>
#include <stdlib.h>

/*存储链表数据的数组*/
char s_data[1024] = {0};
/*存储链表下一位成员地址的数组*/
char s_next[1024] = {-1};
/*记录当前链表长度*/
int Q_len = 0; 
/*记录链表头*/
int head = -1 ,tail = -1; 

/*
#名  称# initStack
#作  用# 初始化地址数组,全部为-1,为无指向 
#参  数# 无
#返回值# 无 
*/ 
void initStack(void)
{
	memset(s_next,-1,sizeof(s_next));
} 

/*
#名  称# add_Head_Stack
#作  用# 由链表头插入链表 
#参  数# 需要插入的数据 
#返回值# 无 
*/ 
void add_Head_Stack(char data)
{
	/*无论如何新加入的节点都是数组的第Q_len个*/ 
	s_data[Q_len] = data;
	/*将新节点的下一个地址指向旧的头地址*/ 
	s_next[Q_len] = head;
	/*头地址更新*/ 
	head = Q_len;
	/*如果是第一个节点,既是头也是尾*/ 
	if(head == 0)tail=0;
	/*每次加完节点,链表长度++*/ 
	Q_len++;
} 

/*
#名  称# add_Tail_Stack
#作  用# 由链表头插入链表 
#参  数# 需要插入的数据 
#返回值# 无 
*/ 
void add_Tail_Stack(char data)
{
	s_data[Q_len] = data;
	s_next[tail] = Q_len;
	tail = Q_len;
	if(tail == 0)head=0;
	Q_len++;
} 

/*
#名  称# find_Stack
#作  用# 找到第n个节点 
#参  数# p链表头地址   node_n需要找的第node_n个节点
#返回值# 找到的地址 
*/ 
int find_Stack(int p,int node_n)
{
	int i;
	if(p==-1)return -1; 
	
	for(i = 1;i<node_n;i++)
	{
		p = s_next[p];
	} 
	
	return p;
} 

/*
#名  称# add_find_Stack
#作  用# 插入到第n个node后面 
#参  数# data 需要插入的数据  node_n插到第几个数后面 
#返回值# 无 
*/ 
void add_Find_Stack(int p,char data,int node_n)
{
	/*取出插入地址前一个节点的地址*/
	int p_node = find_Stack(p,node_n);
	
	if(p_node==-1)return;
	
	s_data[Q_len] = data; 
	s_next[Q_len] = s_next[p_node]; 
	s_next[p_node] = Q_len;
	
	Q_len++;
} 

/*
#名  称# read_Stack
#作  用# 遍历链表 
#参  数# 链表头地址 
#返回值# 无 
*/ 
void read_Stack(int p)
{
	/*判断链表是否为空*/ 
	if(p == -1)
	{
		return; 
	} 
	/*循环遍历链表,链表尾跳出循环*/ 
	while(s_next[p] != -1)
	{
		printf("%d ",s_data[p]);
		p = s_next[p];
	}
	/*打印链表尾*/ 
	printf("%d ",s_data[p]);
}

int main(void)
{
	initStack();
	
	add_Tail_Stack(5);
	add_Head_Stack(1);
	add_Head_Stack(2);
	add_Head_Stack(3);
	add_Head_Stack(4);
	add_Tail_Stack(6);
	
	add_Find_Stack(head,10,3);
	
	read_Stack(head);
}
相关推荐
嵌入式学习和实践21 小时前
C语言-BCD码转换为十进制的测试和说明
c语言·转换·bcd码
喵了meme1 天前
C语言实战4
c语言·开发语言
智者知已应修善业1 天前
【求中位数】2024-1-23
c语言·c++·经验分享·笔记·算法
程序员zgh1 天前
Linux系统常用命令集合
linux·运维·服务器·c语言·开发语言·c++
Bigan(安)1 天前
【奶茶Beta专项】【LVGL9.4源码分析】09-core-obj_class对象类系统
linux·c语言·mcu·arm·unix
程序员zgh1 天前
常用通信协议介绍(CAN、RS232、RS485、IIC、SPI、TCP/IP)
c语言·网络·c++
Bigan(安)1 天前
【奶茶Beta专项】【LVGL9.4源码分析】08-theme主题管理
linux·c语言·mcu·arm·unix
了一梨1 天前
外设与接口:按键输入 (libgpiod)
linux·c语言
昔时扬尘处1 天前
【Files Content Replace】文件夹文件内容批量替换自动化测试脚本
c语言·python·pytest·adi
芯联智造1 天前
【stm32简单外设篇】- 28BYJ-48 步进电机(配 ULN2003 驱动板)
c语言·stm32·单片机·嵌入式硬件