数据结构-C语言代码 day 4-静态链表

一、静态链表定义

逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成的链表称为静态链表。也就是说静态链表是用数组来实现链式存储结构,目的是方便在不设指针类型的高级程序设计语言中使用链式结构。它的优点是和动态链表一样,删除和插入元素时间复杂度低;不足是和数组一样,需要提前分配一块较大的空间。 

数据存放到数组中时,给各个数据元素配备一个整形变量,此变量用于指明各个元素的直接后继元素所在数组中的位置下标:

上图中,从 a[1] 存储的数据元素 1 开始,通过存储的游标变量 3,就可以在 a[3] 中找到元素 1 的直接后继元素 2;同样,通过元素 a[3] 存储的游标变量 5,可以在 a[5] 中找到元素 2 的直接后继元素 3,这样的循环过程直到某元素的游标变量为 0 截止(因为 a[0] 默认不存储数据元素)。

 通常,静态链表会将第一个数据元素放到数组下标为 1 的位置(a[1])中。

上图通过“数组+游标”的方式存储具有线性关系数据的存储结构就是静态链表。

二、静态链表的实现

创建链表

typedef struct StaticLinkedNode{
	char data;

	int next;
} *NodePtr;

typedef struct StaticLinkedList{
	NodePtr nodes;//存储结点
	int* used;//0空闲  1占用
} *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("\r\n");
}

插入元素

void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition)
{
	int p=0, q, i;
	//寻找位置
	for (i = 0; i < paraPosition; i ++)
	{
		p = paraListPtr->nodes[p].next;
		if (p == -1)
		{
			printf("位置%d超出链表范围\r\n",paraPosition);
			return;
		}
	}
	//创建新结点
	for (i = 1; i < DEFAULT_SIZE; i ++)
	{
		if (paraListPtr->used[i] == 0)
		{
			//等同于malloc(分配空间)
			printf("%d处已被分配空间\r\n",i);
			paraListPtr->used[i] = 1;
			q = i;
			break;
		}
	}
	if (i == DEFAULT_SIZE)
	{
		printf("没有空间。\r\n");
		return;
	}
	paraListPtr->nodes[q].data = paraChar;
	printf("插入%c\r\n",paraChar);
	paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = q;
}

删除元素

 

void deleteElement1(ListPtr paraListPtr, char paraChar)
{
	int p=0, q;
	while ((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar))
	{
		p = paraListPtr->nodes[p].next;
	}
	printf("删除%c\r\n",paraChar);
	if (paraListPtr->nodes[p].next == -1)
	{
		printf("%c无法删除\r\n",paraChar);
		return;
	}
	q = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
	//此语句与 free(q) 相同
	paraListPtr->used[q] = 0;
}

功能测试

void appendInsertDeleteTest()
{
	// 初始化一个空列表。
	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);
    insertElement(tempList, '\t', 5);
    insertElement(tempList, 'S', 6);
    insertElement(tempList, 'w', 7);
    insertElement(tempList, 'p', 8);
    insertElement(tempList, 'u', 9);
    insertElement(tempList, '!', 10);
	printList(tempList);

	// 删除一些字符(第一次出现)。
	printf("Deleting 'e'.\r\n");
	deleteElement(tempList, 'e');
	printf("Deleting 'a'.\r\n");
	deleteElement(tempList, 'a');
	printf("Deleting 's'.\r\n");
	deleteElement(tempList, 's');
	printList(tempList);

	insertElement(tempList, 'l', 1);
	printList(tempList);
}

全部代码

#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;//0空闲  1占用
} *ListPtr;

/**
 * Initialize the list with a header.
 * @return The pointer to the header.
 */
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;
}

/**
 * Print the list.
 * @param paraListPtr The pointer to the list.
 */
void printList(ListPtr paraListPtr){
	int p = 0;
	while (p != -1) {
		printf("%c", paraListPtr->nodes[p].data);
		p = paraListPtr->nodes[p].next;
	}// Of while
	printf("\r\n");
}// Of printList

/**
 * Insert an element to the given position.
 * @param paraListPtr The position of the list.
 * @param paraChar The given char.
 * @param paraPosition The given position.
 */
void insertElement(ListPtr paraListPtr, char paraChar, int paraPosition)
{
	int p=0, q, i;
	//寻找位置
	for (i = 0; i < paraPosition; i ++)
	{
		p = paraListPtr->nodes[p].next;
		if (p == -1)
		{
			printf("位置%d超出链表范围\r\n",paraPosition);
			return;
		}
	}
	//创建新结点
	for (i = 1; i < DEFAULT_SIZE; i ++)
	{
		if (paraListPtr->used[i] == 0)
		{
			//等同于malloc(分配空间)
			printf("%d处已被分配空间\r\n",i);
			paraListPtr->used[i] = 1;
			q = i;
			break;
		}
	}
	if (i == DEFAULT_SIZE)
	{
		printf("没有空间。\r\n");
		return;
	}
	paraListPtr->nodes[q].data = paraChar;
	printf("插入%c\r\n",paraChar);
	paraListPtr->nodes[q].next = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = q;
}
/**
 * Delete an element from the list.
 * @param paraHeader The header of the list.
 * @param paraChar The given char.
 */
void deleteElement1(ListPtr paraListPtr, char paraChar)
{
	int p=0, q;
	while ((paraListPtr->nodes[p].next != -1) && (paraListPtr->nodes[paraListPtr->nodes[p].next].data != paraChar))
	{
		p = paraListPtr->nodes[p].next;
	}
	printf("删除%c\r\n",paraChar);
	if (paraListPtr->nodes[p].next == -1)
	{
		printf("%c无法删除\r\n",paraChar);
		return;
	}
	q = paraListPtr->nodes[p].next;
	paraListPtr->nodes[p].next = paraListPtr->nodes[paraListPtr->nodes[p].next].next;
	//此语句与 free(q) 相同
	paraListPtr->used[q] = 0;
}
/**
 * Unit test.
 */
void appendInsertDeleteTest()
{
	// 初始化一个空列表。
	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);
    insertElement(tempList, '\t', 5);
    insertElement(tempList, 'S', 6);
    insertElement(tempList, 'w', 7);
    insertElement(tempList, 'p', 8);
    insertElement(tempList, 'u', 9);
    insertElement(tempList, '!', 10);
	printList(tempList);

	// 删除一些字符(第一次出现)。
	printf("Deleting 'e'.\r\n");
	deleteElement(tempList, 'e');
	printf("Deleting 'a'.\r\n");
	deleteElement(tempList, 'a');
	printf("Deleting 's'.\r\n");
	deleteElement(tempList, 's');
	printList(tempList);

	insertElement(tempList, 'l', 1);
	printList(tempList);
}

/**
 * The entrance.
 */
int main(){
	appendInsertDeleteTest();
}// Of main

运行结果

2处已被分配空间
插入e
3处已被分配空间
插入l
4处已被分配空间
插入l
没有空间。
位置5超出链表范围
位置6超出链表范围
位置7超出链表范围
位置8超出链表范围
位置9超出链表范围
位置10超出链表范围
 Hell
Deleting 'e'.
删除e
Deleting 'a'.
删除a
a无法删除
Deleting 's'.
删除s
s无法删除
 Hll
2处已被分配空间
插入l
 Hlll

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值