简单的静态链表

静态链表

静态链表和单链表其实很相似,只是做的方法不同。再来复习一遍,单链表的一个节点会存放数据域和指针域,指针域存放下一个节点的指针地址。静态链表分为数据与和游标,游标是记录下一个元素在数组中的位置,其实静态链表更像数组。只要我们调整思路,就很好理解了!

首先,创建结构体和头文件等
#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;
}
复制代码
运行结果

结语

这些链表其实都一样,只是做的方法不同,只要记住思路就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值