如何用C语言创建一个多文件编译的单向循环链表(插入,删除,修改,以及遍历)
首先,在开始之前,我们要明白,什么是链表?
链表(Linked List)是一种线性数据结构,由一系列节点(Node)组成,每个节点包含数据域和指针域。数据域存储实际数据,指针域存储下一个节点的地址。链表通过指针将节点串联起来,形成链式结构.换句话说就是讲一个数据分为两个部分,一个指针域用来指向下一个数据的地址,一个数据域用来存储自身的数据.
然后,在了解了链表的基本概念之后,我们就可以开始简单链表的创建(我这里用的是Vscode软件),
首先,创建一个叫做link的文件夹,用来存放单向循环链表的内容,包括link.c,link.h以及main.c,注意:main.c在同一个目录下只能有一个主函数,以下是三个函数的代码.
link.c文件:
主要是对链表各个功能的实现,当在创建第一个头结点的时候,由于是循环链表,因此第一个头结点的指针指向的是他自己,当第二个数据来时,先让第二个数据的指针指向上一个数据的指针,再让第一个数据的指针指向下一个数据的数据,后面的数据也是同理,当删除数据时,依旧是先继承,再摘除要删除的数据,记得将他的指针域指向NULL,这样就不会导致删除时,连累到后面的数据,对数据的修改从本质上与删除一样,只是多了一步插入的过程,当然在遍历时.由于是循环链表,而我们又只想让他执行一次,因此在开始遍历时,我们需要创建一个标志来标记头结点,当循环遍历时,遍历到了头结点的标记时,说明我们已经遍历了一遍了.这个时候我们就可以停止了
#include "link.h"
//封装逻辑
plink_t creat_node(int data)
{
plink_t p=(plink_t)malloc(sizeof(plink_t));
if(p==NULL){
perror("malloc");
return NULL;
}
p->data=data;
p->next=p;
return p;
}
void node_insert(plink_t head,plink_t new)
{
new->next=head->next;
head->next=new;
}
//删除head后面的节点
void node_del(plink_t head)
{
plink_t node=head->next;
head->next=node->next;
node->next=NULL;
free(node);
}
//将data上的数据改为new
void node_updata(plink_t head,plink_t new)
{
plink_t node=head->next;
new->next=node->next;
head->next=new;
node->next=NULL;
free(node);
}
//调用逻辑
//创建头结点
plink_t link_init()
{
return creat_node(-1);
}
//将data数据转为指针域和数据域,同时将他插入带头结点后面
void link_insert_head(plink_t head,int data)
{
plink_t p=creat_node(data);
if(p==NULL)
return;
node_insert(head,p);
}
//尾部插入
void link_insert_tail(plink_t head,int data)
{
plink_t p=creat_node(data);
if(p==NULL)
return;
while(head->next!=NULL)
head=head->next;
node_insert(head,p);
}
//输入要删除的数据
void link_del(plink_t head,int data)
{
while(head->next!=NULL)
{
if(head->next->data==data)
{
node_del(head);
return;
}
head=head->next;
}
printf("没有找到要删除的数据!\n");
}
//输入要修改的数据
void link_change(plink_t head,int data,int newdata)
{
plink_t new=creat_node(newdata);
if(new==NULL)
return;
while(head->next!=NULL)
{
if(head->next->data==data)
{
node_updata(head,new);
return;
}
head=head->next;
}
printf("没有找到要修改的旧数据!\n");
}
//根据count找到要修改的数据
void insertdata(plink_t head,int count,int data)
{
plink_t new_data=creat_node(data);
if(new_data==NULL)
return;
int len=1;
while(head->next!=NULL)
{
if(len==count)
{
node_insert(head,new_data);
return;
}
head=head->next;
len++;
}
}
//遍历打印
void display(plink_t head)
{
plink_t a=head;
printf("遍历结果为:");
while(head->next!=a)
{
head=head->next;
printf("%d ",head->data);
}
printf("\n");
}
link.h文件:
主要是对link.c里面文件的各个函数的声明,以及对链表结构体的创建
#ifndef __LINK_H
#define __LINK_H
#include<stdio.h>
#include<stdlib.h>
typedef struct link{
int data;
struct link *next;
}link_t,*plink_t;
//函数逻辑
plink_t link_init();
plink_t creat_node(int data);
void node_insert(plink_t head,plink_t new);
void node_del(plink_t head);
void node_updata(plink_t head,plink_t new);
//调用逻辑
void link_insert_head(plink_t head,int data);
void link_insert_tail(plink_t head,int data);
void link_del(plink_t head,int data);
void display(plink_t head);
void link_change(plink_t head,int data,int newdata);
void insertdata(plink_t head,int count,int data);
#endif
main.c文件:
通过创建一个头结点,然后在while里面输入数据,判断输入的数据是不是%d类型,如果不是的话则会退出程序,这样子就可以由自己来控制程序的进行与否,当输入的数据大于0时,则会在链表中加入这个数据,当输入的数据小于0时,则会删除数据数据的相反数,如果想要直接删除的话可以通过简单修改代码实现,当要删除的数据不存在时则会输出要删除的数据不存在,这个可以通过link.c查看,要修改的话则是输入要修改的结点数,修改那个结点后的数据,这个也可以通过link.c查看,在每个函数内都有定义,当然在执行插入\删除和修改时,每次都会对链表进行遍历,如果不想显示那么多次,可以只在最后进行遍历,将dispaly函数删掉放在最后就行.总之,main.c就是实现对函数内容的调用和实现.
#include "link.h"
int main()
{
plink_t head=NULL;
head=link_init();
int temp,data;
while(1)
{
temp=scanf("%d",&data);
if(temp==0)
break;
if(data>=0)
{
link_insert_tail(head,data);
display(head);
}
else
{
data=-data;
link_del(head,data);
display(head);
}
}
getchar();
while(1)
{
int count;
printf("请输入你要在第几个节点后插入:");
temp=scanf("%d",&count);
if(temp==0)
break;
int newdata;
printf("请输入你要替换进去的数:");
scanf("%d",&newdata);
insertdata(head,count,newdata);
display(head);
}
free(head);
return 0;
}
更多推荐



所有评论(0)