在csdn写过链表,当时没有熟悉markdown的语法,所以排版很糟糕,虽然排版目前也不怎么样,但是看还是可以的。很用心去研究链表了。我将我的思想写下来。
结点这个词组可能写的不对,还希望原谅,明白意思就好。
结构体指针通过动态内存申请,会转变为结构体变量,你理解了吗?如果不对,请指教。
当然啦,结构体的理解是学好链表的前提。众所周知,链表这种数据结构在数据结构与算法中的地位是极其重要的。我拼了也要把它搞懂。
1:先总结一下如何创建静态链表
显然这个没有任何难度,所谓静态就是它的内存空间并不是动态分配的,这应该是与动态链表的一个主要的区别。静态链表很明显是采用数组来实现这种连续的存储结,动态链表是通过不断动态申请内存空间的,所以链表的长度上没有限制。物理地址的不连续,导致动态链表需要我们使用指针去很好的访问。
终于可以自己完整的写出这两种链表了,先从静态开始。
简单建立一个静态链表
//静态链表的创建
#include<stdio.h>
typedef struct Student{
int age;
struct Student *next;
}stu1;
int main(){
int i;
int age1;
stu1 stu[4];//申明变量,静态链表用数组来代替指针,很明显,这种空间是固定的。
printf("请给结构体变量赋值\n");
for(i=0;i<3;i++){
scanf("%d",&age1);//现在给各结点的数据域赋值
stu[i].age = age1;//用.引用的话,是结构体变量的特权。如果是->,那就是结构体指针引用的方式
}
stu1 *head =&stu[0];//定义一个头指针指向第一个元素,只是指针,没有空间,所以head不是结点。可以认为,当定义的指针,赋予它空间的时候,那么就会成为结点。
stu[0].next = &stu[1];//一下是各个结点串起来,很好理解,依次类推
stu[1].next = &stu[2];
stu[2].next = &stu[3];
stu[3].next =NULL;//没有在stu[3]里面存数据,并且将其指针域的指向赋值为NULL
while((head->next!=NULL)){
printf("%d\n",head->age);
head=head->next;
}
return 0;
}
简单建立一个动态链表 插入我的小小的潦草的草稿比划,希望有用。哈哈哈哈
动态链表的各方面理解的话,可能并不是很好理解,在不断学习的过程中,一定要有直接的理解,永远顺从别人的代码思路去理解看的话很大可能在后来还回迷惑。比较管用的学习方式就是一定自己去写,并加以思考。
//goal:实现动态申请单链表(动态内存分配)采用了头插法实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Student {
int age;//数据域
struct Student* next;//指针域
}Student;
Student* create_head(Student *head){//创建头结点
head = (Student*)malloc(sizeof(Student));
head->next=NULL;
//printf("Hello");
if(head == NULL){
printf("空间申请失败\n");
}else{
printf("申请空间成功\n");
}
return head;
}
Student*insert(Student *head){//插入结点,本次采用了头插法,每个插入方法只要理解一种,就基本都通了。关键在于理解这个过程
int i=1;
Student *p1 = head;//好,定义一个指针指向头结点,再次申明此处没有给指针申请空间,并不等同于结点。
p1->next = NULL;
printf("请输入要插入结点数据域的值\n");
printf("输入1结束输入\n");
while(i!=0){
scanf("%d",&i);
Student *p2 = (Student*)malloc(sizeof(Student));//此处给p2申请了空间,所以可以注意一下两者的区别以及用法。
p2->age = i;
p2->next = p1;//插入连接
p1 = p2;//将p1指针指向p2结点,我这样说就很区别了。因为要用p2申请空间,然后p1会对其进行连接插入的操作。
}
return p1;
}
Student *printf1(Student *head){//打印操作
Student *p = head;
if(p->next==NULL){
printf("没有可遍历的结点\n");
}else{
printf("可遍历的结点的值为\n");
while(p->next!=NULL){
printf("%d,",p->age);
p=p->next;
}
}
}
int main()
{
Student *head= create_head(head);
Student * p2 = insert(head);
printf1(p2);
return 0;
}
一个小小的感想:
终于把动态链表自己去按照自己的思想写出来了。相比当初大一下学期假期在家里上数据结构是并不是太好。近来一定要把不会的东西自己补起来。当我完整的将他人讲课的思维转换为我自己的思维的时候,并可以实现出来完整的东西,这是多么让人喜悦的事情啊。我不怕花费太多的时间,当然前提是自己一直在思考,这个过程充满了痛苦与苦恼,但是很有趣,根是苦的,但是果实是甜的。
注 :会不断查漏补缺,充实文章。将数据结构进行到底。文章会更新。thankyou!此篇会在云鼎社区一同发表。所以文章均为记录所学,以及知识经验分享。
如果有错别字的话,请指正。