数据结构和算法–链表
头指针与头节点的区别:头指针指向头节点,头节点指向下一个节点。头指针是必要的,不然找不到第一个节点,数据就会丢失。
这个头节点不一定要有,也可以没有,头指针就指向NULL
结构指针:
typedef struct Node
{
ElemType data;//数据域
struct Node *Next;//指针域
}Node;
typedef struct Node *LinkList;
单链表的读取,读取的时候,只需要从第一个节点,遍历到需要读取的第i个节点就好了。
Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p;
p=L->next;//指向链表的第一个节点
j=1;//初始化
while(p&&j<i)//p不为空,没有到末尾
{
p=p->next;//指向下一个指针
++j;
}
if(!p||j>i)//找不到,返回0
{
return 0;
}
*e=p->data;
}
单链表的插入:关键是第一个指针指向需要插入的节点地址,需要插入的节点指向下一个节点地址
Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,s;
p=*L;//指向链表的节点指针
j=1;//初始化
while(p&&j<i)//遍历到i的位置
{
p=p->next;//指向下一个指针
++j;//j==i退出,找打i的位置
}
if(!p||j>i)//找不到,返回0
{
return 0;
}
s=(LinkList)malloc(sizeof(Node));//创建s
s->data=e;
//插入指向
s->next=p->next;
p->next=s;
return 1;
}
单链表的删除:关键是第一个指针指向需要删除插入的节点的下一个节点
Status ListDelte(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,s,q;
p=*L;//指向链表的节点指针
j=1;//初始化
while(p&&j<i)//遍历到i的位置
{
p=p->next;//指向下一个指针
++j;//j==i退出,找打i的位置
}
if(!p||j>i)//找不到,返回0
{
return 0;
}
q=p->next;//指向删除的指针
p->next=q->next;
*e=q->data;
free(q);//释放q内存
return 1;
}
对比顺序结构,单链表在频繁插入/删除的优势是明显的。