#include <stdio.h>
#include <malloc.h>
//定义节点结构体
typedef int elemtype;
typedef struct node
{
elemtype data;
struct node *next;
}JD;
//建立单链表函数
JD *creat() /*表位插入法,建立单链表*/
{
JD *h,*p,*t;
int i,n;
h=(JD *)malloc(sizeof(JD));
h->next=NULL;
h->data=NULL;
t=h;
printf("输入数字的个数(n):");
scanf("%d",&n);
printf("请输入%d个整型数据",n);
for(i=n;i>0;i--)
{
p=(JD *)malloc(sizeof(JD));
scanf("%d",&p->data);
p->next=NULL;
t->next=p;
t=p;
}
return (h);
}
//排序
void Array(JD *head)
{
JD *p,*q,*small;
int temp;
for(p=head->next;p->next!=NULL;p=p->next)
{
small=p;//标识small为当前P
for(q=p->next;q;q=q->next)//让q为当前p的下一个,然后依次和small比较,如果比small小,则small=q;
if(q->data<small->data)
small=q;
if(small!=p) //比较完发现不是当前的p,说明后边有比P更小的,则两个数据交换
{
temp=p->data;
p->data=small->data;
small->data=temp;
}
}
}
//结果输出
void output(JD *h)
{
JD *p;
p=h->next;
while(p!=NULL)
{
printf("%2d",p->data);//输出两个字符的长度
p=p->next;
}
printf("\n");
}
JD *link(JD *pa,JD *pb)
{
JD *p,*q,*pc;
pa=pa->next; //头结点没东西的
pb=pb->next;
pc=(JD*)malloc(sizeof(JD));/*建立表c的头结点pc*/
p=pc; /*p指向C表头节点*/
while(pa!=NULL&&pb!=NULL)
{
q=(JD*)malloc(sizeof(JD)); /*建立新节点*/
if(pb->data<pa->data) /*比较A、B表中当前节点的数据大小*/
{
q->data=pb->data; /*B中节点小,将其值赋给q的数据域*/
pb=pb->next; /*B中的指针后移*/
}
else
{
q->data=pa->data; /*A中节点小,将其值赋给q的数据域*/
pa=pa->next; /*A中指针后移*/
}
p->next=q; /*将q接在p后面*/
p=q; /*P始终指向C表尾*/
}
while(pa!=NULL) /*A比B长,将A余下节点接上*/
{
q=(JD*)malloc(sizeof(JD));
q->data=pa->data;
pa=pa->next;
p->next=q;
p=q;
}
while(pb!=NULL) /*B比A长,将B余下节点接上*/
{
q=(JD*)malloc(sizeof(JD));
q->data=pb->data;
pb=pb->next;
p->next=q;
p=q;
}
p->next=NULL;
return (pc);
}
//主函数
void main()
{
JD *LA,*LB,*LC;
LA=creat();
LB=creat();
paixu(LA);
paixu(LB);
LC=link(LA,LB);
printf("LA:");
output(LA);
printf("LB:");
output(LB);
printf("LC:");
output(LC);
}
//2.生成两个多项式PA和PB,求PA和PB之和
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int coef;//系数
int exp;//指数
struct node *next;
}JD;//京东?
JD* creat(JD *P1,int m)
{
int i;
JD *s,*p;
s=(JD*)malloc(sizeof(JD));
if(!s)
{
printf("内存分配失败,程序结束!");
exit(1);
}
s->next=NULL;
P1=s;
for(i=1;i<=m;i++)
{
p=(JD*)malloc(sizeof(JD));
printf("请按照套路出牌,谢谢!按指数的升幂输入一元多项式的系数和指数:\n");
scanf("%d,%d",&p->coef,&p->exp);
printf("\n");
s->next=p;
s=p;
}
s->next=NULL;
return P1;
}
JD *Add(JD *ha,JD *hb)//相当于用ha作为一个接收器
{
JD*p,*q,*r,*pre;
int x;
p=ha->next;
q=hb->next;//头结点是没有东西的
pre=ha;//pre指向多项式A的头结点
while(p&&q)
{
if(p->exp==q->exp)//当两个节点的指数域相等时
{
x=p->coef+q->coef;//系数相加
if(x!=0)//和不为零时,修改p系数域
{
p->coef=x;pre=p;
}
else
{
pre->next=p->next;
free(p);
}//和为零,从A中删去p
p=pre->next;
r=q;
q=q->next;
free(r);
}
else if(p->exp>q->exp)//将q插在p之前,q后移,p不动
{
r=q->next;
q->next=p;//q插在p之前
pre->next=q;//
pre=q;
q=r;//后移了
}
else
{
pre=p;
p=p->next;
}
}
if(q)
pre->next=q;
free(hb);
return(ha);
}
void display(JD*head)
{
JD *p;//p是用来输出的
int i;//i是用来和指数比较
if(!head)
{
printf("大爷的是个空表");
}
p=head->next;
printf("p(x)=");
while(p&&(p->next))
{
printf("%d",p->coef);
for(i=1;i<p->exp;i++)
{
printf("x*");
}
printf("x");
printf("+");
p=p->next;
}
//留下最后一个输出
printf("%d",p->coef);
for(i=1;i<p->exp;i++)
printf("x*");
printf("x");
printf("\n");
}
void main()
{
JD *PA,*PB;//定义两个链表作为两个多项式放的容器
int m,n;
printf("输入你想输入多少项m和n中间请用,分开:");
scanf("%d,%d",&m,&n);
PA=creat(PA,m);
printf("\n下一个\n");
PB=creat(PB,n);
display(PA);
display(PB);
PA=Add(PA,PB);
display(PA);
}
//3.设计一个统计选票的算法,输出每个候选人的得票结果
//(假设采用单链表存放选票,候选人编号依次为1,2,3...N,且每张选票选且只选一人)
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[20];
int flag;
int count;
struct Person *next;
}Person,*pe;
Person *creat()//构造函数
{
printf("请输入候选人的人数:");
int num;
scanf("%d",&num);
Person *h,*p,*t;
h=(Person*)malloc(sizeof(Person));
h->next=NULL;
t=h;
char ch='Y';
while(num)
{
printf("让我们构造一个人出来吧");
p=(Person*)malloc(sizeof(Person));
printf("请输入候选人名字:");
scanf("%s",&p->name);
printf("请输入该候选人的标记数:");
scanf("%d",&p->flag);//构造到这一步
p->count=0;
p->next=NULL;
t->next=p;
t=p;//t指向最后一个元素
num--;
}
return h;
}
void Count(Person*h)//投票计数
{
Person*p;
int num,flag;//用num来代表投票人数
p=h->next;
printf("请输入参与投票的总人数\n");
scanf("%d",&num);
for(int i=1;i<=num;i++)
{
printf("请输入你投票人的标记数");
scanf("%d",&flag);
while(p)
{
if(p->flag==flag)
p->count++;
p=p->next;
}
p=h->next;
}
}
void OutPut(Person *h)
{
printf("本次投票的结果是----------\n");
Person *p;
p=h->next;
while(p)
{
printf("%s的票数为: ",p->name);
printf("%d",p->count);
printf("\n");
p=p->next;
}
}
void main()
{
printf("本人自己写的投票系统,不喜欢用别用,谢谢\n");
Person *pa;//用pa来作为候选人的容器
pa=creat();
Count(pa);
OutPut(pa);
}
//4.解决约瑟夫问题
#include<stdio.h>
#include<stdlib.h>
typedef struct list
{ //定义链表的节点结构
int number; //用于给乘客的位置编号
struct list*next;
}list;
list *creat(int n)//创建一个循环链表
{
list*head=NULL,*p,*q,*r;
for(int i=1;i<=n;i++)
{ /*根据人数n,建立带头结点head循环链表*/
p=(list*)malloc(sizeof(list));
p->number=i; //给每个人位置编号
if(head==NULL)
{
head=p;
}
else
{
q->next=p;
}
q=p;
}
p->next=head;
r=head;
return r;
}
void OutPut(list*r,int n,int m,int k)//输出出局的人
{
list*temp;
int a=0;//用a来表示叫的号
while(r!=NULL&&n!=k)
{
++a;
if((a+1)%m==0)/*找出需出局人的前一位乘客,将需出局的节点删除,并将与出局的相邻的两位节点连起来,保证认是一个循环链表 */
{
temp=r->next;
r->next=r->next->next;
printf("编号为%d位置的乘客需要出局\n",temp->number); //输出出局的位置编号
free(temp);
n--;
}
else r=r->next;
}
}
void main()
{
int n; //n表示人数,i用于for循环
list*r;
printf("请输入桌上的的人数n:\n");
scanf("%d",&n);
r=creat(n);//用r作为一个连接符
int m,k; //m表示乘客数到这个需要出局的数,k表示最终剩余的人数,a用于记录乘客总共报数的次数
printf("请输入数到需要出局的数m\n");
scanf("%d",&m);
printf("请输入最终剩余人数k\n");
scanf("%d",&k);
OutPut(r,n,m,k);
}
//5.设计一个算法,求A和B两个链表表示的集合的交集、并集、差集。
#include <stdio.h>
#include <stdlib.h>
typedef struct list
{
int num;
struct list *next;
}list;//生成一个节点先
list *creat()//创建一个纯数字的链表
{
list *h,*p,*t;
int i,n;
h=(list *)malloc(sizeof(list));
h->next=NULL;
h->num=NULL;
t=h;
printf("输入集合元素个数(n):");
scanf("%d",&n);
printf("请输入%d个整型数据\n",n);
for(i=n;i>0;i--)
{
p=(list*)malloc(sizeof(list));
scanf("%d",&p->num);
p->next=NULL;
t->next=p;
t=p;
}
return (h);
}
void insert(list*lp,int x)//将值为X的节点插在lp之后
{
list*s,*p;
p=lp;
s=(list*)malloc(sizeof(list));//生成一个新的节点
s->num=x;
p->next=s;
p=s;
p->next=NULL;
}
void Array(list *head) //排序
{
list *p,*q,*small;
int temp;
for(p=head->next;p->next!=NULL;p=p->next)
{
small=p;//标识small为当前P
for(q=p->next;q;q=q->next)//让q为当前p的下一个,然后依次和small比较,如果比small小,则small=q;
if(q->num<small->num)
small=q;
if(small!=p) //比较完发现不是当前的p,说明后边有比P更小的,则两个数据交换
{
temp=p->num;
p->num=small->num;
small->num=temp;
}
}
}
list *Intersection(list *head1,list *head2)//求两个集合的交集
{
list *p,*q,*head,*r,*s;
head=r=(list*)malloc(sizeof(list));
p=head1->next;
while(p)
{
q=head2->next;
while(q)
{
if(p->num==q->num)
{
s=(list*)malloc(sizeof(list));//尾插法
s->num=p->num;
r->next=s;
r=s;
break;
}
q=q->next;
}
p=p->next;
}
r->next=NULL;
return head;
}
list*Sub_2(list*head1,list*head2)//A-B
{
list *p,*q,*head,*r,*s;
int flag;//用来标记有没有相同的元素
head=r=(list*)malloc(sizeof(list));
p=head1->next;
while(p)
{
flag=0;
q=head2->next;
while(q)
{
if(p->num==q->num)
{
flag=1;
break;
}
q=q->next;
}
if(flag==0)
{
s=(list*)malloc(sizeof(list));
s->num=p->num;
r->next=s;
r=s;
}
p=p->next;
}
r->next=NULL;//其实有点像差集
return head;
}
list *Union(list *head1,list *head2)//求两个的并集
{
list *p,*q,*head,*r,*s;
int flag;//用来标记有没有相同的元素
head=r=(list*)malloc(sizeof(list));
p=head1->next;
while(p)
{
flag=0;
q=head2->next;
while(q)
{
if(p->num==q->num)
{
flag=1;
break;
}
q=q->next;
}
if(flag==0)
{
s=(list*)malloc(sizeof(list));
s->num=p->num;
r->next=s;
r=s;
}
p=p->next;
}
r->next=head2->next;//其实有点像差集
return head;
}
void output(list *h)
{
list *p;
p=h->next;
printf("集合为:");
while(p!=NULL)
{
printf("%2d",p->num);//输出两个字符的长度
p=p->next;
}
printf("\n");
}
void main()
{
list*pa,*pb,*Inse,*Add,*Sub;
pa=creat();
pb=creat();
Inse=Intersection(pa,pb);
Add=Union(pa,pb);
Sub=Sub_2(pa,pb);
printf("集合A:");
output(pa);
printf("集合B:");
output(pb);
printf("交集为:");
output(Inse);
printf("并集为:");
output(Add);
printf("差集为:");
output(Sub);
}