如图所示,链表有很多节点组成,每个节点都有两部分组成,数据项和指针项,指针项指向下一个节点。
特点:链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多;
下面我来讲讲链表的各种操作~~
类型声明
#include "stdio.h"
#include "stdlib.h"
typedef struct A
{
int a;
struct A * next;
} Node;
Node *creatList(int n);
Node *del(Node *head,int s);
Node *sort(Node *head);
Node *Insert(Node *head,int s);
1.新建链表
新建链表分为头插和尾插,下面我介绍一下尾插法。
如图所示:每次都会新开辟一个空间,指针项为空,进入下一次循环的时候,指针项指向新开辟的节点,以此类推,得到一个完整的链表。
下面请看代码实现:
Node *creatList(int n)
{
Node *p, *q,*head;
int i;
head = p = (Node *)malloc(sizeof(Node));
int b;
for(i = 0 ; i < n ; i++)
{
scanf("%d",&b);
q = (Node *)malloc(sizeof(Node));
q->a = b;
q->next = NULL;
p->next = q;
p = q;
}
return head->next;
}
2.删除节点
如图所示,q为要删除的节点,要想删除q,只要让p指向的下一个节点为p指向的下一个节点就行;
下面的代码为删除数据项为s的节点.
Node *del(Node *head,int s)//删除指定元素的节点
{
Node *p,*q;
p=q=head;
while(q->a!=s&&p->next!=NULL)
{
p=q;
q=q->next;
}
if(q->a==s)
{if(q==head)
head=head->next;
else
p->next=q->next;}
return head;
};
3.对链表进行排序
排序有很多种,下面我介绍的是用冒泡法对链表进行排序
冒泡法的思想就是两两进行比较,设置两个链表指针fist,end,第一个用来指向头结点,第二个指向最后一个节点的next值,只要first跟end不重合,循环就继续,每次内循环结束,end就向前面移动一个节点,first不变,在内层循环的时候满足交换条件则交换,直至排序完毕。
Node *sort(Node *head)
{
Node *first=NULL,*end=NULL;
first=head;
while(first != end)
{
while(first->next != end)
{
if(first->a<first->next->a)//两相邻的值进行比较
{
int temp=first->a;
first->a=first->next->a;
first->next->a=temp;
}
first=first->next;
}
end=first;
first=head;
}
return head;
}
4.插入节点
如图所示:
当s节点符合插入要求的时候,先把s->next指向s的下一个节点,也就是s->next=p->next;然后在把s前面的节点指向s,(p->next=s);注意:如果你是用一个指针控制,一定要先连接后面的!
Node *Insert(Node *head,int r)
{
Node *p,*q;
Node *s=(Node *)malloc(sizeof(Node));
p=q=head;
s->a=r;
while(p->a>r&&p!=NULL)
{
q=p;
p=p->next;
}
if(p==head)
{
s->next=head;
head=r;
}
else
{
s->next=q->next;
q->next=r;
}
return head;
}
下面是主函数对自定义函数的调用:
int main()
{
Node *head;
int n;
scanf("%d",&n);
head=creatList(n);
prin(head);
head=sort(head);
prin(head);
head=Insert(head,5);
prin(head);
head=del(head,3);
prin(head);
}