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地址(数组14 = 4),并将他的下一个节点指向地址1(数组24 = 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(数组23 = 4),在4地址新加入一个节点,因为尾节点故下一个节点的地址为-1(数组24 = -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);
}
相关推荐
Navigator_Z6 小时前
LeetCode //MySQL - 1251. Average Selling Price
c语言·算法·leetcode
Escalating_xu7 小时前
【C语言数据类型和变量·上】从内置类型到变量模型:一次讲透 sizeof、signed/unsigned 与作用域
c语言
aramae7 小时前
模拟实现strlen()函数 (C语言)
c语言·开发语言·后端
多弗朗皮卡丘10 小时前
数据结构9:排序算法
c语言·数据结构·排序算法
老当益壮梁奶奶14 小时前
ARM 汇编学习笔记(二)启动代码、指令、函数调用与 C 混合编程
c语言·arm开发·单片机·嵌入式硬件·51单片机
wuminyu15 小时前
Markword在紧凑对象头上的实现原理剖析
java·linux·c语言·jvm·c++
潘潘的嵌入式日记15 小时前
位操作怎么写才不出错?置位、清位、翻转、取位一次讲清
c语言·嵌入式·寄存器·位操作
无忧.芙桃16 小时前
数据结构之排序算法(上):从评价指标到插入、希尔、选择与堆排序
c语言·c++·排序算法
SuperByteMaster16 小时前
configUSE_TIME_SLICING和configUSE_PREEMPTION
c语言
周杰偷奶茶16 小时前
【C 语言】分支、循环和 goto 语句(附实战)
c语言