2021.12.12周总结

专业课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;
}

Guess you like

Origin blog.csdn.net/qq_62537709/article/details/121893447