算法与数据结构上机练习2

这篇博客通过C语言实现多项式加法,利用链表数据结构创建多项式并进行加法运算。同时,还展示了如何创建一个简单的投票系统,统计候选人得票,以及解决约瑟夫问题。此外,还涉及了链表操作,包括求两个链表表示集合的交集、并集和差集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//设计一个程序,创建链表LA;LB,并用一个链表LC将两个链表链接起来,单调非递减.
#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);


}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值