静态链表
静态链表在初始化时就需要指定链表的容量,这意味着静态链表的大小是固定的,无法进行动态扩容。
在静态链表中,我们使用数组来存储链表中的节点。每个节点都包含两个部分:数据域和指针域。数据域用来存储节点的数据,指针域用来存储节点在数组中的位置。具体来说,指针域可以是一个整型变量,存储当前节点在数组中的下标,也可以是一个结构体指针,存储当前节点在数组中的地址。
#include <bits/stdc++.h>
#define MAX_SIZE 10000
using namespace std;
typedef struct Node
{
int data; // 数据域
int next; // 指向下一个节点的指针
} Node;
typedef struct StaticLinkedList
{
Node nodes[MAX_SIZE]; // 节点数组
int head; // 头节点的位置
int length; // 链表长度
} StaticLinkedList;
/**
* 函数初始化链表头为-1,链表长度为0,每个结点的next指针指向链表的下一个结点
*
* @param list 要初始化的列表
*/
void initList(StaticLinkedList *list)
{
list->head = -1;
list->length = 0;
for (int i = 0; i < MAX_SIZE; i++)
{
list->nodes[i].next = i + 1;
}
list->nodes[MAX_SIZE - 1].next = 0;
}
void destroyList(StaticLinkedList *list)
{
list->head = -1;
list->length = 0;
for (int i = 0; i < MAX_SIZE; i++)
{
list->nodes[i].next = i + 1;
}
list->nodes[MAX_SIZE - 1].next = -1;
}
/**
* 将新节点插入列表的头部。
*
* @param list 要插入的列表。
* @param val 要插入的值
*/
void insert(StaticLinkedList *list, int val)
{
int p = list->head;
int q = list->nodes[MAX_SIZE - 1].next; // 获取空闲节点的位置
list->nodes[MAX_SIZE - 1].next = list->nodes[q].next; // 将空闲节点的指针域指向下一个空闲节点
list->nodes[q].data = val; // 将数据域赋值
list->nodes[q].next = p; // 将新节点的指针域指向头节点
list->head = q; // 将头节点的位置指向新节点(头插法)
list->length++;
}
/**
* 删除指定位置的节点。
*
* @param list 要操作的列表
* @param pos 要删除的节点的位置
*/
void deleteAt(StaticLinkedList *list, int pos)
{
if (pos < 0 || pos >= list->length)
{
cout << "删除位置不合法" << endl;
return;
}
int p = list->head;
for (int i = 0; i < pos - 1; i++)
{
p = list->nodes[p].next; // 找到要删除节点的前一个节点
}
int q = list->nodes[p].next; // 获取要删除节点的位置
list->nodes[p].next = list->nodes[q].next;
list->nodes[q].next = list->nodes[MAX_SIZE - 1].next; // 将删除节点的指针域指向空闲节点的指针域
list->nodes[MAX_SIZE - 1].next = q; // 将空闲节点的指针域指向删除节点
list->length--;
}
/**
* 它打印列表中节点的数据。
*
* @param list 静态链表对象
*/
void printList(StaticLinkedList *list)
{
int p = list->head;
while (p != -1)
{
cout << list->nodes[p].data << " ";
p = list->nodes[p].next;
}
cout << endl;
}
/**
* 获取指定位置节点的数据。
*
* @param list 指向 StaticLinkedList 的指针
* @param pos 要访问的节点的位置
*
* @return 指定位置节点的数据。
*/
void getAt(StaticLinkedList *list, int pos)
{
if (pos < 0 || pos >= list->length)
{
cout << "非法的访问位置" << endl;
return;
}
int p = list->head;
for (int i = 0; i < pos - 1; i++)
{
p = list->nodes[p].next;
}
cout << "第 " << pos << " 个节点的数据为:" << list->nodes[p].data << endl;
}
int main()
{
StaticLinkedList *list = (StaticLinkedList *)malloc(sizeof(StaticLinkedList));
initList(list);
for (int i = 0; i < 10; i++)
{
cout << "插入第 " << i + 1 << " 个节点" << endl;
insert(list, i + 1);
}
cout << "插入后的链表为:" << endl;
printList(list);
cout << "删除第 5 个节点" << endl;
deleteAt(list, 5);
cout << "删除后的链表为:" << endl;
printList(list);
cout << "获取第 3 个节点的数据" << endl;
getAt(list, 3);
destroyList(list);
system("pause");
return 0;
}
Last updated