工作原理
直白的说该代码原理就是通过两个数组,一个数组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);
}