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);
}
相关推荐
智者知已应修善业1 小时前
【51单片机32个灯,第一次亮1,2。第二次亮2,3。第三次亮3,4。。。。】2023-2-10
c语言·经验分享·笔记·嵌入式硬件·51单片机
无限进步_2 小时前
【C语言】寻找数组中唯一不重复的元素
c语言·开发语言·算法
JuneXcy2 小时前
C语言易错点大总结
c语言·嵌入式硬件·算法
迎風吹頭髮4 小时前
UNIX下C语言编程与实践39-UNIX 定时器:alarm 函数与 setitimer 函数的使用与对比
服务器·c语言·unix
2401_841495644 小时前
【数据结构】链栈的基本操作
java·数据结构·c++·python·算法·链表·链栈
egoist20234 小时前
[linux仓库]System V 进程通信详解:System V消息队列、信号量
linux·c语言·消息队列·pv·信号量
Archie_IT5 小时前
「深入浅出」嵌入式八股文—P2 内存篇
c语言·开发语言·数据结构·数据库·c++·算法
XCOSnTh6 小时前
单片机入门的相关工具XCOSnTh
c语言·单片机·嵌入式硬件·xcosnth·单片机入门
byte轻骑兵6 小时前
Windows 安全分割利器:strtok_s () 详解
c语言·开发语言·windows·安全
迎風吹頭髮9 小时前
UNIX下C语言编程与实践41-UNIX 单线程 I/O 超时处理:终端方式、信号跳转方式与多路复用方式
c语言·php·unix