单链表的算法之遍历节点
1.什么是遍历?
(1)遍历就是把单链表中的各个节点挨个拿出来,就叫遍历。
(2)遍历的要点:一是不能遗漏、二是不能重复、追求效率。
2.如何遍历单链表
(1)分析一个数据结构如何遍历,关键是分析这个数据结构本身的特点。然后根据本身特点来制定它的遍历算法。
(2)单链表的特点就是由很多个节点组成,头指针+头节点为整个链表的起始,最后一个节点的特征是它内部的pNext指针值为NULL。从起始到结尾中间由各个节点内部的pNext指针来挂接。由起始到结尾的路径有且只有一条。单链表的这些特点就决定了它的遍历算法。
(3)遍历方法:从头指针+头节点开始,顺着链表挂接指针依次访问链表的各个节点,取出这个节点的数据,然后再往下一个节点,直到最后一个节点,结束返回。
3.编程实战
写一个链表遍历的函数
#include <stdio.h>
//构建一个链表的节点
struct node
{
int data; //有效数据
struct node* pNext; //指向下一个节点的指针
};
//创建一个链表的节点
//返回值:指针,指针指向我们本函数新创建的节点的首地址
struct node* creat_node(int data)
{
struct node* pHeader = NULL;
//每创建一个新的节点,把这个新的节点和它前一个节点关联起来
//创建一个链表节点
struct node* p = (struct node*)malloc(sizeof(struct node));
if(NULL == p)
{
printf("malloc failure\n");
return NULL;
}
memset(p, 0, sizeof(struct node));
//bzero(p, sizeof(struct node));
p->data = data;
p->pNext = NULL; //将来要指向下一个节点的首地址,实际操作时将下一个节点malloc返回的指针赋值给它
return p;
}
//尾部插入
//计算添加了新的节点后总共有多少个节点,然后把这个数写进节点中
void insert_tail(struct node* pH, struct node* new)
{
int count = 0;
//分两步完成插入
//第一步,先找到链表中最后一个节点
struct node* p = pH;
while(NULL != p->pNext) //由头指针向后便利,走到最后一个节点
{
p = p->pNext;
count++;
}
//第二部,将新节点插入到最后一个节点尾部
p->pNext = new; //新节点成为最后一个节点
pH->data = count + 1;
}
//从头部添加新节点
void insert_head(struct node* pH, struct node* new)
{
//新节点的next指向原来的第一个节点
new->pNext = pH->pNext; //pH->pNext是第一个节点的地址
//头结点的next指向新节点的地址
pH->pNext = new;
//头结点中的计数加1
pH->data += 1;
}
//遍历单链表,pH为指向单链表的指针,将遍历的数据打印出来
void ergodic(struct node* pH)
{
//pH-data; //头结点数据,不是链表的常规数据,不要算进去
struct node* p = pH; //因为头指针后面是头结点
//struct node* p = pH->pNext;
while(NULL != p->pNext)
{
p = p->pNext;
printf("node data = %d\n", p->data);
}
printf("over\n");
}
int main()
{
//头指针
//struct node* pHeader = NULL;
struct node* pHeader = creat_node(0);
insert_head(pHeader, creat_node(1));
insert_head(pHeader, creat_node(2));
insert_head(pHeader, creat_node(3));
/*pHeader = creat_node(1);
pHeader->pNext = creat_node(2);
pHeader->pNext->pNext = creat_node(3);*/
//访问链表中的各个节点的有效数据,这个访问必须注意不能使用p,p2,p3,只能使用pHeader
//访问链表的头结点有效数据
printf("beader data: %d\n", pHeader->data); //pHeader->data == p->data
ergodic(pHeader);
/*//访问链表的第1个有效数据
printf("node2 data: %d\n", pHeader->pNext->data); //pHeader->data == p->data
//访问链表的第2个有效数据
printf("node3 data: %d\n", pHeader->pNext->pNext->data); //pHeader->data == p->data
//访问链表的第3个有效数据
printf("node3 data: %d\n", pHeader->pNext->pNext->pNext->data); //pHeader->data == p->data*/
return 0;
}