链表的结构是什么?
typedef struct ListNode{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
}ListNode;
文字描述:
链表中每个数据的存储都由一下两个部分组成:
-
数据元素本身,其所在的区域称为数据域。
-
指向直接后继元素的指针,所在的区域称为指针域
头节点,头指针和首元节点 -
头指针:一个普通的指针,它的特点是用永远指向链表第一个节点的位置。
-
节点:链表中的节点又细分为头节点、首元节点和其他节点:
- 头节点:其实就是一个不存在任何数据的空节点,通常作为链表的第一个节点。对于链表来说,头节点不是必须的,它的作用只是为了方便解决某些实际问题;
- 首元节点:由于头节点(也就是空节点)的缘故,链表中称第一个存有数据的节点为首元节点。首元节点只是对链表中第一个存有数据节点的一个称谓,没有实际意义;
- 其他节点:链表中其他的节点
注意:链表中有头节点时,头指针指向头节点;反之,若链表中没有头节点,则头指针指向首元节点。
好了知道链表是什么,接下来就是链表的操作有哪些了?
- 链表的创建
- 声明一个头指针(如果有必要,可以声明一个头节点);
- 创建多个存储数据的节点,在创建的过程中,要随时与其前驱节点建立逻辑关系;
ListNode head(-1);//声明一个头节点,只有元素-1,并没有指向下一元素的指针
ListNode *tmp=&head;//一般这样结合使用,通过修改tmp->next指向下一元素
ListNode* initList(){
ListNode* p=NULL;//创建头指针
ListNode* temp=(ListNode*)malloc(sizeof(ListNode));//创建首元节点
//首元节点先初始化
temp->val=1;
temp->next=NULL;
p = temp;//头指针指向首元节点
//从第二个节点开始创建
for (int i=2; i<5; i++) {
//创建一个新节点并初始化
ListNode *a=(ListNode*)malloc(sizeof(ListNode));
a->val=i;
a->next=NULL;
//将temp节点与新建立的a节点建立逻辑关系
temp->next=a;
//指针temp每次都指向新链表的最后一个节点,其实就是 a节点,这里写temp=a也对
temp=temp->next;
}
//返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表
return p;
}
- 插入节点
注意:要保存地址
void InsertList(ListNode* Head,int InsertIndex,int InsertData)
{
int i=1;// 由于起始结点Head是头结点,所以计数从1开始
ListNode *Current=Head;
//将Current指向待插入位置的前一个结点(InsertIndex -1)
while(Current&&i<InsertIndex-1)
{
Current=Current->next;
i++;
}
ListNode *NodeToInsert=(ListNode*)malloc(sizeof(ListNode));
if(NodeToInsert==NULL)
{
printf("空间缓存不足");
return;
}
NodeToInsert->val=InsertData;
NodeToInsert->next=Current->next;
Current->next=NodeToInsert;
return;
}
Tips:Current=Current->next;
表示下移一位,不能改变指针指向
NodeToInsert->next=Current->next;
表示改变指针指向
3. 删除节点
void DeleteList(ListNode* Head,int DeleteIndex)
{
int i=1;
ListNode *Current=Head;
ListNode *NodeToDelete;
//将Current指向待删除位置的前一个结点(index -1)
while(Current&&i<DeleteIndex-1)
{
Current=Current->next;
i++;
}
NodeToDelete=Current->next;
Current->next= NodeToDelete->next;
free(NodeToDelete);
return;
}
- 遍历节点并获取链表的长度
int GetListLength(ListNode *Head)
{
int len=0;
ListNode *Current=Head;
while(Current)//当前指针不为空时可以计数累加
{
len++;
cout<<Current->val<<" ";
Current=Current->next;
}
cout<<endl;
return len;
}