一、链表
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里储存下一个节点的指针(Pointer)。一般分为单向链表,双向链表,循环链表等。单向链表:节点中储存数据与指向下一节点的指针;双向链表:节点中储存数据、指向下一节点的指针与指向上一节点的指针;循环链表:将首节点与尾节点通过指针连接在一起。
下图便是一个链表的示意图:
二、节点
节点一般分为两部分:1.此节点所储存的数据2.指向下一节点的指针。
如下例子:
构建一个链表其中每个节点包含学生姓名,学号,性别,年龄信息。
struct Node
{
string Name;
string Number;
string Sex;
int age;
struct Node *nextptr;
};
可使用typedef改写如下:
(1)使用typedef对结构体指针取别名
typedef struct Node* NodePtr;
struct Node
{
string Name;
string Number;
string Sex;
int age;
NodePtr nextptr;
};
(2)或者使用typdef对结构体取别名
typedef struct Node Node;
struct Node
{
string Name;
string Number;
string Sex;
int age;
Node* nextptr;
};
注:使用这种写法有可能出现下面的问题:第一行代码中nextptr,endptr和headptr都是指针,但第二行中endptr与headptr不是指针,而第三行中endptr不是指针却在两个指针声明中间进行声明,易使人混淆,需要注意!!!
Node *nextptr, *endptr, *headptr;
Node *nextptr, endptr, headptr;
Node *nextptr, endptr, *headptr;
注:c++中可直接使用如下写法,不需要使用typedef取别名。
struct Node
{
string Name;
string Number;
string Sex;
int age;
Node* nextptr;
};
三、链表的生成
第一步:建立第一个节点,并使用头指针head指向这一节点。并且使用一个current指针指向我们所在的位置。
第二步:使用new申请一定大小的所需空间,并使用上一节点中的指针nextptr指向这片区域。并且为了能够建立后续节点,将current前移,指向新建立的节点。
第三步:如果需要继续建立新的节点,重复第二步,如果不需要就将最后一个节点的nextptr指针设为空指针。
Node *head;
Node *current;
//创建头节点
head= new Node ;
head->nextptr = NULL;
current=head;
//创建一个新的节点
current->nextptr= new Node;
current =current->nextptr;
//将尾节点设为空节点
current->nextptr= NULL;
四、删除节点
1.如果删除的节点位于首位,直接将head指向下一节点,并且释放此节点所占据的内存;
//删除头节点
Node *temp = head;//将首节点的地址储存起来以便之后释放内存!!!
head = head->nextptr;
delete temp;
2.如果删除的节点位于中间,找到需要删除的节点,然后将前一个节点中的指针指向下一个节点,并释放所删除节点的内存;
//删除中间节点
Node *temp;
Node *follow;
temp = head;
while (temp != NULL && xx )//xx为检索条件
{
follow = temp;
temp = temp->nextptr;
}
if(temp != NULL)
{
//将follow指向的结构体中的指针指向需要删除节点的下一个节点
follow->nextptr = temp->nextptr;
delete temp;//释放需要删除的节点的内存
}
3.如果删除的节点位于结尾,将前一节点中的指针变为空指针,并且释放尾节点的内存。
//删除尾节点
Node *temp;
Node *follow = NULL;
temp = head;
//将指针移到尾节点
while(temp != NULL)
{
follow = temp;
temp = temp->nextptr;
}
//将前一个指针设为空指针
follow->nextptr = NULL;
delete temp;