最近在准备计算机考研,正在复习数据结构的知识点,刚开始学习链表的时候实在是有些痛苦,在痛苦了几个小时后,终于有所收获,在此记录一下
链表----属性
①:相邻元素之间通过指针连接。
②:最后一个元素的后继指针为NULL。
③:链表的空间能够按需分配。
④:没有内存空间的浪费。
单向链表
链表通常是指单向链表,它包含多个结点,每个结点都有一个指向后继元素的next(下一个)指针。表中最后一个结点的next值为NULL,表示链表的结束。
链表的简单实现:
定义一个结构体用来生成结点:
typedef struct node
{
int date;
struct node *next;
}Node;
定义一个struct node型的结构体,在以后的程序中用Node来代替struct node出现(方便更改和操作);
定义一个结构体用来存放链表的头结点和尾结点:
typedef struct node
{
Node *head;
Node *tail;
}LNode;
该结构体中存放的是两个结点,(是地址!!!!)不可以直接对他进行取值!!
生成一个元原始链表(空链表,没有指向任何结点)
LNode *createlist()
{
LNode *list=(LNode *)malloc(sizeof(*list));
list->head=NULL;
list->tail=NULL;
return list;
}
新生成的原始链表要返回给主调函数用,注意返回值类型和指针函数类型;
给原始链表赋值:
void crea(LNode *list)
{
while(1)
{
int i;
scanf("%d",&i);
if(i==100)
{
break;
}
//生成孤立结点
Node *pnew=(Node *)malloc(sizeof(*pnew)); //注意这里要在while()里面定义和分配空间!!!
pnew->next=NULL; //因为每添加一个新结点就需要多增加一块存储空间!!!
pnew->date=i; //这里错 1 次!!
//判断链表是否为空链表,是空链表就让链表的头和尾都指向孤立结点
if(list->head==NULL)//注意不能直接用head!!! //这里错 1 次!!
{
list->head=pnew;
list->tail=pnew;
}
else //不是孤立结点就插入结点生成链表
{
list->tail->next=pnew; //尾插法;1.让原链表的next指向新结点,
//使新结点成为原链表尾结点的下一个结点;
list->tail=pnew; //2.让原链表的尾结点指向新结点,更新尾结点的位置;
// pnew->next=list->head; //头插法:1.让新结点的next指向原链表的头结点;
// list->head=pnew; //2.让原链表的头结点指向新结点,更新头结点的位置;
}
}
}
打印链表:
void print(LNode *list)
{
if(list->head==NULL) //若链表为空,直接退出
{
return ;
}
Node *p=list->head; //注意这里p指向的是链表的头结点,p的类型是结点型的!!不是链表型的。
while(p)
{
printf("%d ",p->date);
p=p->next; //对结点进行操作!!
}
printf("\n");
}
2).打印并销毁链表
void print(LNode *list)
{
if(list->head==NULL) //若链表为空,直接退出
{
return ;
}
Node *p=list->head; //用来指向要打印的结点
Node *pre=NULL; //用来指向打印完的结点
while(p)
{
printf("%d ",p->date);
pre=p; //指向打印完的结点
p=p->next;
free(pre); //销毁打印完的结点(释放其所占空间),即逐渐销毁链表所有的结点。
}
printf("\n");
free(list); //把空链表也销毁
}
如果有问题 请指出
我们一起进步