链表中头指针和头结点

线性表使用顺序(数组)存储时有个弊端,那就是在插入和删除时需要大量的移动数据,这显示是非常消耗时间的,所以可以采用链式存储,即有一个指针域(单链表),来记录下个结点的存储位置(地址),这样在插入和删除结点时只需要修改指针域即可,从而大量减少移动数据所消耗的时间。来看链表的定义:

struct node {
	int data;
	struct node *next;
};

其中有两个元素,data为数据域,用于存储数据,next为指针域,用于存储下个结点的位置(地址)。那么什么是头指针呢?我们把指向第一个结点的指针称为头指针,那么每次访问链表时都可以从这个头指针依次遍历链表中的每个元素,例如:

struct node first;
struct node *head = &first;

这个head指针就是头指针。
这个头指针的意义在于,在访问链表时,总要知道链表存储在什么位置(从何处开始访问),由于链表的特性(next指针),知道了头指针,那么整个链表的元素都能够被访问,也就是说头指针是必须存在的。示例如下:

#include <stdio.h>

struct node {
	int data;
	struct node *next;
};

int main(void)
{
	struct node *head, first, second;

	head = &first;
	first.data = 1;
	first.next = &second;

	second.data = 2;
	second.next = NULL;

	while (head) {
		printf("%d\n", head->data);
		head = head->next;
	}
	return 0;
}

需要着重注意的是while那部分(通过头指针遍历完整个链表)。

那么什么又是头结点呢?很多时候,会在链表的头部附加一个结点,该结点的数据域可以不存储任何信息,这个结点称为头结点,
头结点的指针域指向第一个结点,例如:

struct node head, first;
head.next = &first;

那么这里的头指针又是谁呢,不在是指向第一个结点的指针,而是指向头结点的指针,例如:

struct node *root = &head;

即root指针才是头指针。示例如下:

#include <stdio.h>

struct node {
	int data;
	struct node *next;
};

int main(void)
{
	struct node *root, head, first, second;

	root = &head;
	root->data = 0;
	root->next = &first;

	first.data = 1;
	first.next = &second;

	second.data = 2;
	second.next = NULL;

	while (root) {
		printf("%d\n", root->data);
		root = root->next;
	}

	return 0;
}
时间: 2024-10-10 02:39:35

链表中头指针和头结点的相关文章

剑指offer56:删除链表中重复的结点,排序的链表中,删除重复的结点不保留,返回链表头指针。 例如,链表1-&gt;2-&gt;3-&gt;3-&gt;4-&gt;4-&gt;5 处理后为 1-&gt;2-&gt;5

1 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 2 思路和方法 (1)链表为空,不必多说,return NULL: (2)如果恰恰是头结点与头结点的后一个重复了,这种情况是可以发生的,那头结点就要被删除,另选新的结点作为头结点.如何处理这种特殊情况,多申请一个指针就可以了. 3 C++核心代码 1 /* 2 struct

链表中的头指针和头结点(转)

链表中的头指针和头结点 链式存储 指针域(单链表),来记录下一个结点的存储位置(地址) 插入和删除结点时,只需要修改指针即可 struct node{ int data; struct node *next; } data是数据域,用于存储数据 next是指针域,用于存储下一个结点的位置(地址) 原文地址:https://www.cnblogs.com/wwqdata/p/11578861.html

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点

#include <iostream> #include <string.h> #include <stdlib.h> #include <stack> using namespace std; struct Node { int data; struct Node* next; }; struct Node* create_list(int len) { if (len <= 0) return NULL; struct Node* head; st

给定链表的头指针和一个结点指针,在O(1)时间删除该结点

题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点. 具体思路:把头结点的数据直接copy到要删除的结点处,然后头指针向后移动一个结点,再free掉原来的头指针指向的结点,这样等于把要删除的结点删除了.当链表只有一个结点或者要删除的结点是头结点或尾结点时,这种方法也是成立的,所以不需要做特殊的处理.假设链表总共有n个结点,我们的算法在n-1总情况下时间复杂度是O(1),只有当给定的结点处于链表末尾的时候,时间复杂度为O(n).那么平均时间复杂度[(n-1)*O(1)+O(n)]/n,

13输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4250795.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针. 题目分析: 1.链表的倒数第0个结点为链表的尾指针,设为r,则r指向最后一

防御性编程习惯:求出链表中倒数第 m 个结点的值及其思想的总结

防御性编程习惯 程序员在编写代码的时候,预料有可能出现问题的地方或者点,然后为这些隐患提前制定预防方案或者措施,比如数据库发生异常之后的回滚,打开某些资源之前,判断图片是否存在,网络断开之后的重连次数或者是否连接备用网络,除法运算中的除数问题,函数或者类在接受数据的时候的过滤情况,比如如果输入一个指针参数,是否需要判断是不是空指针?输入一个字符串参数,是否需要判断字符串空否……总的来说就是防止出现不可预见的事情,设计出鲁棒性的代码. 看下面的例子 输入一个链表,输出链表中倒数第 m 个结点额内容

代码的鲁棒性:链表中倒数第k个结点

输入一个链表,输出该链表中倒数第k个结点. 代码思路如下:两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点.然后两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点了. /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution {

输出单链表中倒数第k个结点(Java版)

题目:输入带头结点的单链表L,输出该单链表中倒数第k个结点.单链表的倒数第0个结点为该单链表的尾指针.要求只能遍历一次单链表. 解题思路: 如果不要求只能遍历一次单链表,我们可以先遍历一次单链表,求出它的结点的总个数n(包括头结点),所以单链表的结点是从倒数第n-1个到倒数第0个,然后再遍历一次单链表,遍历时访问的第n-k-1个结点就是该单链表中倒数第k个结点.现在要求只能遍历一次单链表,可以设两个指针p和q,最开始时它们都指向头结点,然后p向后移动k位,最后p,q同时向后移动直到p为最后一个结

【编程题目】输入一个单向链表,输出该链表中倒数第 k 个结点

第 13 题(链表):题目:输入一个单向链表,输出该链表中倒数第 k 个结点.链表的倒数第 0 个结点为链表的尾指针.链表结点定义如下: struct ListNode {int m_nKey;ListNode* m_pNext;}; 我的思路:先翻转链表,再从翻转后的链表的头向尾数k-1个,返回,再次翻转链表. 代码如下:注意这个思路非常差.差的原因是:如果只是用最原始的方法,先遍历一遍计数,再遍历一遍找倒数第k个,需要遍历两遍.但我的思路,翻转两次链表就要遍历两遍.还要在走k-1步找倒数第k

剑指Offer面试题15(Java版):链表中倒数第K个结点

题目: 输入一个链表,输出该链表中倒数第k哥结点. 为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点. 例如一个链表有6个结点,从头结点开始它们的值依次是1,2,3,4,5,6.这个链表的倒数第3个结点是值为4的结点 为了得到第K个结点,很自然的想法是先走到链表的尾端,再从尾端回溯K步.可是我们从链表结点的定义可疑看出本题中的链表 是单向链表,单向链表的结点只有从前往后的指针而没有从后往前的指针,因此这种思路行不通. 既然不能从尾节点开始遍历这个链表,我们还是把思路回到头