一、链表结构--C++
链表由节点和节点之间的指针相连构成,一个最基本的链表结构如下所示
该结构的data域只含有一个int型变量val,next指针指向下一个结点
struct ListNode {
int val;
ListNode* next;
ListNode(int x) :val(x), next(nullptr){}
};
二、链表的基本操作--增加/删除节点
与数组的连续存储不同,链表数据结构的每个节点是分散在内存各处的,只倚靠指针连接,所以链表是【不定长】的
1.增加节点
下面举一个简单的例子,初始链表为:
1->2->4
ListNode *root = new ListNode(1);
root->next = new ListNode(2);
root->next->next = new ListNode(4);
添加节点3,将链表修改为
1->2->3->4
实现添加功能所对应的代码如下,注意指针的修改顺序很重要,不可更改:
/*add*/
/*1 2 4*/
ListNode* add = new ListNode(3);
add->next = root->next->next;
root->next->next = add;
2.删除节点
由添加后的链表1-2-3-4,删除节点3,变为1-2-4
直接把2的next指针连接到4上即可(注意释放指针)
代码如下:
/*delete*/
/*1 2 3 4*/
ListNode* temp = root->next->next;
root->next->next = root->next->next->next;
root->next->next->next = nullptr;
free(temp);
3.检查修改结果
利用Print_list函数
void Print_list(ListNode* root)
{
while (root != nullptr)
{
cout << root->val << " ";
root = root->next;
}
cout << endl;
}
得到如下结果,修改正确:
三、总结
增加或删除节点,只需要修改指针之间的关系即可,时间复杂度均为O(1)
但是因为存储并不连续,所以链表不支持简单的下标访问,故而访问节点的时间复杂度为O(n)
另外,采用链表数据结构会造成较高的指针空间消耗,如果数据简单,额外的指针消耗可能占相当大的比例
对需要频繁进行增删的、单个数据内容较大的数据,链表或许是不错的选择。