单向链表的建立(C语言)
2016-10-31 11:10
288 查看
貌似有段时间没有做原创文章了,聒噪的很,开始正式学习数据结构啦哈哈,今天先做单向链表的建立,希望和大家一起分享
数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性。但数组也同样存在一些弊病。如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要30个大小的数组,有时需要50个数组的大小,难于统一。我们只能够根据可能的最大需求来定义数组,经常会造成一定存储空间的浪费。
我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要。链表就是我们需要的动态数组。它是在程序的执行过程中根据需要有数据存储就向系统要求申请存储空间,决不构成对存储区的浪费。
链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表。首先介绍单链表
下图(图1)是单链表的结构
单 链表有一个头节点head,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给 出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL。
上图还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存的当前情况,既可以连续分配地址,也可以跳跃式分配地址。
看一下链表节点的数据结构定义:
在链表节点的数据结构中,非常非凡的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。
链表的创建、输出步骤
单链表的创建过程有以下几步:
1 ) 定义链表的数据结构;
2 ) 创建一个空表;
3 ) 利用malloc ( )函数向系统申请分配一个节点;
4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新
节点接到表尾;
5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;
单链表的输出过程有以下几步
1) 找到表头;
2) 若是非空表,输出节点的值成员,是空表则退出;
3 ) 跟踪链表的增长,即找到下一个节点的地址;
4) 转到2 ).
就是这样的话头结点默认的data值是没有用的,从头结点的next开始,流程如图下
如果希望表头就有数据接入,则代码改为如下
运行结果如下:
至此,完成链表的创建
数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性。但数组也同样存在一些弊病。如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要30个大小的数组,有时需要50个数组的大小,难于统一。我们只能够根据可能的最大需求来定义数组,经常会造成一定存储空间的浪费。
我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要。链表就是我们需要的动态数组。它是在程序的执行过程中根据需要有数据存储就向系统要求申请存储空间,决不构成对存储区的浪费。
链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表。首先介绍单链表
下图(图1)是单链表的结构
单 链表有一个头节点head,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给 出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL。
上图还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存的当前情况,既可以连续分配地址,也可以跳跃式分配地址。
看一下链表节点的数据结构定义:
struct node { int num; struct node *p; } ;在链表节点的定义中,除一个整型的成员外,成员p是指向与节点类型完全相同的指针。
在链表节点的数据结构中,非常非凡的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。
链表的创建、输出步骤
单链表的创建过程有以下几步:
1 ) 定义链表的数据结构;
2 ) 创建一个空表;
3 ) 利用malloc ( )函数向系统申请分配一个节点;
4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新
节点接到表尾;
5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;
单链表的输出过程有以下几步
1) 找到表头;
2) 若是非空表,输出节点的值成员,是空表则退出;
3 ) 跟踪链表的增长,即找到下一个节点的地址;
4) 转到2 ).
1.输入链表长度的链表
首先是输入链表长度的链表建立打印,先上代码#include <stdio.h> #include <stdlib.h> typedef struct Node *PtrToNode; struct Node { int Data; PtrToNode Next; }; PtrToNode Read(); /* 细节在此不表 */ void Print( PtrToNode L ); /* 细节在此不表;空链表将输出NULL */ int main() { PtrToNode L1; L1 = Read(); Print(L1); return 0; } PtrToNode Read() { int len = 0; int num = 0; PtrToNode h = NULL; PtrToNode last = NULL; h = ( PtrToNode )malloc( sizeof( struct Node ) );//建立头结点 h->Next = NULL; last = h; scanf( "%d",&len ); while(len){ scanf( "%d",&num ); PtrToNode node = ( PtrToNode )malloc( sizeof( struct Node ) ); node->Data = num; node->Next = NULL; last->Next = node; last = node; len--; } return h; } void Print( PtrToNode L ) { L=L->Next; if(L==NULL){ printf("NULL\n"); return; } while(L!=NULL){ printf("%d ",L->Data); L=L->Next; } putchar('\n'); }
就是这样的话头结点默认的data值是没有用的,从头结点的next开始,流程如图下
如果希望表头就有数据接入,则代码改为如下
#include <stdio.h> #include <stdlib.h> typedef struct Node *PtrToNode; struct Node { int Data; PtrToNode Next; }; PtrToNode Read(); /* 细节在此不表 */ void Print( PtrToNode L ); /* 细节在此不表;空链表将输出NULL */ int main() { PtrToNode L1; L1 = Read(); Print(L1); return 0; } PtrToNode Read() { int len = 0; int num = 0; PtrToNode h = NULL; PtrToNode last = NULL; scanf( "%d",&len ); if(len==0) return NULL; else{ scanf("%d",&num); h = ( PtrToNode )malloc( sizeof( struct Node ) );//建立头结点 h->Data=num; h->Next = NULL; last = h; len--; while(len){ scanf( "%d",&num ); PtrToNode node = ( PtrToNode )malloc( sizeof( struct Node ) ); node->Data = num; node->Next = NULL; last->Next = node; last = node; len--; } return h; } } void Print( PtrToNode L ) { if(L==NULL){ printf("NULL\n"); return; } while(L!=NULL){ printf("%d ",L->Data); L=L->Next; } putchar('\n'); }
2.以一个非负数作为链表的结尾
代码如下#include <stdio.h> #include <stdlib.h> typedef struct Node *PtrToNode; struct Node { int Data; PtrToNode Ne c424 xt; }; PtrToNode Read(); /* 细节在此不表 */ void Print( PtrToNode L ); /* 细节在此不表;空链表将输出NULL */ int main() { PtrToNode L1; L1 = Read(); Print(L1); return 0; } PtrToNode Read() { int num = 0; PtrToNode h = NULL; PtrToNode last = NULL; scanf( "%d",&num ); if(num<=0) return NULL; else{ h = ( PtrToNode )malloc( sizeof( struct Node ) );//建立头结点 h->Data=num; h->Next = NULL; last = h; scanf( "%d",&num ); while(num>0){ PtrToNode node = ( PtrToNode )malloc( sizeof( struct Node ) ); node->Data = num; node->Next = NULL; last->Next = node; last = node; scanf( "%d",&num ); } return h; } } void Print( PtrToNode L ) { if(L==NULL){ printf("NULL\n"); return; } while(L!=NULL){ printf("%d ",L->Data); L=L->Next; } putchar('\n'); }
运行结果如下:
至此,完成链表的创建
相关文章推荐
- C语言单向链表的建立
- C语言单向链表的建立
- 头插法建立单向链表 C语言实现
- c语言:写一个函数建立一个有3名学生数据的单向动态链表
- C语言单向链表的建立
- C语言单向动态链表程序,实现链表的建立,合并,重新排序,链表元素的插入与删除,以及根据元素成员的值进行元素删除。
- C语言单向链表的建立
- C语言单向链表的建立
- iOS开发之C语言单向链表的建立
- 尾插法建立单向链表 C语言实现
- C语言单向链表的建立
- c语言:写一个函数建立一个有3名学生数据的单向动态链表
- C语言链表操作(新增单向链表的逆序建立)
- 建立单向链表
- 建立一个带有头结点的单向链表,并将存储在数组中的字符依次转储到链表的各个结点中
- 建立一个带头结点的的单向链表并输出到out53.dat和屏幕上。各节点的值为对应的下表。链表的节点数及输出地文件名作为参数传入
- 程序功能:建立一个带有头结点的单向链表,并将存储在数组中的字符依次转储到链表的各个结点中。
- c语言实现--单向循环链表操作
- 单向链表之创建添加(C语言实现)
- C语言之单向链表