专业课100题完成情况
理解链表的基本概念,学会头插法和尾插法
头插法(运用头插法时,最终头节点的下一个是输入的最后一个,即倒序输入)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//创建一个节点类型
typedef struct node {//typedef的意思是
int data;
struct node* next;//因为我下一个节点的类型是struct node类型,所以next是struct node*类型;
}Node;
Node* head, * p, * r;//头结点是用来找到这个链表的,不能动。
int n;
//创建链表
void create_Linklist() {
head = (Node*)malloc(sizeof(Node));//我要一个Node大小的内存。存的是Node*类型的东西
head->next = NULL;//初始化指针变量
for (int i = 0; i < n; i++) {
r = (Node*)malloc(sizeof(Node));//创建一个新节点,为其开辟内存空间
scanf("%d", &r->data);
r -> next = head -> next;//让新节点的next指向(原来接在头结点后面的结点)
head->next = r;//让新节点接在头结点后
}
}
int main()
{
scanf_s("%d", &n);
create_Linklist();
//头结点永远不要动
p = head->next;//把head下一个节点赋值给p,p代替头结点遍历整个链表
while (p != NULL) {
Node* q = NULL;
q = p;
printf("%d ", p->data);
p = p->next;//p变成了p的下一个
free(q);//释放原来p的内存空间
}
free(head);//最后释放头节点的内存空间
return 0;
}
尾插法(运用尾插法时,尾节点的上一个是最后输入的那个,即为正序输入)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//创建一个节点类型
typedef struct node {//typedef的意思是
int data;
struct node* next;//因为我下一个节点的类型是struct node类型,所以next是struct node*类型;
}Node;
Node* head, * p, * r;//头结点是用来找到这个链表的,不能动。
int n;
//创建链表
void create_Linklist() {
head = (Node*)malloc(sizeof(Node));//我要一个Node大小的内存。存的是Node*类型的东西
head->next = NULL;//初始化指针变量
p = head;//把head赋值给p,p代替头结点遍历整个链表
for (int i = 0; i < n; i++) {
r = (Node*)malloc(sizeof(Node));//来了一个新结点
r->next = NULL;//初始化
scanf("%d", &r->data);
p->next = r;
p = p->next;//移动p到下一个
}
}
int main()
{
scanf("%d", &n);
create_Linklist();
//头结点永远不要动
p = head->next;//头节点的数据域为空,须从头节点的下一个开始遍历
while (p != NULL) {
Node* q = NULL;
q = p;
printf("%d ", p->data);
p = p->next;//p变成了p->next
free(q);//释放内存空间
}
free(head);//释放内存空间
return 0;
}
学会递归函数的典例-汉诺塔问题
1.给定一个由n个圆盘组成的塔,这些圆盘按照大小递减的方式套在第一根桩柱上。现要将整个塔移动到另一根桩柱上,每次只能移动一个圆盘,且较大的圆盘在移动过程中不能放置在较小的圆盘上面。(a可以直接到c)
输入格式:
包含1组数据,输入一个n值(1<=n=35)。
输出格式:
输出移动步骤及序号,每行输出一步。
#include<stdio.h>
int q;
void hnt(int n,char a[],char b[],char c[])//无返回值,用void;
{
if(n==1)
printf("第%d步:%s->%s\n",++q,a,c);//当a柱只有一个圆盘时,只需把它移到c柱即可
else //运用递归思想,将问题分为1,和n-1个盘子;
{
hnt(n-1,a,c,b);
printf("第%d步:%s->%s\n",++q,a,c);
hnt(n-1,b,a,c);
}
}
int main()
{
int n;
char a[50],b[50],c[50];//三个柱子的名称
scanf("%d",&n);
scanf("%s",a);
scanf("%s",b);
scanf("%s",c);
hnt(n,a,b,c);
return 0;
}
2.现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。 Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?(a不能直接到c)
输入格式:
包含多组数据,每次输入一个N值(1<=N=35)。
输出格式:
对于每组数据,输出移动最小的次数。
#include<stdio.h>
int main()
{
int t,n,i;
long long a[36];
a[1]=2; //当只有一个盘子时,须移动2步;
for(i=2;i<36;i++)
a[i]=a[i-1]*3+2; //计算出1个盘子到35个盘子每种情况时的总步数
while(scanf("%d",&n)!=EOF)
{
printf("%lld\n",a[n]);
}
return 0;
}