二、链表
1.单向链表
-
特点
链式存储,即存储空间不是连续的。
逻辑形式如:a->b->c->d…
-
优点
1.插入与删除效率比较高,比较灵活。
2.在内存上的存储结构不要求是连续的,储存更方便。
-
缺点
1.物理空间上不保证连续性,查询效率没有顺序表高。
2.只有一个指针,向后查找方便,但是向前查找很麻烦。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Node
{
int x;
struct Node *next;
};
void InitListHead(struct Node *phone);
//增
bool InsertNodeAtlast(struct Node *phead,int val); //尾插法:建立链表
bool InsertNode(struct Node *phead,int val_a,int val_b); //在指定节点后面插入节点
//删
bool RemoveNode(struct Node *pthread,int val); //删除值为val的节点
bool DestoryList(struct Node *phead); //销毁链表(将链表的所有节点删除)
void PrintList(struct Node *phead); //遍历并输出链表的所有数据域的值
int main(void)
{
struct Node head; //链表头节点
InitListHead(&head);
InsertNodeAtlast(&head,100);
InsertNodeAtlast(&head,200);
InsertNodeAtlast(&head,300);
InsertNodeAtlast(&head,400);
InsertNodeAtlast(&head,500);
PrintList(&head);
InsertNode(&head,500,600); //在值为500的节点之后插入一个新的节点
PrintList(&head);
InsertNode(&head,300,888); //在300后面插入一个节点888
PrintList(&head);
//销毁链表
DestoryList(&head);
PrintList(&head);
return 0;
}
void InitListHead(struct Node *phead)
{
phead->x = 0;
phead->next = NULL;
}
//在末尾插入元素
bool InsertNodeAtlast(struct Node *phead,int val)
{
struct Node *plast = NULL;
//1.创建一个新的节点,数据域的值为x
struct Node *pnew = (struct Node *)malloc(sizeof(struct Node));
if(!pnew)
return false;
pnew->x = val;
pnew->next = NULL;
//2.遍历链表,找到这个链表的最后一个节点
for(plast = phead;plast->next != NULL;plast = plast->next)
{}
//3.将新的节点插入为节点之后
plast->next = pnew;
return true;
}
void PrintList(struct Node *phead)
{
struct Node *pcur = phead->next;
while(pcur != NULL)
{
printf("%d\t ",pcur->x);
pcur = pcur->next;
}
printf("\n");
}
bool InsertNode(struct Node *phead,int val_a,int val_b)
{
struct Node *pcur = NULL;
struct Node *pnew = NULL;
//1.遍历链表,找到域val_a值相同的节点
for(pcur = phead;pcur != NULL && pcur->x != val_a;pcur = pcur->next)
{}
if(pcur == NULL)
{
printf("没有找到与%d 值相同的节点.\n",val_a);
return false;
}
printf("pcur : %d\n",pcur->x);
//2.创建一个新的节点,数据域的值为 val_b
pnew = (struct Node *)malloc(sizeof(struct Node));
if(!pnew)
return false;
pnew->x = val_b;
pnew->next = NULL;
//3.将新节点插入到值为val_a的节点之后
pnew->next = pcur->next;
pcur->next = pnew;
return true;
}
//删除指定的节点
bool RemoveNode(struct Node *phead,int val)
{
struct Node *prev = NULL;
struct Node *pcur = NULL;
for(pcur = phead;pcur != NULL && pcur->x != val;pcur = pcur->next)
{
prev = pcur; //将当前位置作为前一个节点的位置,然后pcur指向next
}
if(pcur == NULL)
{
printf("没有找到对应的节点.\n");
return false;
}
//删除相应的节点
prev->next = pcur->next;
pcur->next = NULL;
free(pcur);
return true;
}
bool DestoryList(struct Node *phead)
{
struct Node *pcur = phead->next; //pcur当前指向头结点
//从头结点开始删除,遍历删除所有的节点
while(pcur != NULL)
{
phead->next = pcur->next;
pcur->next = NULL;
free(pcur);
pcur = phead->next;
}
return true;
}