C++ 无/有表头节点单链表——头插法

一、无/有表头结点的区别

1.无头结点的链表只是没有头结点,但有头指针。(头结点是在单链表的第一个结点之前附加一个结点)

2.头指针记录第一个存储数据的结点的地址。头结点数据域可以不存储任何数据,next域来记录第一个存储数据的结点的地址。

3.无论是否有头结点,头指针始终指向链表的第一个结点。即有头结点的,头指针指向头结点,头指针不可改变;无头结点的,头指针指向首元结点,可变。

4.插入结点的代码不同,如下:

(1)无头结点

//无头结点插入第一个位置
x->next = head;
head = x;

//插入其他结点
x->next = p->next;
p->next = x;

(2)有头结点 

//带头结点 

//插入第一个结点(头结点)
//p = head;
x->next = head->next;
head->next = x;
x->data++;

//插入其他结点
x->next = p->next;
p->next = x;
x->data++;

可以发现:无头结点的链表,插入(删除)第一个结点时,需要特殊处理。而插入(删除)其它结点于有头结点一样。

 ​​​​​​​

4.初始化链表的代码不同,如下:

//初始化无表头结点
 LinkNode* head = NULL;

//初始化有表头结点
 LinkNode* head = new LinkNode;

可知:若使用无头结点,当表非空时,头指针指向第1个结点的地址,即*LinkNode类型,但是对于空表头指针指向的是NULL

若使用头结点,无论表是否为空,头指针都指向头结点,也就是*LNode类型,对于空表和非空表的操作是一致的。

二、无/有表头结点链表的头插法

1.无表头节点单链表头插一个整型变量

//定义结点结构
typedef struct Node
{ 
  int data;
  Node* next;
}LinkNode;

void hInsertNo(LinkNode* &h ,int y)//要改变指针的指向,需引用指针

{

  LinkNode* t = new LinkNode;

  t->data = y;

  t->next =  h;

  h = t;

}

int main()

{

  int x = 0;

  LinkNode* head = NULL;//定义头指针,无头结点,空表初始为NULL

  hInsertNo(head,x);//传入头指针

  return 0;

}
void hInsertNo(LinkNode **h ,int y)//双指针传入指针的指向
{
  LinkNode* t = new LinkNode;

  t->data = y;

  t->next = *h;

  *h = t;
}

int main()
{
  int x = 0;

  LinkNode* head = NULL;

  hInsertNo(&head,x);//传入头指针的地址

  return 0;
}

2.有表头节点单链表头插一个整型变量

typedef struct Node
{ 
  int data;
  Node* next;
}LinkNode;

void hInsert(LinkNode*h ,int y)//每次插入的都是头元素在变,表头指针永远不变
{

  LinkNode* t = new LinkNode;

  t->data = y;

  t->next = h->next;

  h->next = t;

  h->data++;
}

int main()
{

  int x = 0;

  LinkNode* head = new LinkNode;//指针变量表头结点,需动态分配空间

  head->data = 0;//存储链表长度用,初始为0

  head->next = NULL;

  hInsert(head,x);//传入头指针

  return  0;
}
void hInsert(LinkNode &h ,int y)//引用取表头结点的地址
{

  LinkNode* t = new LinkNode;

  t->data = y;

  t->next = h.next;

  h.next = t;

  h.data++;
}

int main()
{

  int x = 0;

  LinkNode head;//定义表头结点

  head.data = 0;//存储链表长度用,初始为0

  head.next = NULL;

  hInsert(head,x);//传入表头节点

  return 0;
}
void hInsert(LinkNode*h ,int y)//定义指针变量h存头指针的地址
{
  LinkNode* t = new LinkNode;

  t->data = y;

  t->next = h->next;

  h->next = t;

  h->data++;
}

int main()
{
  int x = 0;

  LinkNode head;

  head.data = 0;//存储链表长度用,初始为0

  head.next = NULL;

  hInsert(&head,x);//传头结点的地址

  return 0;
}

注意:有表头节点的头插法,如果传入表头指针,表头指针是永远不变的,每次插入的都是头元素在变。

除非传入和操作的是表头节点自己(表头节点自己的两个分量是要变化的,一个记录链表长度,一个指向头元素)需要用指针或者引用来改变外部变量的值。

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值