目录
实验1 顺序表的基本操作
一、实验目的
熟练应用顺序表存储结构,实现顺序线性表上的初始化、查找、插入、删除等基本操作。
二、实验软硬件要求
硬件:一台安装了windows操作系统的计算机。
软件:C语言编程工具
三、实验内容(需写出源程序,行距16磅)
用顺序表存储结构,求解以下问题:
- 将两个多项式polyA和polyB相加,将多项式的和存放在多项式polyC中。
- #include <stdio.h>
-
#include <stdlib.h>
//定义节点结构体 typedef struct polynomial { int coe;//系数 int index;//指数 struct polynomial*next;//指向写一个节点的指针 }pol; //创建头节点 pol*create() { pol*head=NULL; head=(pol*)malloc(sizeof(pol)); head->next=NULL; return head; } //按大小插入节点 void insert(pol*head,int coe_insert,int index_insert) { pol*t=(pol*)malloc(sizeof(pol)); pol*n=head->next,*m=head; //插入第一个节点的操作 if(head->next==NULL) { head->next=t; t->next=NULL; t->coe=coe_insert; t->index=index_insert; } //插入其余节点的操作 else while(1) { //当插入节点的指数比当前指针指向的节点的指数小或者已无后续节点时 if(n->next==NULL&&n->index>index_insert) { n->next=t; t->next=NULL; t->coe=coe_insert; t->index=index_insert; break; } if(n->index<index_insert) { m->next=t; t->next=n; t->coe=coe_insert; t->index=index_insert; break; } //当插入节点的指数和当前指针指向的节点的指数相等(虽然题目中没有提示这种情况,但是以防万一) if(n->index==index_insert) { n->coe=n->coe+coe_insert; break; } //当插入节点的指数比当前指针指向的节点的指数大,则指针继续后延 else { m=n; n=n->next; } } } //将2个链表比较,按照要求进行整合,我选择直接整合到第一个链表中 void compare(pol*headA,pol*headB) { pol*n=headA,*x,*m=headB->next; //具体比较和插入的逻辑大家可以看一下 while(1) { x=m; if(m==NULL) break; else if(n->index==m->index) { n->coe=n->coe+m->coe; m=m->next; continue; } else if(n->next->index<m->index||n->next==NULL) { m=m->next; x->next=n->next; n->next=x; continue; } else n=n->next; } } //输出第一个链表,当系数为0时,自动跳过 void output(pol*head) { pol*y=head->next; while(1) { if(y ->coe == 0) y = y ->next; if(y==NULL) break; printf("[ %d %d ] ",y->coe,y->index); y=y->next; } printf("\n"); } int main() { int num; scanf("%d",&num); for(int i=0;i<num;i++) { pol*headA=NULL; pol*headB=NULL; headA=create(); headB=create(); while(1) { int a,b; scanf("%d%d",&a,&b); if(b<0) break; insert(headA,a,b); } while(1) { int a,b; scanf("%d%d",&a,&b); if(b<0) break; insert(headB,a,b); } compare(headA,headB); output(headA); } return 0; }
2、求解约瑟夫环问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为 1 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。
- 输入玩游戏人数n和计数m
- 输出依次出圈的玩家编号和胜利者编号
求解约瑟夫环问题:
#include<stdlib.h>
#include<stdio.h>
int main ()
{int n,q,i=0,count=1,flag=0;
printf("请输入人数:\n");
scanf("%d",&n);
printf("报到第几个数要淘汰:\n");
scanf("%d",&q);
int a[n];
for (i=0;i<n;i++)
{a[i]=0;//给每个人设置生的状态
}
i=0;
printf("输出被淘汰的人顺序:\n");
while(1)
{ if (flag==n-1)break;
if(a[i]==1)i++;
else{if (count==q)
{a[i]=1;//设置淘汰状态
flag++;//淘汰人数加一
printf("%d ",i);
count=1;//重置报数
i++;
}
else
{
count++;
i++;
}
}
if(i==n)i=0;//数组下标从0开始
}
printf("\n胜利者 :");
for(i=0;;i++)
{if(a[i]!=1)
{printf("%d",i);
break;
}
}
return 0;
}
-
实验结果(写出运行程序后的结果截图)
- 两个多项式相加
-
2、求解约瑟夫环问题
实验2 单链表的基本操作
一、实验目的
熟练应用链表存储结构,实现顺序单链表,顺序双向链表上的初始化、查找、插入、删除等基本操作。
二、实验软硬件要求
硬件:一台安装了windows操作系统的计算机。
软件:C语言编程工具
-
实验内容(需写出源程序)
用链表存储结构,求解以下问题:
1、将两个多项式polyA和polyB相乘,将多项式的乘积存放在多项式polyC中。
2、求解约瑟夫环问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。
- 输入玩游戏人数n、起始编号k和计数m
- 输出依次出圈的玩家编号和胜利者编号
#include<stdio.h>
#include<stdlib.h>
//定义结构体数组,前面存放系数,后面存放指数//
typedef struct Node
{float ratio;
int index;
struct Node*next;
}*PNode,*LinkList;
LinkList Create_Link()
{ LinkList head;
PNode p,q;
float ratio;//系数
int index;//指数
head=(struct Node*)malloc(sizeof(struct Node));
head->next=NULL;
q=head;
scanf("%f %d",&ratio,&index);
while(ratio!=0||index!=0)
{p=(struct Node*)malloc(sizeof(struct Node));
p->next=NULL;
q->next=p;
q=p;
p->index=index;
p->ratio=ratio;
scanf("%f %d ",&ratio,&index);
}
return head;
}
//将数据按从小到大排列方便相加
void Sort_Link(LinkList head)
{PNode p,q;
float temp1;
int temp2;
for(p=head->next;p!=NULL;p=p->next)
for(q=p->next;q!=NULL;q=q->next)
{if(q->index>q->index)
{temp1=q->ratio;
q->ratio=p->ratio;
p->ratio=temp1;
temp2=q->index;
q->index-p->index;
p->index=temp2;
}
}
}
//两个多项式相加:将两个多项式的每一个结点的数进行比较
void Add_List(LinkList llist1,LinkList llist2)
{ PNode p,q,pre,temp;
p=llist1->next;
q=llist2->next;
pre=llist1;
while(p&&q)
{//如果B中项的指数小于A,进行前插
if(q->index<p->index)
{ temp=q->next;
q->next=p;
pre->next=q;
pre=q;
q=temp;
}
//如果B中项的指数数大于A,A中指针后移
else
if(q->index>p->index)
{pre=p;
p=p->next;
}
//指数相等,系数相加
else
{if(q->ratio+p->ratio==0)
{pre->next=p->next;
free(p);
}
else
{p->ratio=p->ratio+q->ratio;
pre=p;}
p=pre->next;
temp=q;
q=q->next;
free(temp);
}
}//移动B中指针到下一节点
if(q)
{pre->next=q;
}
free (llist2);
}
//进行链表输出
void print(LinkList head)
{ PNode p;
for(p=head->next;p!=NULL;p=p->next)
{printf("%.0fX%d ",p->ratio,p->index);
}
}
//主函数
int main()
{ LinkList llist1=Create_Link();
LinkList llist2=Create_Link();
Sort_Link(llist1);
Sort_Link(llist2);
Add_List(llist1,llist2);
print(llist1);
}
2.求解约瑟夫环问题
#include<stdio.h>
#include<stdlib.h>
typedef struct link
{
int id;
struct link*next;
}Link;
Link* Creat(int n)//创建循环链表并返回链表尾结点
{
Link *head=NULL,*p=NULL,*pr=NULL;
int i;
for(i=1;i<=n;i++)//从1开始创建n个链表节点,并依次赋值i
{
p =(Link*)malloc(sizeof(Link));
if(p==NULL)
{
printf("ERROR");
return NULL;
}
p->id=i;
if(head==NULL)
{
head=p;
}
else
{
pr->next=p;
}
pr=p;
}
pr->next=head;
return pr;
}
void YueSeFu(Link*tail,int n,int m,int *a)//用于确定出圈顺序
{
int count=0,flag=0;//报数值与死亡人数值
Link*p=tail->next,*q=tail;
while(flag<n-1)
{
count++;//报数
if(count==m)
{
*a=p->id;
a++;
q->next=p->next;
free(p);
p=q->next;//p移动到下一个人
count=0;
flag++;
}
else// 移动到下一个人
{
q=p;p=p->next;
}
}
*a=p->id;
free(p);
}
int main(void)
{
int n,m;
scanf("%d %d",&n,&m);//总人数与出圈人数
int a[n];
Link*tail=NULL;
tail=Creat(n);
YueSeFu(tail,n,m,a);
for(int i=0;i<n;i++)
{
printf("%d ",a[i]);
}
}
四、实验结果(写出运行程序后的结果截图)
2.求解约瑟夫环问题
实验3 栈的基本操作
一、实验目的
熟练应用顺序表和单链表存储结构,实现栈的初始化、入栈、出栈等基本操作。
二、实验软硬件要求
硬件:一台安装了windows操作系统的计算机。
软件:C语言编程工具
-
实验内容(需写出源程序)
- 利用栈的基本操作实现将一个键盘输入的十进制整数转换为对应的八进制数。
进制转换,代码如下,先构写基本的栈操作代码,出栈,入栈,建立栈,再构写进制转换程序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define OK 1
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
typedef int SElemType;
#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
//顺序栈
struct SqStack
{
SElemType *base;
SElemType *top;
int stacksize;
};
//构造一个空栈S
Status InitStack(SqStack &S)
{
S.base = (int*)malloc(STACK_INIT_SIZE*sizeof(int));
if (!S.base)
exit(OVERFLOW);
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
//检查s栈是否为空栈
Boolean StackEmpty(SqStack S)
{
if (S.top == S.base)
return TRUE;
else
return FALSE;
}
//插入元素e为新的栈顶元素
Status Push(SqStack &S,int e)
{
if (S.top-S.base >= S.stacksize) //栈满,追加存储空间
{
S.base = (SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));
if (!S.base)
exit (OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACK_INCREMENT;
}
*(S.top)++=e;
return OK;
}
//若栈不为空,删除S的栈顶元素,用e返回其值
Status Pop(SqStack &S,int &e)
{
if (S.top == S.base)
return ERROR;
e = *--S.top;
return OK;
}
// 对于输入的非负十进制整数,打印输出与其等值的八进制数
void conversion(SqStack S)
{
int N,e;
InitStack(S);
printf("请输入一个十进制整数:");
scanf("%d",&N);
while(N){
Push(S,N%8);
N=N/8;
}
printf("转为八进制:");
while(!StackEmpty(S)){
Pop(S,e);
printf("%d",e);
}
printf("\n");
}
int main()
{
SqStack S;
conversion(S);
}}}
2、利用栈的“后进先出”思想,编写一个具有行编辑功能的程序,前一个字符输入有误时,输入’#’消除。当输入的一行有误时,输入’@’消除当前行的字符序列。
例如:当用户输入whike##le (s1#!=0)时,对应的有效输入为while(s!=0)
同样,先构写基本的建立栈,入栈,出栈等操作代码,再构写行编辑程序
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10 //储存空间分配增量
#define OK 1
#define error 0
typedef char SElemType;
typedef int Status;
using namespace std;
typedef struct SqStack{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
Status InitStack(SqStack &s){
s.base=(SElemType *)malloc(STACK_INIT_SIZE *sizeof(SElemType));
if(!s.base) return error;
s.top=s.base;
s.stacksize=STACK_INIT_SIZE ;
return OK;
}
Status Push(SqStack &s,SElemType &e){
if(s.top-s.base>=s.stacksize){
s.base=(SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));//重新申请内存
if(!s.base) return error;
s.top=s.base+s.stacksize;
s.stacksize+= STACKINCREMENT ;
}
*s.top++ =e;
return OK;
}
Status Pop(SqStack &s,SElemType &e){
if(s.top == s.base) return error;
e = *--s.top;
return OK;
}
Status ClearStack(SqStack s){
s.top=s.base;
return OK;
}
Status DestoryStack(SqStack s){
s.top=s.base;
free(s.base);
s.top=NULL;
s.base=NULL;
return OK;
}
void LineEdit(SqStack s){
InitStack(s);
char c,ch,*p;
ch=getchar();
while (ch!= EOF){
while (ch!= EOF && ch!='\n'){
switch (ch){
case '#':Pop(s,c); break;
case '@':ClearStack(s); break;
default:Push(s,ch); break;
}
ch = getchar();
}
p = s.base;
while(p!=s.top){
cout<<*p;
++p;
}
ClearStack(s);
if(ch!= EOF) ch=getchar();
}
}
int main(){
SqStack s;
InitStack(s);
cout<<"请输入字符串:";
LineEdit(s);
DestoryStack(s);
return 0;
}
四、实验结果(写出运行程序后的结果截图)
1.用栈实现数制转换
2.行编辑功能
实验4 队列的基本操作
一、实验目的
熟练应用顺序表和单链表存储结构,实现队列的初始化、入队、出队等基本操作。
二、实验软硬件要求
硬件:一台安装了windows操作系统的计算机。
软件:C语言编程工具
-
实验内容(需写出源程序)
【问题描述】
对顺序循环队列,将自然数按序入队、出队。具体的操作是:队列未满时,入队、入队、出队(即做连续两次入队操作之后,做一次出队操作),输出出队元素的值;队列满时,执行连续的出队操作,输出出队元素的值(应与队列未满时所输出的有不同标识),直至队列为空。编写程序实现以上操作。
【测试情况】
假设顺序循环队列使用的数组大小为20
运行程序得到的实际输出如下:
1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19#20#21#22#23#24#25#26#27#28#29#30#31#32#33#34#35#36#37#
#include"iostream"
#include"string"
using namespace std;
typedef int element;
class Queue{
private:
element *arr;
int front;
int maxsize;
int tail;
public:
Queue(int size){
maxsize = size;
arr = new element[size];
front = 0;
tail = 0;
}
bool empty(){
return tail == front;
}
bool full(){
return (tail + 1) % maxsize == front;
}
bool push(element data){
if(full()){
cout<<"out"<<endl;
return false;
}
arr[tail] = data;
tail = (tail + 1) % maxsize;
return true;
}
int length(){
return (tail - front + maxsize) % maxsize;
}
element pop(){
if(empty()){
return false;
}
int temp = front;
front = (front + 1) % maxsize;
return arr[temp];
}
element getFront(){
if(empty()){
return arr[-1];
}
return arr[front];
}
};
int main(){
element data;
int n;
string s;
cin>>n;
Queue myq(n);
cin>>n;
while(n--){
cin>>s;
if(s=="in"){
cin>>data;
myq.push(data);
}
else{
myq.pop();
}
}
while(!myq.empty()){
cout<<myq.pop()<<ends;
}
cout<<endl;
return 0;}}
四、实验结果(写出运行程序后的结果截图)
资料仅供学习使用
编者能力有限,如有错误欢迎留言交流
编者的其他专栏:
关注编者了解更多