C语言数据结构_静态链表

静态链表

本代码描述

首先定义结构体存放该结点的数据和下一个结点的int类型的下标next,通过下标next来访问整个链表。同时再定义一个结构体来表明开辟的空间是否存有数据如果有数据则used的值为1,没有存数据则used的值为0。本质上静态链表就是以数组的形式来存储数据的,只是在存储数据时多了下一个结点的下标。

上代码

//宏定义整个链表的大小
#define DEFAULT_SIZE 5
//创建结点
typedef struct StaticLinkedNode
{
	char data;
	int next;
} *NodePtr;

typedef struct StaticLinkedList
{
	NodePtr nodes;
	int *used;
} *ListPtr;
//头结点的初始化
ListPtr initLinkedList()
{
	ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedList));
	tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAULT_SIZE);
	tempPtr->used = (int*)malloc(sizeof(int) * DEFAULT_SIZE);

	tempPtr->nodes[0].data = '\0';
	tempPtr->nodes[0].next = -1;
	tempPtr->used[0] = 1;
	for(int i = 1; i < DEFAULT_SIZE; i++)
	{
		tempPtr->used[i] = 0;
	}

	return tempPtr;
}

添加元素

//插入元素
void insertElement(ListPtr paraListPtr,char paraChar,int paraPosition)
{
	int p,q,i;
	//刚开始插入到时候必须从0的位置插入,不能随意的选择一个位置插入
	p = 0;
	for(i = 0; i < paraPosition; i++)
	{
		p = paraListPtr->nodes[p].next;
		if(p == -1)
		{
			printf("The position %d is beyond the scope of the list.\n",paraPosition);
			return;
		}
	}
	//找到没有数据的空间的地址
	for(i = 1; i < DEFAULT_SIZE; i++)
	{
		if(paraListPtr->used[i] == 0)
		{
			printf("Space at %d allocated.\n",i);
			paraListPtr->used[i] = 1;//再插入元素后该位置就有数据了used = 1
			q = i;
			break;
		}
	}
	if(i == DEFAULT_SIZE)
	{
		printf("No space!\n");
		return;
	}

	paraListPtr->nodes[q].data = paraChar;
	printf("linking\n");
	paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = q;
}

在这里插入图片描述

删除元素


void deleteElement(ListPtr paraListPtr,char paraChar)
{
	int p,q;
	//定位要删除的值
	p = 0;
	while((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data) != paraChar)
	{
		p = paraListPtr->nodes[p].next;
	}
	
	if (paraListPtr->nodes[p].next == -1)
	{
		printf("Can not locate the %c,can not delete!\n",paraChar);
		return;
	}
	//将要删除的结点的上一个结点的下标next改为要删除的结点的下标,在遍历的时候就可以跳过要删除的结点
	q = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
	//因为删除了该结点所以该结点对应的used改为0
	paraListPtr->used[q] = 0;
}

打印链表

//打印整个链表
void printList(ListPtr paraListPtr)
{
	int p = 0;
	while(p != -1)
	{
		printf("%c",paraListPtr->nodes[p].data);
		p = paraListPtr->nodes[p].next;
	}
	printf("\n");	
}

全部代码

#include <stdio.h>
#include <malloc.h>
//宏定义整个链表的大小
#define DEFAULT_SIZE 5
//创建结点
typedef struct StaticLinkedNode
{
	char data;
	int next;
} *NodePtr;

typedef struct StaticLinkedList
{
	NodePtr nodes;
	int *used;
} *ListPtr;
//头结点的初始化
ListPtr initLinkedList()
{
	ListPtr tempPtr = (ListPtr)malloc(sizeof(struct StaticLinkedList));
	tempPtr->nodes = (NodePtr)malloc(sizeof(struct StaticLinkedNode) * DEFAULT_SIZE);
	tempPtr->used = (int*)malloc(sizeof(int) * DEFAULT_SIZE);

	tempPtr->nodes[0].data = '\0';
	tempPtr->nodes[0].next = -1;
	tempPtr->used[0] = 1;
	for(int i = 1; i < DEFAULT_SIZE; i++)
	{
		tempPtr->used[i] = 0;
	}

	return tempPtr;
}
//打印整个链表
void printList(ListPtr paraListPtr)
{
	int p = 0;
	while(p != -1)
	{
		printf("%c",paraListPtr->nodes[p].data);
		p = paraListPtr->nodes[p].next;
	}
	printf("\n");	
}
//插入元素
void insertElement(ListPtr paraListPtr,char paraChar,int paraPosition)
{
	int p,q,i;
	//刚开始插入到时候必须从0的位置插入,不能随意的选择一个位置插入
	p = 0;
	for(i = 0; i < paraPosition; i++)
	{
		p = paraListPtr->nodes[p].next;
		if(p == -1)
		{
			printf("The position %d is beyond the scope of the list.\n",paraPosition);
			return;
		}
	}
	//找到没有数据的空间的地址
	for(i = 1; i < DEFAULT_SIZE; i++)
	{
		if(paraListPtr->used[i] == 0)
		{
			printf("Space at %d allocated.\n",i);
			paraListPtr->used[i] = 1;//再插入元素后该位置就有数据了used = 1
			q = i;
			break;
		}
	}
	if(i == DEFAULT_SIZE)
	{
		printf("No space!\n");
		return;
	}

	paraListPtr->nodes[q].data = paraChar;
	printf("linking\n");
	paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = q;
}

void deleteElement(ListPtr paraListPtr,char paraChar)
{
	int p,q;
	//定位要删除的值
	p = 0;
	while((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data) != paraChar)
	{
		p = paraListPtr->nodes[p].next;
	}
	
	if (paraListPtr->nodes[p].next == -1)
	{
		printf("Can not locate the %c,can not delete!\n",paraChar);
		return;
	}
	//将要删除的结点的上一个结点的下标next改为要删除的结点的下标,在遍历的时候就可以跳过要删除的结点
	q = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
	//因为删除了该结点所以该结点对应的used改为0
	paraListPtr->used[q] = 0;
}

void appendInsterDeleteTest()
{
	ListPtr tempList = initLinkedList();
	printList(tempList);
	insertElement(tempList,'H',0);
	insertElement(tempList,'e',1);
	insertElement(tempList,'l',2);
	insertElement(tempList,'l',3);
	insertElement(tempList,'o',4);
	printList(tempList);

	printf("Deleting,'a'\n");
	deleteElement(tempList,'a');
	printList(tempList);
	printf("Deleting,'e'\n");
	deleteElement(tempList,'e');
	printList(tempList);
	printf("Deleting,'o'\n");
	deleteElement(tempList,'o');
	printList(tempList);

	insertElement(tempList,'x',1);
	printList(tempList);

}

int main()
{
	appendInsterDeleteTest();
	return 0;
}

测试结果


Space at 1 allocated.
linking
Space at 2 allocated.
linking
Space at 3 allocated.
linking
Space at 4 allocated.
linking
No space!
Hell
Deleting,'a'
Can not locate the a,can not delete!
Hell
Deleting,'e'
Hll
Deleting,'o'
Can not locate the o,can not delete!
Hll
Space at 2 allocated.
linking
Hxll

相比单链表静态链表的空间是固定的这样有可能造成空间的浪费比如申请了100个单位的空间但是只存储了50单位的数据这样剩下的空间任然存在造成空间的浪费。
在单链表的遍历中是通过指针域next来访问的,而静态链表是通过int类型的next为数组的下标来访问的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值