顺序打乱,分类差不多是同一个类型的哦
链表的一些应用
7-6 链表去重
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
struct node//利用结构体
{
int data,next;//存储 键值,下一个结点的地址
}a[100005];//下标 表示 地址
int main()
{
int f[100005]={0};//置所有键值状态为0
int ne[100005];//表示 去重后的链表 存储地址
int de[100005];//表示 删除后的链表 存储地址
int first_add,n,//输入 首地址和个数
int i;
int l1=0;//表示 ne[]数组中的个数
int l2=0;//de[]数组中的个数
int add,data,next;//定义 地址,键值,下一个结点的地址
//输入
scanf("%d %d",&first_add,&n);
for(i=0;i<n;i++)
{
scanf("%d %d %d",&add,&data,&next);
a[add].data=data;
a[add].next=next;
}
//从第一个地址开始,判断是否为空地址
add=first_add;//从首地址开始
while(add!=-1)
{
int data=abs(a[add].data);//键值 取绝对值
if(f[data]==0)//第一次出现,存储到ne数组
{
ne[l1++]=add;
f[data]=1;//置此时状态为1
}
else
de[l2++]=add;//否则存储到de数组
add=a[add].next;//依次到下一个地址
}
//输出
//输出 去重后的
//注意 下一个地址的输出 不是原来链表的下一个,而是新的链表的下一个
for(i=0;i<l1;i++)
{
if(i==l1-1)
printf("%05d %d -1\n",ne[i],a[ne[i]].data);//地址,键值
else
printf("%05d %d %05d\n",ne[i],a[ne[i]].data,ne[i+1]);//地址,键值,下一个地址
}
//输出 删除的
for(i=0;i<l2;i++)
{
if(i==l2-1)
printf("%05d %d -1\n",de[i],a[de[i]].data);
else
printf("%05d %d %05d\n",de[i],a[de[i]].data,de[i+1]);
}
return 0;
}
7-3 重排链表
include <stdio.h>
#include <stdlib.h>
struct node//利用结构体
{
int data,next;//存储 键值,下一个节点的地址
}a[100005];// 下标 表示 地址
int main()
{
int first_add,n,add,data,next;//第一个地址,n个数据,定义地址,键值,下一个节点的地址
//输入
scanf("%d %d",&first_add,&n);
int i;
for(i=0;i<n;i++)
{
scanf("%d %d %d",&add,&data,&next);
a[add].data=data;
a[add].next=next;
}
int in[100005];//in数组表示 原来的链表 存储地址
int ne[100005];//ne数组表示 重排的链表 存储地址
int count=0;//in数组中的个数
//从第一个地址开始,判断地址是否为空
add=first_add;//从首地址开始
while(add!=-1)
{
in[count++]=add;//存储地址
add=a[add].next;
}
//重排链表,将原链表的最后一个(倒数第二),移到第一个(第二个)
// 将原链表的第一个(第二个),移到最后一个(倒数第二)
int in_left=0,in_right=count-1;//分别指向in数组的最左侧和最右侧
int ne_point=0;//指向ne数组
while(in_left<=in_right)
{
if(in_left<in_right)
{
ne[ne_point]=in[in_right];//将原链表的最后一个,移到第一个
ne_point++;
in_right--;
ne[ne_point]=in[in_left];//将原链表的第一个,移到最后一个
ne_point++;
in_left++;
}
else
{
ne[ne_point]=in[in_left];
ne_point++;
in_left++;
}
}
//输出
//依旧注意下一个地址的输出
for(i=0;i<count;i++)
{
if(i==count-1)
printf("%05d %d -1\n",ne[i],a[ne[i]].data);
else
printf("%05d %d %05d\n",ne[i],a[ne[i]].data,ne[i+1]);
}
return 0;
}
两个链表
7-1 两个有序链表序列的合并
#include <stdio.h>
#include <stdlib.h>
//结构体
struct node
{
int data;
struct node*next;
};
int count=0;//定义 链表的长度
//利用头指针,创建链表
struct node* creat()
{
struct node*head,*tail,*p;//定义指针
//创建头指针
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
tail=head;//尾指针
//输入,创建链表
int x;
while(~scanf("%d",&x)&&x!=-1)
{
p=(struct node*)malloc(sizeof(struct node));
p->data=x;
tail->next=p;
tail=p;
count++;
}
return head;
};
//输出链表
void show(struct node*p)
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
//合并两个链表
struct node* he(struct node*head1,struct node*head2)
{
struct node*p1,*p2,*tail,*head3;
p1=head1->next;
p2=head2->next;
//创建新的头指针,来建立新的链表
head3=(struct node*)malloc(sizeof(struct node));
head3->next=NULL;
tail=head3;
while(p1&&p2)
{
if(p1->data<p2->data)//p1的值小,就先将p1的值放在新的链表中
{
tail->next=p1;
tail=p1;
p1=p1->next;
}
else//p2的值小,就将p2的值放在新的链表中
{
tail->next=p2;
tail=p2;
p2=p2->next;
}
//将剩余的值 放在新的链表后面
if(p1)
tail->next=p1;
else
tail->next=p2;
}
return head3;
};
int main()
{
struct node*head1,*head2,*head3;
//输入
head1=creat();
head2=creat();
//根据链表的的长度,输出
if(count)
{
head3=he(head1,head2);
show(head3->next);
}
else
printf("NULL\n");
return 0;
}
7-2 两个有序链表序列的交集
#include <stdio.h>
#include <stdlib.h>
//结构体
struct node
{
int data;
struct node*next;
};
int f=0;//置状态为0,来判断是否有交集
//创建链表
struct node*creat()
{
struct node*head,*tail,*p;
//创建头指针
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
//尾指针
tail=head;
//输入,创建链表
int x;
while(~scanf("%d",&x)&&x!=-1)
{
p=(struct node*)malloc(sizeof(struct node));
p->data=x;
tail->next=p;
tail=p;
}
return head;
};
//输出链表
void show(struct node*p)
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
//两个链表的交集
struct node*bing(struct node*head1,struct node*head2)
{
struct node*p1,*p2,*head3,*tail;
p1=head1->next;
p2=head2->next;
//创建新的链表,新的头指针
head3=(struct node*)malloc(sizeof(struct node));
head3->next=NULL;
tail=head3;
while(p1&&p2)
{
if(p1->data<p2->data)//p1的值小,p1指针后移
{
p1=p1->next;
}
else if(p1->data>p2->data)//p2的值小,p2指针后移
{
p2=p2->next;
}
else if(p1->data==p2->data)//直到p1=p2,将该值放到新的链表中,p1,p2一起后移
{
f=1;//状态置为1
tail->next=p1;//该值放在新的链表中
tail=p1;
//指针后移
p1=p1->next;
p2=p2->next;
}
}
return head3;
};
int main()
{
//输入
struct node*head1,*head2,*head3;
head1=creat();
head2=creat();
head3=bing(head1,head2);
//判断是否有交集
if(f==0)
printf("NULL");
else
show(head3->next);
return 0;
}
单向链表的一些基础操作
7-5 单链表的创建及遍历
#include <stdio.h>
#include <stdlib.h>
//结构体
struct node
{
int data;
struct node* next;
};
//创建链表
struct node* creat(int n)
{
struct node*head,*tail,*p;
//创建头指针
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
//尾指针
tail=head;
//读入n值,创建链表
int i;
for(i=0;i<n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
scanf("%d",&p->data);
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
};
//输出链表
void show(struct node*p)
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
int main()
{
//输出
int n;
scanf("%d",&n);
struct node*head;
//输入
head=creat(n);
show(head->next);
return 0;
}
7-7 单链表就地逆置
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
//结构体
typedef struct node
{
int data;
struct node*next;
}node;//将 struct node 命名为 node
//创建链表
node*creat()
{
node*head,*p;
//创建头指针
head=(node*)malloc(sizeof(node));
head->next=NULL;
//输入,创建链表
int x;
while(~scanf("%d",&x)&&x!=-1)
{
p=(node*)malloc(sizeof(node));
p->data=x;
p->next=NULL;
p->next=head->next;
head->next=p;
}
return head;
}
//输出链表
void show(node*p)
{
while(p)
{
if(p->next)
printf("%d ",p->data);
else
printf("%d\n",p->data);
p=p->next;
}
}
int main()
{
int t;
scanf("%d",&t);
//多组测试数据
while(t--)
{
node*head;
head=creat();
show(head->next);
}
return 0;
}
7-9 头插法创建单链表、遍历链表、删除链表
注意:对每组测试数据,创建链表,遍历链表输出之后,一定要删除链表,否则会出现“内存超限”。
所以在这里,参考代码,我使用数组简单些
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int main()
{
//输出测试数据
int t;
scanf("%d",&t);
while(t--)
{
int a[1000005];//数组存储
int i=0;//表示数组长度
int x;//表示输入数据
//数组存储 输入数据
while(~scanf("%d",&x)&&x!=-1)
{
a[i]=x;
i++;
}
//逆向输出
int j;
for(j=i-1;j>=0;j--)
{
if(j==0)
printf("%d \n",a[j]);
else
printf("%d ",a[j]);
}
}
return 0;
}
循环链表和双向链表的操作
7-4 约瑟夫环
#include <stdio.h>
#include <stdlib.h>
//结构体
struct node
{
int data;
struct node*next;
};
//创建链表
struct node*creat(int n)
{
struct node*head,*tail,*p;
//输入第一个数
p=(struct node*)malloc(sizeof(struct node));
p->data=1;
//头尾指针
head=tail=p;
//输入其他的数,创建链表
int i;
for(i=2;i<=n;i++)
{
p=(struct node*)malloc(sizeof(struct node));
p->data=i;
tail->next=p;
tail=p;
}
//创建 循环链表
tail->next=head;
return head;
};
//输出链表
void show(struct node*p)
{
while(p)
{
if(p->next==NULL)
printf("%d\n",p->data);
else
printf("%d ",p->data);
p=p->next;
}
}
int main()
{
//输入
int n,m;
scanf("%d %d",&n,&m);
struct node*head,*p,*q;
head=creat(n);
//从头指针开始,
q=head;
while(q->next!=head)
q=q->next;
int a=0;//a为计数器
//从头指针开始,报数
while(q->next!=q)
{
p=q->next;
a++;
if(a==m)//报数到m
{
printf("%d ",p->data);//输出序号
q->next=p->next;//将p删除释放
free(p);
a=0;//计数器归零
}
else//指针后移
q=p;
}
//输出最后的序号
printf("%d",q->data);
return 0;
}
7-8 带头节点的双向循环链表操作
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
//结构体
typedef struct node
{
int data;
struct node*next;
struct node*front;
}node;
int main()
{
node*head,*p,*q,*h;
//头指针创建
head=(node*)malloc(sizeof(node));
head->next=NULL;//头节点的后继
head->front=NULL;//头节点的前驱
head->data=1;//输入第一个值
q=head;
h=head;
//输入其他的值,创建链表
int x;
int count=1;
while(~scanf("%d",&x)&&x!=-1)
{
count++;
p=(node*)malloc(sizeof(node));
p->data=x;
p->next=NULL;
p->front=NULL;
if(count%2!=0)//是奇数个,前移
{
q->front=p;//头结点前驱 指向 p
p->next=q;//p的后继 指向 头节点
q=p;//头指针前移
}
else//是偶数个,后移
{
h->next=p;//头结点后继 指向 p
p->front=h;//p的前驱 指向 头节点
h=h->next;//头指针后移
}
}
//输出
while(h)
{
if(h!=head)//h,前移
{
if(h->front)
printf("%d ",h->data);
else
printf("%d\n",h->data);
h=h->front;
}
else
h=h->front;
}
while(q)
{
if(q!=head)//q,后移
{
if(q->next)
printf("%d ",q->data);
else
printf("%d\n",q->data);
q=q->next;
}
else
q=q->next;
}
return 0;
}