一.线性表分为顺序表和链表;
1.顺序表(地址连续)
使用顺序表的时候可以使用数组或者结构体来定义,插入删除元素时需要移动元素。
2.链表(地址不连续)
(1)单向链表
插入:
删除: 记得要delete q
(2)双向链表
插入:
删除:
(3)循环链表:单向和双向
(4)单向静态链表
-
right里面填的是下个元素的下标:data[3]=12,下个元素下标是4,所以right[3]=4。
-
使用静态链表的好处:好定位
插入:
-
data[5]=49,下个元素是25并且下标9,所以right[5]=9。
-
5->9->6:right[5]=9,right[9]=6
删除:
-
2->4:right[2]=4
(5)双向静态链表
-
data[2]=9,9的前一个元素是56并且其下标是1,9的下一个元素是12并且其下标3,所以left[2]=1,right[2]=3
插入:
-
5-9-6:left[9]=5,left[6]=9;right[5]=9,right[9]=6
删除:
-
2-4:left[4]=2,rght[2]=4
二.c++链表构造函数
- c++的链表结构是基于结构体创建的,结构体可以这么写
struct ListNode
{
double value;
ListNode *next;
};
结构成员 value 是结点的数据部分,而另一个结构成员 next 则被声明为 ListNode 的指针,它是指向下一个结点的后继指针。
- 结构体的构造函数可以这么写
struct ListNode
{
double value;
ListNode *next;
//构造函数
ListNode(double value1, ListNode *next1 = NULL)
{
value = value1;
next = next1;
}
};
如何使用构造函数初始化结点:
- 通过仅指定其 value 部分,而后继指针则默认为 nullptr。一般用于当需要创建一个结点放在链表的末尾时。
- 通过指定 value 部分和一个指向链表下一个结点的指针。一般用于当新创建的结点将被插入到链表中间某个有后继结点的地方时。
- 创建一个链表
参考博客:C++链表及其创建
(1)定义一个初始为空的链表,方法是定义一个用作链表头的指针并将其初始化为 nullptr
ListNode *head = nullptr;
或者:将头指针指向头结点
ListNode* head = new ListNode;
(2)创建一个链表,其中包含一个结点,存储值为 20.5,这是第一个结点(首结点)
head = new ListNode; //分配新结点:首结点
head->value = 20.5; //存储值
head->next = nullptr; //表示链表的结尾
(3)创建一个新结点,在其中存储 25.0的值,并将其作为链表中的第二个结点。可以使用第二个指针来指向新分配的结点(其中将存储 25.0 的值)
ListNode *secondPtr = new ListNode;
secondPtr->value = 25.0;
secondPtr->next = nullptr; //第二个结点是链表的结尾
head->next = secondPtr; //第一个结点指向第二个
以上语句通过将其后继指针 secondPtr->next 设置为 nullptr,可以使第二个结点成为链表的结尾,通过 head->next = secondPtr; 语句将链表头的后继指针改为指向第二个结点。
(3)
#include <iostream>
using namespace std;
struct ListNode
{
double value;
ListNode *next;
};
int main()
{
ListNode *head = nullptr;//定义一个空链表,里面没有结点
// 第一个结点
head = new ListNode;
head->value = 12.5;
head->next = nullptr;
//第二个结点
ListNode *secondPtr = new ListNode;
secondPtr->value = 13.5;
secondPtr->next = nullptr;
head->next = secondPtr;
cout << "First item is " << head->value << endl;
cout << "Second item is " << head->next->value << endl;
return 0;
}
- 遍历链表:从链表头开始,涉及整个链表,并在每个结点上执行一些处理操作的过程被称为遍历链表。
假设某个链表的链表头指针是 numberList,要遍历该链表,则需要使用另一个指针 ptr 指向链表的开头
ListNode* head=new ListNode;//头指针指向头结点
ListNode *ptr = head;//定义一个新指针ptr指向链表开头
while (ptr != nullptr)
{
cout << ptr->value << " "; //处理结点(显示结点内容)
ptr = ptr->next; //移动到下一个结点
}
补充:用nullptr,不用null可以让程序更健壮