浙江大学MOOC数据结构-陈越、何钦铭 编程练习题(第二讲)
编程说明
编程环境:平台运行
编程语言:C
第一题代码
//链表:每一个节点对应一个结构体
List Merge( List L1, List L2 )
{
List p1,p2,p,L;
p1=L1->Next;//L1指向头节点,头节点的L1->next对应首元节点。故p1指向L1链表首元节点
p2=L2->Next;//L2指向头节点,头节点的L2->next对应首元节点。故p2指向L2链表首元节点
L=(List)malloc(sizeof(List));//创建L链表,默认指向头节点
L->Data=L1->Data+L2->Data;//L链表头节点的数据=L1链表头节点的数据+L2链表头节点的数据
p=L;//p指向L链表的头节点
while(p1!=NULL&&p2!=NULL)
{
if(p1->Data < p2->Data)
{
p->Next=p1;
p=p->Next;
p1=p1->Next;
}
else
{
p->Next=p2;
p=p->Next;
p2=p2->Next;
}
}
if(p1==NULL)
p->Next=p2;
else if(p2==NULL)
p->Next=p1;
L1->Next=NULL;
L2->Next=NULL;
return L;
}
第二题程序代码
#include <stdio.h>
#include <stdlib.h>
typedef struct PolyNode *Polynomial;
struct PolyNode {
int coef;
int expon;
Polynomial link;
};
Polynomial ReadPoly();
void Attach(int,int,Polynomial*);
Polynomial Mult(Polynomial,Polynomial);
Polynomial Add(Polynomial,Polynomial);
void PrintPoly(Polynomial);
int main()
{
Polynomial P1, P2, PP, PS;
P1 = ReadPoly();
P2 = ReadPoly();
PP = Mult( P1, P2 );
PrintPoly( PP );
PS = Add( P1, P2 );
PrintPoly( PS );
return 0;
}
Polynomial ReadPoly()
{
Polynomial Rear,P,t;
int c,e,N;
scanf("%d",&N);
//Rear是存放数据的链表节点(头到末),P是链表的头节点后经修改为首元节点,t便于释放头节点
P = (Polynomial)malloc(sizeof(struct PolyNode));//链表头空节点
P->link=NULL;
Rear=P;
for(int i=0;i<N;i++)
{
scanf("%d %d",&c,&e);
Attach(c,e,&Rear);
}
t=P;//t临时指针指向头节点P
P=P->link;//P后移指向首元节点
free(t);//释放头节点
return P;
}
void Attach(int c,int e,Polynomial *pRear)
{
Polynomial P;
P = (Polynomial)malloc(sizeof(struct PolyNode));//链表存放数据都需要新开辟空间
P->coef=c;
P->expon=e;
P->link=NULL;
(*pRear)->link=P;//把新空间链接到原链表后面
*pRear=P;//把链表的指针移动到新开辟的空间
}
Polynomial Mult(Polynomial P1,Polynomial P2 )
{
Polynomial P,Rear,t1,t2,t;
int c,e;
if(!P1||!P2)
return NULL;
t1=P1;
t2=P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));//链表存放数据都需要新开辟空间
P->link=NULL;
Rear=P;
//多项式1第一项乘以多项式2的每一项
while(t2)
{
Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
t2=t2->link;
}
//多项式1的每一项(无第一项)乘以多项式2的每一项
t1=t1->link;
while(t1)
{
t2=P2;//多项式2从头开始
Rear=P;//每一次需要从mult链表头节点开始,为了指数降序排列
while(t2)
{
c=t1->coef*t2->coef;
e=t1->expon+t2->expon;
while(Rear->link&&Rear->link->expon>e)//mutl链表下一节点项非空,且计算得到的新项指数比前面的项指数都低,则需要一直往后排,mult链表指针后移
Rear=Rear->link;
if(Rear->link&&Rear->link->expon==e)//计算项与链表下一项指数相同
{
if(c+Rear->link->coef)//系数非0,只改系数
{
Rear->link->coef+=c;
}
else//系数0则需要释放节点
{
t=Rear->link;
Rear->link=t->link;
free(t);
}
}
else//计算项指数最大,需要新建节点插入
{
t = (Polynomial)malloc(sizeof(struct PolyNode));
t->coef=c;
t->expon=e;
t->link=Rear->link;
Rear->link=t;
Rear=Rear->link;
}
t2=t2->link;
}
t1=t1->link;
}
//t2用于删除头节点
t2=P;
P=P->link;
free(t2);
return P;
}
//为什么不直接链表P链接,因为有加和乘两操作,不可以改变原始数据
Polynomial Add(Polynomial P1,Polynomial P2 )
{
Polynomial Rear,front,temp;
Rear = (Polynomial)malloc(sizeof(struct PolyNode));//链表存放数据都需要新开辟空间,Rear用于链表数据存放
front=Rear;//front用于记录链表起始地址,便于后面返回链表首地址
while(P1!=NULL && P2!=NULL)
{
if(P1->expon>P2->expon)
{
Attach(P1->coef,P1->expon,&Rear);
P1=P1->link;
}
else if(P1->expon<P2->expon)
{
Attach(P2->coef,P2->expon,&Rear);
P2=P2->link;
}
else
{
if((P1->coef+P2->coef)!=0)//系数不等于0,此项才添加到新链表
{
Attach(P1->coef+P2->coef,P1->expon,&Rear);
}
P1=P1->link;
P2=P2->link;
}
}
for(;P1;P1=P1->link)
{
Attach(P1->coef,P1->expon,&Rear);
}
for(;P2;P2=P2->link)
{
Attach(P2->coef,P2->expon,&Rear);
}
Rear->link=NULL;
//temp用于删去头节点
temp=front;
front=front->link;
free(temp);
return front;
}
//打印的时候,第一次只打印数据,之后:空格+数据
void PrintPoly(Polynomial P)
{
int flag=0;
if(!P)
{
printf("0 0\n");
return ;
}
while(P)
{
if(!flag)
flag=1;
else
printf(" ");
printf("%d %d",P->coef,P->expon);
P=P->link;
}
printf("\n");
}
第三题代码
https://blog.youkuaiyun.com/liuchuo/article/details/51985857?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-13&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-13
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int first, k, n, sum = 0;
cin >> first >> n >> k;
int temp, data[100005], next[100005], list[100005], result[100005];
for (int i = 0; i < n; i++) {
cin >> temp;
cin >> data[temp] >> next[temp];
}
while (first != -1) {
list[sum++] = first;
first = next[first];
}
for (int i = 0; i < sum; i++)
result[i] = list[i];
//i决定了几个需要逆向翻转。k-1-i%k是一个小阶段逆向组的下标位置。i/k*k是前面的组数*一组元素数
for (int i = 0; i < (sum - sum % k); i++)
result[i] = list[i / k * k + k - 1 - i % k];
for (int i = 0; i < sum - 1; i++)
printf("%05d %d %05d\n", result[i], data[result[i]], result[i + 1]);
printf("%05d %d -1", result[sum - 1], data[result[sum - 1]]);
return 0;
}
第四题代码
这里是引用https://blog.youkuaiyun.com/weixin_44720323/article/details/102502803
#include <stdio.h>
#include <stdlib.h>
//堆栈定义
typedef int ElementType;
typedef struct SNode *Stack;
struct SNode{
ElementType Data;
Stack Next;
};
//函数声明
Stack CreateStack();
int IsEmpty(Stack S);
void Push( ElementType item, Stack S);
ElementType Pop(Stack S);
int GetTop(Stack p);
int **ReadData(int m,int n,int k);
int main()
{
int m,n,k;
int **ptr;
scanf("%d%d%d",&m,&n,&k);
ptr = ReadData(m,n,k);
for(int i=0;i<k;i++)
{ //真正的模拟了栈
//i的数值每一次代表预先输入数组的一行。
Stack p = CreateStack();
int count = 0; //记录栈的容量
int current = 0; //记录要检测数组下标
for(int j=1;j<=n;j++)
{
Push(j,p);
count++;
if(count > m)
break;
while(!IsEmpty(p) && GetTop(p) == ptr[i][current])// p非空 && 栈顶元素等于预先输入数组
{
Pop(p);
count--;
current++;
}
}
while(!IsEmpty(p))
Pop(p);
if(current == n)
printf("YES\n");
else
printf("NO\n");
}
for(int j=0;j<k;j++)
{ //为每一行分配地址
free(*(ptr+j));
}
system("pause");
return 0;
}
//头节点S,S->Next指向栈顶
Stack CreateStack()
{ /* 构建一个堆栈的头结点,返回指针 */
Stack S;
S =(Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
int IsEmpty(Stack S)
{ /*判断堆栈S是否为空, 若为空函数返回整数1, 否则返回0 */
return ( S->Next == NULL );
}
void Push( ElementType item, Stack S)
{ /* 将元素item压入堆栈S */
Stack TmpCell;
TmpCell=(Stack)malloc(sizeof(struct SNode));
TmpCell->Data = item;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}
ElementType Pop(Stack S)
{ /* 删除并返回堆栈S的栈顶元素 */
Stack FirstCell;
ElementType TopElem;
if( IsEmpty( S ) ) {
printf("堆栈空");
return NULL;
}
else {
FirstCell = S->Next;
S->Next = FirstCell->Next;
TopElem = FirstCell ->Data;
free(FirstCell);
return TopElem;
}
}
int GetTop(Stack p)
{
return p->Next->Data;
}
int **ReadData(int m,int n,int k) //读取数据
{
int num;
int **arr;
arr = (int**)malloc(sizeof(int*)*(k));
for(int j=0;j<k;j++){ //为每一行分配地址
arr[j] = (int*)malloc(sizeof(int)*n);
}
for(int i=0;i<k;i++){
for(int j=0;j<n;j++){
scanf("%d",&num);
arr[i][j] = num;
}
}
return arr;
}