链表的概念:
当一组数据中需要频繁的进行插入、删除操作的时候,链表是首选的数据结构
链表的组成:
链表是由结点组成
结点分为两部分:
1:数据域,保存存储的数据元素
2:指针域,指向下一个结点的地址
结点的创建:
struct Node{
int data; //数据域
struct Node *next; //指针域
};
结点的类型:
头结点:只有指针域 数据域不存放数据
首元结点:第一个存放数据的结点,成为首元结点
链表的实现
链表的初始化
typedef struct Node{
int data; //数据域
struct Node * next; //指针域
}Node,*LinkList; //Node struct Node 的别名
//LinkList struct Node * 的别名
//链表的初始化
LinkList create(){
//动态申请空间 head指针指向这个空间
LinkList head=(Node *)malloc(sizeof(Node));
if(head==NULL){
printf("内存分配失败\n");
return NULL;
}
head->next=NULL; //头结点指针域赋值为 NULL
return head; //返回头结点 指针
}
链表的长度获取
//实际传的是头结点地址,但是代表的是一个链表
int getSize(LinkList head){
//头结点为空
if(!head){
printf("空间开辟失败!");
return 0;
}
//p 指向首元结点
Node *p=head->next;
//LinkList q=head->next;
//计算器
int count=0;
while(p!=NULL){
count++;
p=p->next; //指针后移
}
//返回链表长度
return count;
}
链表的遍历
void foreach(LinkList head){
if(!head){
printf("空间开辟失败!");
return;
}
LinkList p=head->next;
while(!p){
printf("%d",p->data);
p=p->next;
}
}
链表的清空
void clear(LinkList head){
if(!head){
return;
}
Node *p=head->next;
while(!p){
//q存放的是p下一个结点地址
LinkList q=p->next;
//释放p
free(p);
p=q;
}
head->next=NULL
}
链表的销毁
void destroy(LinkList head){
if(!head){
return;
}
clear(head);
free(head);
head = NULL; //指针设置为 空
}
链表的插入(尾插法)
void insert(LinkList head){
if(!head){
return;
}
int num;
printf("请输入你要插入的结点数量:\n");
scanf("%d",&num);
int i;
Node *q=head;
for(i=0;i<num;i++){
LinkList p=(Node *)malloc(sizeof(Node));
printf("请输入数据域的值:");
scanf("%d",&p->data);
q->next=p;
q=q->next;
}
}
链表的插入(头插法)
void insert(LindList head){
if(!head){
return;
}
int i,num;
printf("请输入你要插入的结点数量:\n");
scanf("%d",&num);
for(i=0;i<num;i++){
Node *p=(Node *)malloc(sizeof(Node));
printf("请输入数据域的值:");
scanf("%d",&p->data);
p->next=NULL;
//头插法
p->next = head->next;
head->next=p;
}
}
链表的删除
//根据元素的值去删除结点
void delete(LinkList head,int value){
if(head==NULL){
return;
}
Node *p=head; //p指针指向头结点的
Node *q;
while(p->next!=NULL){
if(p->next->data==value){
q=p->next;
p->next=q->next;
free(q);
}else{
p=p->next;
}
}
}