c语言链表的学习

    技术2025-06-13  19

    链表和数组的不同点在于:数组里所有的元素的地址都是连着的,不能分散着。而链表是可以分散的。但是链表和数组也各有各的优点。数组的优点就是占用的内存小,链表的优点是内存可以不是整块的使用,可以使用一些分散的内存块,这样可以有效的利用内存来记录数据。 比如,绿色的就是用的数组的方式,四个元素只需要四个存储单元,但是你用链表就需要8个存储单元,但是这8个可以不连续的,但是那两个还是必须连续的,所以一个结构体内有多个数据的话,内存使用效率就会提高,不过一个结构体内的数据域和指针域还是必须连着的。在数据比较多复杂的时候就可以用链表,它可以把各个散落的存储单元利用起来,提高了利用效率。

    静态链表

    typedef struct student { int score; struct student *next; //创建一个链表,包含数据和指针 } LinkList; ```这是一个结构体,包含一个数据和一个指针 我们可以定义三个静态链表 ```cpp int main() { LinkList node1={1,NULL}; //创建三个结构体 LinkList node2={2,NULL}; LinkList node3={3,NULL}; node1.next=&node2; //第一个结构体内的指针指向第二个结构体地址 node2.next=&node3; node3.next=NULL; LinkList *head=&node1; //创建一个头结点 while(head != NULL) //遍历链表,可以用来查询链表数量 { printf("data:%d\n",head->score); head=head->next; //这个指针等于指向下一个结构体的指针 } }

    这样虽然只有三个数据,但是指针也会占用存储单元,相当于一共占用了6个存储单元,是数组的两倍。推荐数据量小就用数组。实际过程中,链表一般是动态的,我们需要对数据删除,增加等等。。。

    动态链表

    其实我觉得动态链表和静态链表差不多,就是在增加和删除节点的时候用静态链表更容易理解,动态链表则难一点: 创建结构体,一个数据域一个指针域还是一样的

    typedef struct student { int score; struct student *next; //创建一个链表,包含数据和指针 } LinkList;

    然后我们先循环创建一个链表

    创建链表

    //创建一个列表 LinkList *CreateList(int n) { int i; LinkList *head,*node,*end; //定义一个头结点 head=(LinkList*)malloc(sizeof(LinkList)); //给头结点申请内存 end=head; //这个为什么头结点等于 //尾结点,这是因为链表还没有创建,所以是没有数据的,所以头结点就等于尾结点 //我是这么理解的,刚学 end->next=NULL; //链表最后一个结点的指针为空 for(i=0;i<n;i++) //循环创建链表 { node=(LinkList*)malloc(sizeof(LinkList)); node->score=i; //给结点数据赋值 end->next=node; //这个node是新申请的节点 //而end是最后一个结点,最后一个结点指向新申请的那个结点,我的理解 node->next=NULL; end=node; } return head; }

    增加结点

    这个增加结点的时候,需要定义两个结构体,其中一个是新申请的节点,另外一个结点是用来交换的,如果没有这个结点,链表会不停的指向结点,相当于循环一样。 如果只定义一个结构体的话,我的理解是这么写的`

    node->next=now; now->score=mem; //赋值于新的节点的数据值 now->next=node; //now的下一个指针指向node

    但这样不行,他会一直在那个结点和增加的节点循环,相当于,所以就需要定义两个结构体,其中一个用来交换,避免出现这种情况。

    //插入在第几个节点,比如5,插入的节点就是第五个节点 int insert(LinkList *head,int num,int mem) { int i=0; LinkList *node=head; LinkList *swap; //用于交换 LinkList *now; //存入的节点 now=(LinkList*)malloc(sizeof(LinkList)); while(i<num-1) //比如back=5,执行四次,此时循环后是第四个node { i++; node=node->next; } now->score=mem; //赋值于新的节点的数据值 swap=node->next; //sw下一个指针指向swap node->next=now; //node 下一个指针指向now now->next=swap; //now的下一个指针指向swap return 0; }

    删除节点

    int dele(LinkList *head,int back) { int data,i=0; LinkList *node=head; LinkList *now; while(i<back-1) //比如back=5,执行四次,此时循环后是第四个node { i++; node=node->next; } now=node->next; //now等于第五个node的指针 ,这两个是为了释放第五个node的内存 node->next=node->next->next; free(now); return 0; } 删除指针就比较简单了,直接讲第n个指针指向低n+2个指针,就可以了,然后释放那个结点的内存就好了

    遍历链表

    用来打印链表内的数据

    void traverlist(LinkList *head) { LinkList *p=head->next; while(NULL!=p) { printf("该节点数值为:%d\n",p->score); p=p->next; } return; }

    主函数里面就调用这些函数就好了

    int main() { LinkList *phead; phead=CreateList(5); traverlist(phead); printf("111111111111111111111111111\n"); dele(phead,2); traverlist(phead); printf("111111111111111111111111111\n"); insert(phead,3,111); traverlist(phead); }
    Processed: 0.012, SQL: 9