数据结构PTA实验二循环,函数与递归

【6-1递增的整数序列链表的插入】

递增的整数序列链表(带头结点)中插入一个新整数,并保持该序列的有序性

函数接口定义:

List Insert( List L, ElementType X );

其中List结构定义如下:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

L是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Insert要将X插入L,并保持该序列的有序性,返回插入后的链表头指针

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表 */

List Insert( List L, ElementType X );

int main()
{
    List L;
    ElementType X;
    L = Read();
    scanf("%d", &X);
    L = Insert(L, X);
    Print(L);
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

5
1 2 4 5 6
3

输出样例:

1 2 3 4 5 6 

C

List Insert(List L,ElementType x){//函数接口定义
    List p,l;
    l=L;
    p=(List)malloc(sizeof(struct Node));//创建一个结点
    p->Data=x;
    p->Next=NULL;
    if(L->Next==NULL)//判断空表的情况
    {
        L->Next=p;
        return L;
    }
    while(L->Next&&L->Next->Data<x)//找到要插入的位置
    {
        L=L->Next;
    }
    p->Next=L->Next;//插进去这个结点
    L->Next=p;
    return l;
}

【6-2两个有序链表序列的合并】

将两个链表表示的递增整数序列合并为一个非递减的整数序列

函数接口定义:

List Merge( List L1, List L2 );

其中List结构定义如下:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

L1L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表;空链表将输出NULL */

List Merge( List L1, List L2 );

int main()
{
    List L1, L2, L;
    L1 = Read();
    L2 = Read();
    L = Merge(L1, L2);
    Print(L);
    Print(L1);
    Print(L2);
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

3
1 3 5
5
2 4 6 8 10

输出样例:

1 2 3 4 5 6 8 10 
NULL
NULL

C

List Merge(List L1,List L2)
{
	List head=(List)malloc(sizeof(List));
    List p=head;
    List a=L1->Next;
    List b=L2->Next;
    while(a&&b)//即当a!=NULL且b!=NULL时
    {
    	if(a->Data > b->Data)
        {
        	p->Next=b;
            b=b->Next;
        }
        else
        {
        	p->Next=a;
            a=a->Next;
        }//大的在前
        p=p->Next;
    }
    p->Next=a?a:b;//判断a是否为空。若不为空,则为a;否则为b
    L1->Next=NULL;
    L2->Next=NULL;
    return head;
}

【7-1汉诺塔的非递归实现】

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入格式:

输入为一个正整数N,即起始柱上的盘数

输出格式:

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

输入样例:

3

输出样例:

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c

C

{
	int n;
	scanf("%d",&n);
	
	pro a[3*n],b;//结构体栈 
	int p = -1;//栈顶指针
	Push(a,n,'a','b','c',&p);
	while(p > -1){//栈为空结束循环 
		if(a[p].n1 == 1){//当操作圆盘数为1 
			if(!p)	
				printf("%c -> %c",a[p].begin,a[p].end);
			else
				printf("%c -> %c\n",a[p].begin,a[p].end);
			p--;
		}else{
			Pop(a,&b,&p);
			Push(a,b.n1-1,b.mid,b.begin,b.end,&p);
			Push(a,1,b.begin,b.mid,b.end,&p);
			Push(a,b.n1-1,b.begin,b.end,b.mid,&p);
		}
	}
}

【7-2数组循环左移】

实现一个对数组进行循环左移的简单函数:一个数组a中存有n(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移m(≥0)个位置,即将a中的数据由(a0​a1​⋯an−1​)变换为(am​⋯an−1​a0​a1​⋯am−1​)(最前面的m个数循环移至最后面的m个位置)。如果还需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:

输入第1行给出正整数n(≤100)和整数m(≥0);第2行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出循环左移m位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

输入样例:

8 3
1 2 3 4 5 6 7 8

输出样例:

4 5 6 7 8 1 2 3

C

#include<stdio.h> 

int main()
{
	int m,n;
	int arr[100];
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&arr[i]);
	}
	for(int i=0;i<m;i++)
	{
		int temp = arr[0];
		for(int j=1;j<n;j++)
		{
			arr[j-1] = arr[j];
		}
		arr[n-1] = temp;
	}
	for(int i=0;i<n;i++)
	{
		if(i == n-1)
		{
			printf("%d",arr[i]);
		}
		else
		{
			printf("%d ",arr[i]);
		}
	}
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值