赞
踩
1.链表是由如干个节点所组成的(链表的各个节点结构是完全相似的),节点是由有效数据和指针组成的,有效数据区是用来储存数据的,指针是用来指向下一个节点的首地址,从而构成链表。
2.链表是用来解决数组的大小不能动态扩展的问题,灵活性比数组好,和数组一样也是用来存储数据的,链表需要分配多少个动态数据分配多少个,不占用额外内存。
3.单链表的实现
(1)单链表的节点构成
有效数据部分,和指针部分
(2)定义的struct
node只是一个结构体,本生没有变量生成,也不占用内存,结构体定义相当于为链表节点定义了一个模板,但是还没有一个节点,将来在实际创建一个链表时需要一个节点用这个模板复制一个即可
3.堆内存的申请和使用
(1)链表的内存要求比较灵活,不能用栈,也不能用data数据段,只能用堆内存
(2)使用堆内存创建一个链表节点的步骤:1、申请堆内存,大小为一个节点的大小(检查申请结果是否正确);2、清理申请到的堆内存;3、把申请到的堆内存当做一个新节点;4、填充这个新节点的有效数据和指针区域。
4.链表的头指针
(1)头指针并不是节点,而是一个普通指针,只占4个字节,它的类型是struct node *型,所以他才能指向链表的节点.
(2)访问链表中各个节点的数据只能用头指针,因为实际中,我们保存链表的时候是不会保存各个节点的指针的,只能通过头指针来访问链表节点。
(3)前一个节点的pNext指针能帮我们找到下一个节点。
一个一个的创建节点:
#include <stdio.h> #include <string.h> #include <stdlib.h> //构建链表节点 struct node { int data; //有效数据 struct node *pNext; //指向下一个节点的指针 }; int main(void) { //定义头指针 struct node *pHeader = NULL; //创建一个链表节点 struct node *p1 = (struct node *)malloc(sizeof(struct node)); if(NULL == p1) { printf("malloc error\n"); return -1; } //清理申请到的堆内存 // void bzero(void *s, size_t n); bzero(p1,sizeof(struct node)); //填充节点 p1->data = 1; p1->pNext = NULL; //将来要指向下一个节点的首地址 pHeader = p1; struct node *p2 = (struct node *)malloc(sizeof(struct node)); if(NULL == p2) { printf("malloc error\n"); return -1; } //清理申请到的堆内存 // void bzero(void *s, size_t n); bzero(p2,sizeof(struct node)); //填充节点 p2->data = 2; p1->pNext = p2; //将来要指向下一个节点的首地址 struct node *p3 = (struct node *)malloc(sizeof(struct node)); if(NULL == p3) { printf("malloc error\n"); return -1; } //清理申请到的堆内存 // void bzero(void *s, size_t n); bzero(p3,sizeof(struct node)); //填充节点 p3->data = 3; p2->pNext = p3; //将来要指向下一个节点的首地址 //访问链表中的有效数据(只能用pHeader访问) //pHeader->data; //pHeader->data等同于p1->data printf("node1 data = %d\n",pHeader->data); printf("p1->data = %d\n",p1->data); printf("node2 data = %d\n",pHeader->pNext->data); printf("p2->data = %d\n",p2->data); printf("node3 data = %d\n",pHeader->pNext->pNext->data); printf("p3->data = %d\n",p3->data); return 0; }
将创建节点的程序封装成一个函数:
#include <stdio.h> #include <string.h> #include <stdlib.h> //构建链表节点 struct node { int data; //有效数据 struct node *pNext; //指向下一个节点的指针 }; //函数功能,创建链表节点 //返回值:指针,指向我们本函数新创建的一个节点的首地址 struct node *creat_node(int data) { //创建一个链表节点 struct node *p = (struct node *)malloc(sizeof(struct node)); if(NULL == p) { printf("malloc error\n"); return NULL; } //清理申请到的堆内存 // void bzero(void *s, size_t n); bzero(p,sizeof(struct node)); //填充节点 p->data = data; p->pNext = NULL; //将来要指向下一个节点的首地址 return p; } int main(void) { //定义头指针 struct node *pHeader = NULL; pHeader = creat_node(1); pHeader->pNext = creat_node(2); pHeader->pNext->pNext = creat_node(3); //访问链表中的有效数据(只能用pHeader访问) printf("node1 data = %d\n",pHeader->data); printf("node2 data = %d\n",pHeader->pNext->data); printf("node3 data = %d\n",pHeader->pNext->pNext->data); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。