目前我个人在数据结构的学习中,在课外主要学习郝斌老师的数据结构, 借此博文分享我的注释与拙劣的见解
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct node
{
int data;//数据域
struct node * next;//指针域
}NODE,*PNODE;//NODE等价于 struct node,PNODE等价于 struct node*
//NODE是定义的一个结点的类型 这个结点里面含有两个数据 一个是数据域 一个是指针域
//*PNODE是定义的指向这个类型结点的指针的东东
//函数声明
PNODE create_list();//创建链表的声明函数(是struct node *类型的)
void traverse_list(PNODE phead);
int main()
{
PNODE phead=NULL;//等价于struct node * phead=Null;
//定义了一个指向头结点的指针也就是头指针(目前让这个指针什么都不指向 也就是指向空NULL)
phead=create_list();//creat_list()功能:创建一个非循环单链表,并将该链表的头结点的地址付给phead
//phead是头指针 把创建的单链表的头结点的地址赋给phead
//也就是让头指针指向创建的单链表的头结点 这个函数返回的东西就是头结点的地址
//返回的东西应该是在函数中定义的
traverse_list(phead);//遍历这个单链表
return 0;
}
PNODE create_list()//创建的create_list这个单链表返回的是指针(地址)类型的数据
{
int len;//用来存放有效节点的个数
int i; //计数的
int val;//用来临时存放用户输入的结点的值
PNODE phead=(PNODE)malloc(sizeof(NODE));
//分配了一个不存放有效数据的头结点
//定义了一个head指针(与主函数里面的phead无关)指向了一个动态分配的内存
//PNODE(和int * 是一种属性)类型的地址malloc每个内存大小占字节(NODE类型)个
if(phead==NULL)
{
printf("分配失败 程序终止!\n");
exit(-1);
}
PNODE ptail=phead;//尾结点指向头结点,因为创造了0个结点,那么头结点就是尾结点
//我们要把新生成的结点挂到最后面 所以需要一个尾指针永远指向最后
ptail->next=NULL;//0个结点那么没有下一个结点,则结点的指针域就指向NULL
//把ptail->next清空就是把ptail指向的结点的指针域清空
//最后一个结点的指针域通常是null所以ptail尾指针永远指向最后一个
printf("请输入你需要生成的链表的结点的个数: len=");
scanf("%d",&len);
for(i=0;i<len;i++)//for每循环一次就创造新的结点
{
PNODE pnew=(PNODE)malloc(sizeof(NODE));
printf("请输入第%d个结点的值:",i+1);
scanf("%d",&val);
//创造新的结点给它动态分配内存 和head一个类型
if(pnew==NULL)//如果没分配内存的时候
{
printf("分配失败 程序终止!\n");
exit(-1);
}
pnew->data=val;//挂,//新的结点中的数据域的值
//把输入的数据也就是结点的值先赋给pnew的数据域里面
ptail->next=pnew;//尾结点的指针域保存新节点的指针(地址)
pnew->next=NULL;//新节点的指针域指向NULL
ptail=pnew;//新结点添加在旧链表的末尾,变成尾结点
}
return phead;//把phead即头指针的地址以PNODE类型返回函数
}
void traverse_list(PNODE phead)//遍历单链表不返回什么 可能被直接用到主函数不赋值
{
PNODE p=phead->next;//头结点的指针域,指向第一个节点的指针(地址)
while(p!=NULL)// 最后一个结点指针域为NULL
{
printf("%d",p->data); //结点数据域中的数据
p=p->next ;//下一个结点的指针域.不连续,不能用p++
}
printf("\n");
return;
}