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);
}
相关推荐
知识领航员20 小时前
蘑兔AI音乐深度实测:功能拆解、实测表现与适用场景
java·c语言·c++·人工智能·python·算法·github
如何原谅奋力过但无声21 小时前
【灵神高频面试题合集06-08】反转链表、快慢指针(环形链表/重排链表)、前后指针(删除链表/链表去重)
数据结构·python·算法·leetcode·链表
程序leo源1 天前
C语言知识总结
c语言·开发语言·c++·经验分享·笔记·青少年编程·c#
爱编码的小八嘎1 天前
C语言完美演绎9-30
c语言
爱编码的小八嘎1 天前
C语言完美演绎9-28
c语言
笨笨饿1 天前
80_聊聊SPI以及它们的变体
linux·c语言·网络·stm32·单片机·算法·个人开发
坚果派·白晓明1 天前
【鸿蒙PC三方库移植适配框架解读系列】第四篇:构建执行、产物获取与 HAP 集成
c语言·华为·harmonyos·鸿蒙·c/c++三方库
Cinema KI1 天前
Linux C/C++ 编译构建:GCC/G++ + Makefile 零基础完整教程
linux·c语言·c++
念恒123061 天前
基础IO(文件缓冲区)
linux·c语言·c++
_深海凉_1 天前
LeetCode热题100-两两交换链表中的节点
算法·leetcode·链表