链表
- 单链表
链表的插入:
s->next=p->next;
p->next=s;
链表的删除:
引进一个指针保存p
q=p->next;
p->next=q->next; - 双向链表
链表的插入:
s-prev=p;
s->next=p->next;
p->next->prev=s;
p->next=s;
链表的删除:
p->prev->next=p->next;
p->next->prev=p->prev;
连接两个循环单链表
p=a->next; //保存A表的头结点位置
a->next=b->next->next; //B的开始结点链接到A表尾
free(b->next);
b->next=p;
return b;
注:a,b为已构建好的循环链表,具有尾指针
链表中的环
- 判断链表是否有环
快慢指针 快慢指针初始值都为链表头结点
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
true; - 找到环的入口
快慢指针相等的点就是环的入口 - 若存在环,求环上结点的个数
一指针记录相遇点,当slow指针再次走到相遇点时,所经过的结点个数
简单的计数器原理,不赘述 - 求链表的长度
环节点数加上头结点到环入口的距离
约瑟夫环
附代码
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *create(int n)//循环链表的创建
{
struct node *p,*head,*s;
p=NULL;
head=(struct node *)malloc(sizeof(struct node));
p=head;
int i=1;
while(i<=n){
s=(struct node *)malloc(sizeof(struct node));
s->data=i++;
p->next=s;
p=s;
}
s->next=head->next;
free(head);
return s->next;
}
int main()
{
int m=41;
int n=3;
int i;
struct node *p=create(m);
struct node *temp;
while(p!=p->next)
{
for(i=1;i<n-1;i++)
p=p->next;
printf("%-4d",p->next->data);
temp=p->next;
p->next=temp->next;//猴子出库
free(temp);
p=p->next;
}
printf("%d",p->data);//最后的赢家
return 0;
}
链表的相关操作
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *CreateList(int n)//链表的创建
{
struct node *p,*q,*head;
head=NULL;
for(int i=0;i<n;i++)
{
p=(struct node *)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
}
return head;
free(p);
}
int ListLength(struct node *head)//统计链表长度
{
struct node *p;
p=head;
int n=0;
while(p)
{
n++;
p=p->next
}
return n;
}
void DestoryList(struct node *head)//链表的摧毁
{
struct node *p,*q;//创建两个指针交替使用
p=head;
q=head->next;
while(q)
{
free(p);
p=q;
q=q->next;
}
free(p);
}
void print(struct node *head)//链表的打印
{
struct node *q;
q=head;
while(q)
{
printf("%d\n",q->data);
q=q->next;
}
}
int main()
{
struct node *p;
int n;
scanf("%d",&n);
p=CreateList(n);
print(p);
}