静态链表
静态链表和单链表其实很相似,只是做的方法不同。再来复习一遍,单链表的一个节点会存放数据域和指针域,指针域存放下一个节点的指针地址。静态链表分为数据与和游标,游标是记录下一个元素在数组中的位置,其实静态链表更像数组。只要我们调整思路,就很好理解了!
首先,创建结构体和头文件等
#include <stdio.h>
#define maxSize 7 //定义备用链表大小
typedef struct {
char data;//数据域
int cur;//游标
}component;
void reserveArr(component *array);//创建一个备用链表
int initArr(component *array);//初始化链表
void insertArr(component * array,int body,int add,char a);//插入数据
void deletArr(component * array,int body,char a);//删除数据
int selectElem(component * array,int body,char elem);//查询元素
void amendElem(component * array,int body,char oldElem,char newElem);//修改元素
void displayArr(component * array,int body);//打印数据
int mallocArr(component * array);//分配空闲的备用链表
void freeArr(component * array,int k);//将无用的数据放回备用表以便下次使用
静态链表是在指定的一块内存中存放数据,所以我们要创建一个备用链表用来存放数据
void reserveArr(component *array){//创建一个备用链表
int i;
for (i=0; i<maxSize; i++) {
array[i].cur=i+1;
}
array[maxSize-1].cur=0;
}
分配空间
int mallocArr(component * array){
int i=array[0].cur;
if (array[0].cur) {
array[0].cur=array[i].cur;
}
return i;//每次返回一个未使用的游标
}
初始化静态链表
int initArr(component *array){
reserveArr(array);//创建备用链表
int body=mallocArr(array);分配一个游标
int tempBody=body;//将游标赋值给另一个变量
int i;
for (i=1; i<5; i++) {//插入数据
int j=mallocArr(array);//分配游标
array[tempBody].cur=j;
array[j].data='a'+i-1; //这里最后还是会转成char类型
tempBody=j;
}
array[tempBody].cur=0;
return body;
}
打印数据,这里不做过多解释
void displayArr(component * array,int body){
int tempBody=body;
while (array[tempBody].cur) {
printf("%c,%d ",array[tempBody].data,array[tempBody].cur);
tempBody=array[tempBody].cur;
}
printf("%c,%d\n",array[tempBody].data,array[tempBody].cur);
}
插入数据
void insertArr(component *array,int body,int add, char a)
{
int tempBody = body;
int i;
for (i=1;i<add;i++) {
tempBody = array[tempBody].cur;//找到上一个节点
}
int insert = mallocArr(array);//分配新的游标
array[insert].cur = array[tempBody].cur;//更改插入节点的游标
array[insert].data = a;
array[tempBody].cur = insert;//最后将上一个节点的游标改成插入的地址
}
查找一个元素
int selectElem(component * array,int body,char elem)
{
int tempBody = body;
while (array[tempBody].cur != 0) {
if (array[tempBody].data == elem) {
return tempBody;//循环所有节点,找到数据等于elem的指针地址
}
tempBody=array[tempBody].cur;
}
return -1;
}
修改一个元素
void amendElem(component *array,int body,char oldElem,char newElem)
{
int add = selectElem(array, body, oldElem);//找到要修改元素的指针地址
if (add == -1) {
printf("无更改元素");
return;
}
array[add].data = newElem;
}
删除一个元素,这里删除一个元素,需要把占用的结点重新放回备用链表
void deletArr(component * array,int body,char a)
{
int tempBody = body;
while (array[tempBody].data!=a) {//首先找到指针地址
tempBody = array[tempBody].cur;
if (tempBody == 0) {
printf("此链表没有数据");
return;
}
}
int del = tempBody;//要删除的指针地址
tempBody = body;
while (array[tempBody].cur!=del) {
tempBody = array[tempBody].cur;//找到要删除节点的上一个节点
}
array[tempBody].cur = array[del].cur;//将上一个节点的游标,改成要删除节点的游标
freeArr(array, del);//最后把没用到的节点放回 备用链表
}
将没用的节点,放回备用链表
void freeArr(component *array,int k)
{
array[k].cur = array[0].cur;//将要要删除的指针地址的游标改为0
array[0].cur = k;//指针为0的游标改为k
}
运行
int main() {
component array[maxSize];
int body=initArr(array);
printf("静态链表为:\n");
displayArr(array, body);
printf("查找的位置为:\n");
char findElem = 'b';
int place = selectElem(array,body,findElem);
printf("%d", place);
printf("\n");
printf("插入后的链表为:\n");
char insertElem = 'q';
insertArr(array,body,3,insertElem);
displayArr(array, body);
printf("修改后的链表为:\n");
char newElem = 'z';
amendElem(array, body,insertElem,newElem);
displayArr(array, body);
printf("删除后的链表为:\n");
char delElem = 'a';
deletArr(array,body,delElem);
displayArr(array, body);
return 0;
}
运行结果
结语
这些链表其实都一样,只是做的方法不同,只要记住思路就行了。