本文中链表都是没有头结点的,即头指针指向的结点就存数据,head==NULL链表为空
链表就是一种线性表,优点是不用事先知道要开多少空间、有多少数据,插入删除数据快,相对的,缺点就是不能像数组那样直接访问第i个数据,因此不能快速排序。
一、结点
struct node
{
int data; //链表中存储的数据
struct node* next; //指向下一个结点
};
二、链表的创建
struct node* Creat(int n) //创建链表 n是数据数
{
struct node *head=NULL;
struct node *q=NULL; //q保存前驱结点
while(n--)
{
struct node* p=(struct node*)malloc(sizeof(struct node)); //创建一个新结点并给该结点开空间
scanf("%d",&p->data);
p->next=NULL; //初始化新结点的next指针
if(head==NULL) //head==NULL 则该节点是第一个结点
head=p;
else
q->next=p; //前一个结点的next指向当前结点
q=p; //让q指向新结点,则下次循环q指向的结点就是前一个结点
}
return head; //返回头指针,没有头指针我们就找不到链表了
};
三、链表的删除
1.按值删除,删除所有值为x的结点
struct node* Delete(struct node* head,int x) //x是要删除的值
{
while(head!=NULL&&head->data==x) //把前面的值为x的结点删除
head=head->next;
if(head==NULL) //如果删空了直接return
return head;
struct node *q=head; //前面的x已经删除了,第一个结点一定不等于x,从头结点的下一个结点开始遍历
while(q!=NULL&&q->next!=NULL)
{
if(q->next->data==x)
q->next=q->next->next; //删除结点
q=q->next;
}
return head;
};
2.删除第pos个结点
struct node* Delete(struct node* head,int pos) //删除第pos个点,从0开始计数
{
if(pos==0)
return head->next; //如果删除第0个 直接返回指向第1个结点的指针
int num=0;
struct node *p=head;
while(p!=NULL&&p->next!=NULL) //遍历
{
num++;
if(num==pos) //当前是第pos个结点,删除并返回
{
p->next=p->next->next;
return head;
}
p=p->next;
}
return head; //循环结束说明链表中结点数小于x,返回头指针
};
四、链表的插入
struct node* Insert(struct node* head,int n,int pos) //在pos位置后插入n
{
struct node *t=(struct node*)malloc(sizeof(struct node));
t->data=n;t->next=NULL; //创建新结点开空间并初始化
if(pos==0)
{
if(head!=NULL)
{
t->next=head;
head=t;
return head; //如果pos为0,直接插入并返回
}
return t; //如果原链表为空链表,直接返回t
}
struct node *p=head;
int num=0;
while(p!=NULL)
{
num++;
if(num==pos)
{
t->next=p->next;
p->next=t;
return head;
}
p=p->next;
}
return head; //没有第pos个结点 插入失败
};
五、链表的排序
因为链表的优势就是插入数据快,所以这里写一个插入排序,其他排序就不写了
struct node* Sort(struct node *head)
{
if(head==NULL)
return head;
struct node *Head=head; //Head是排好序后的链表,将剩下的结点插入到Head链表中
head=head->next;
Head->next=NULL;
while(head!=NULL)
{
struct node *t=head; //t是剩下的结点中的第一个
head=head->next;
struct node *q=NULL; //q指向p的前驱结点
struct node *p=Head;
while(p!=NULL&&p->data<t->data) //在Head链表中找到第一个大于等于t->data的结点
{
q=p;
p=p->next;
}
t->next=p;
if(q==NULL) //q==NULL说明当前点是最小的,要放在第一个
Head=t;
else
q->next=t;
}
return Head;
};