以下全为个人理解,若有一些专业知识我理解的不是很好的话,还请在评论区里留言提出,我万分感激!!!
如何确定一个链表?
或者说定义一个怎样的变量,我们就可以知道这个链表中的所有细节
我觉得这个变量一定是头指针
如果定义了一个头指针,那么这个链表一定可以确定
(这条结论是建立在理解了链表的结构的基础之上)
依照这样的思路,我们就开始建立链表了
typedef struct node
{
int data;//数据域
struct node * pnext;//指针域
}node,*pnode;
这是结点的存储结构,下面来说明一下基本意思
一个结点是由数据域和指针域组成的,所以我们看到,在struct结构体中分为
int data;//数据域
struct node * pnext;//指针域
开始让我不解的一个问题在于这行代码
struct node * pnext;//指针域
它的意思是建立一个指向结点的指针,指针名为“pnext”,就好比“int*a”一样,struct node就是像“int”一样的数据类型,“pnext”中只能存放像“struct node”这样数据类型的变量。
typedef struct node
{
int data;//数据域
struct node * pnext;//指针域
}node,*pnode;
然后让我不解的是这一块代码中最后一行代码。这里的其实就是给“struct node”取了两个名字:
如果是“struct node”类型的变量,取名为node
如果是存放“struct node”类型变量的指针,取名为pnode
(这样就可以直接写node <变量名>、pnode<指针名>,而不用再写struct node<变量名>、struct node*<指针名>)
接下来就是链表建立函数
pnode creatlisthead()
{
int len,i,val;
//建立头节点,它的指针是头指针phead
pnode phead = (pnode)malloc(sizeof(node));
//此处建立头结点应该与其他结点的数据类型相同,头指针指向头节点,头指针相当于一个基址,在这里开辟的是头节点的内存
if (!phead)//检验是否成功分配空间
{
cout << "空间分配失败,程序终止" << endl;
exit(-1);
}
pnode ptail = phead;//定义尾指针进行尾插法
ptail->pnext = NULL;//尾指针所指向的结点指针域设为空
cout << "please enter the length" << endl;
cin >> len;
for (i = 0; i < len; ++i)
{
printf("请输入第%d个结点的值:", i + 1);
cin >> val;
//此处建立普通节点,其指针为pnew
pnode pnew = (pnode)malloc(sizeof(node));
if (!pnew)
{
cout << "空间分配失败,程序终止" << endl;
exit(-1);
}
pnew->data = val;
ptail->pnext = pnew;
pnew->pnext = NULL;
ptail = pnew;//使尾指针永远指向最后一个
}
return phead;
}
链表输出函数
void traverse_list(pnode phead)
{
pnode p = phead->pnext;//p是建立了一个指向结点的指针,使这个指针存储每个结点指针域的值
while (NULL != p)
{
cout << p -> data << ' ';
p = p->pnext;
}
}
主函数
int main()
{
pnode p = NULL;//==struct node * ()指针类型 p=null 这里是一个头指针
p = creatlisthead();
traverse_list(p);
return 0;
}