数组的亲兄弟:链表!
就好像函数和映射的区别(同是储存东西,一个只有数字,一个什么都可以存储,并比数组更加方便快捷)
什么是链表:
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作。
关于链表的基本操作(创建、增、删、查、改)
1.初始化
#include<stdio.h>
#include<stdlib.h>
#include<math.h>//插入所需的头文件
int main()
{
typedef struct person{
int n;
char'c';
struct person *next)
}node *x;
void initlist(x*p)
{
if(((*head)=(*p)malloc(sizeof(node)))==NULL) /*为头结点分配一个存储空间*/
exit(-1);
(*head)->next=NULL; /*将单链表的头结点指针域置为空*/
}
2.创建链表
Node* jianbiao(int n)//返回Node*类型的值
{
int i;
Node *start=NULL,*node,*end;//建立头结点,普通结点,尾结点,头结点初始化
start=(Node*)malloc(sizeof(Node));//申请内存
end=start;//空表则尾结点与头结点一致
for(i=0;i<n;i++)
{
node=(Node*)malloc(sizeof(Node));
scanf("%d",&node->store);//输入数据
end->next=node;//连接结点
end=node;//指向下一个结点
}
end->next=NULL;//建表结束
return start;//返回链表头地址
}
3.遍历链表
void bianli(Node *start)
{
Node *h=start;//定义指针指向链表头地址
while(h->next!=NULL)//遍历
{
h = h->next;
printf("%d ",h->store);
}
}
4.查
void cha(Node *start,int a)
{
int i=0;
Node* temp=start;
while(i<a)
{
temp=temp->next;
i++;
}printf("%d",temp->store);
}
5.增
//p为原链表,elem表示新数据元素,add表示新元素要插入的位置
link * insertElem(link * p, int elem, int add) {
link * temp = p;//创建临时结点temp
link * c = NULL;
int i = 0;
//首先找到要插入位置的上一个结点
for (i = 1; i < add; i++) {
if (temp == NULL) {
printf("插入位置无效\n");
return p;
}
temp = temp->next;
}
//创建插入结点c
c = (link*)malloc(sizeof(link));
c->elem = elem;
//向链表中插入结点
c->next = temp->next;
temp->next = c;
return p;
}
6.删
//p为原链表,add为要删除元素的值
link * delElem(link * p, int add) {
link * temp = p;
link * del = NULL;
int i = 0;
//temp指向被删除结点的上一个结点
for (i = 1; i < add; i++) {
temp = temp->next;
}
del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
free(del);//手动释放该结点,防止内存泄漏
return p;
}
注意在申请完动态内存之后,要记得释放空间。
完成链表关系时要多动手画图,这样有助于理解