PAT

2 篇文章 0 订阅

2018年底十二天狂练

Day one (data structure)

  • 绪论
  1. 什么是时间复杂度?
    消耗的时间 与 问题的规模(n) 之间的关系 f ( n ) = . . . . . . f(n)=...... f(n)=......
  2. 什么是空间复杂度?
    消耗的空间和问题的规模之间的关系
    消耗的空间分为内存和外存两部分,外存就是指硬盘
  • 线性表
  1. 线性表仅仅是一个逻辑上的概念,具体实现方式有两种:顺序表和链表
  2. 顺序表有三个元素就可以构成线性表:初始容量,扩充容量,有效数据个数
  • 栈和队列
  1. 栈和队列也都是逻辑概念
  2. 栈的实现有两种方式:顺序表,链表
  3. 顺序表有三个要素:首地址base,容量,栈顶top(为了根据base计算栈顶的元素位置)
  4. 栈的应用:十进制转二进制,括号对称合并,表达式求值(先中缀表达式转后缀表达式,再计算后缀表达式)
  5. 队列的实现也有两种方式:顺序表和链表
  6. 顺序表的实现需要三个要素:front,rear,queueSize
  7. 队列的有效元素个数为 ( r − f + n ) % n (r-f+n)\%n (rf+n)%n
  8. 判断队列满不满有两种方法: ( r − f + n ) % n = = n − 1 (r-f+n)\%n==n-1 (rf+n)%n==n1 ( r + 1 ) % n = = f (r+1)\%n==f (r+1)%n==f
  9. 这里要设计循环队列,否则的话会出现假溢出的情况,既然是循环队列,那也有一定限制,就是最后一个位置不能填满,为了区分队列为空还是队列为满。

Day two (data structure)

  1. 度分为两种:节点的度是孩子个数;树的度为最大的节点度
  2. 树分为有序树和无序树,所谓无序树就是兄弟节点之间的相对位置改变不会引起树的变化
  3. 树的集合称为森林
  4. 二叉树的性质:
    第i层, 2 i − 1 2^{i-1} 2i1个节点
    深度为k,最多节点数 2 k − 1 2^k-1 2k1
    在二叉树中有三种节点:度为0,度为1和度为2,个数分别为 n 0 n_0 n0 n 1 n_1 n1 n 2 n_2 n2,则有 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1,(按孩子的个数求总的节点个数, n 0 + n 1 + n 2 = 1 + 2 n 2 + n 1 n_0+n_1+n_2=1+2n_2+n_1 n0+n1+n2=1+2n2+n1)
  5. 满二叉树:k层, 2 k − 1 2^{k}-1 2k1个节点
  6. 完全二叉树:k-1层为满二叉树,第k层由左向右依次排布节点,不能有漏;高度:n个节点-> h e i g h t = ⌊ l o g 2 n ⌋ + 1 height=\lfloor log_2n\rfloor+1 height=log2n+1
  • 二叉树
  1. 二叉树两种存储结构:顺序表,链表。其中顺序表(按照 x 的 左 孩 子 为 2 x , 右 孩 子 为 2 x + 1 存 储 在 顺 序 表 中 x的左孩子为2x,右孩子为2x+1存储在顺序表中 x2x2x+1)的存储结构浪费空间。
  2. 二叉链的存储结构包含孩子指针,三叉链表示除了孩子指针还有双亲指针
  3. 遍历二叉树有四种方式:按层遍历,前序遍历,中序遍历,后序遍历
  4. 二叉树的叶子节点由左至右打印:前序遍历中叶子节点出现的顺序
  5. 造二叉树的三种方法:层序列,前序序列,后序序列(必须包含空节点)
  6. 遍历的两种实现方法:递归,非递归。其中非递归用到了栈,且以后序遍历最难
  7. 线索二叉树分为三种:前序线索二叉树,中序~,后序…(以前序为例,叶子节点的左指针指向前序遍历的上一个节点,右指针指向前序遍历的后一个节点)

Day three (data structure)

  • 森林转化成二叉树
  1. 树转二叉树用的是孩子兄弟表示法,没有右子树(因为根节点没有兄弟节点)
  2. 森林转二叉树:每棵树的根节点用虚线连接,不同树的节点不会连接。连接完成后,实线为左孩子,虚线为右孩子
  3. 树的遍历:1)先根遍历(<1>访问根;<2>访问每棵子树);2)后根遍历(<1>访问每棵子树;<2>访问根)
  4. 森林的遍历:1)先序遍历(<1>访问第一棵树根;<2>先序其子树森林;<3>访问其余树);2)中序遍历(<1>先访问其子树森林;<2>访问树根;<3>其余树)
  5. 森林遍历的序列到二叉树遍历的序列:先序<—>先序;中序<—>中序
  • 哈夫曼树
  1. 哈夫曼树是为了编码,将出现频度高的字符用最短的编码表示出来
  2. 编码分为两个过程:1)根据频度造树;2)根据树编码(这里有两种方法:由根到叶,由叶到根)
  3. 如果有n个待编码的字符,则构造出来的树有2n+1个节点
  4. 哈夫曼编码是前缀编码:任意字符的编码都不能是其他字符编码的前缀,即前缀的特征性

Day four (data structure)

  • 查找
  1. 查找分为静态查找和动态查找(只读,边读边改)
  2. 静态查找:顺序表的查找,v[0]作为哨兵,从后往前找
  3. 有序表的查找:折半查找,二叉判定树前n-1层为满,和完全二叉树类似,所以高度为 h = ⌊ l o g 2 n + 1 ⌋ h=\lfloor log_2n+1\rfloor h=log2n+1
  4. 随机存储能力:访问每个元素的时间一样,顺序表是,而链表会随着元素的增加而增大
  5. 静态查找的另一种:分块查找,也叫索引表查找,分块后每一块提供第一个元素的下标和这个块中的最大元素
  6. 动态查找:二叉排序树,自平衡二叉树(首先是二叉排序树,任一节点的左子树高度与右子树高度差的绝对值小于等于1)
  7. AVL树每个节点的平衡因子: B F = h l − h r BF=h_l-h_r BF=hlhr
  8. AVL树的转换:LL型,RR型,LR型,RL型。
  9. R转:若将来的顶节点的右子树不为空,则将其放在现在顶节点的左孩子上
  10. L转:若将来的顶节点的左子树不为空,则将其放在现在顶节点的右孩子上
  11. R转,L转为最基本的操作规则
  • 排序
  1. 排序有三种:插入排序,快速排序,堆排序
  2. 插入排序要先从第一个元素开始,每次都从当前元素的前一个开始比较
  3. 快速排序是用两个index同时从数组的两端遍历,以第一个元素为标准进行移动和交换
  4. 堆排序是按照最大堆(最小堆)对二叉树进行调整,每次调整结束都将最大(最小)的元素放在数组的最后同时将根节点与最后的节点交换并将最后的节点脱离该树,直到只剩下最后一个节点。

Day five (practice 1001~1015)

  • 1001
    递归
#include<iostream>
using namespace std;

void ShowNum(int x)
{
	if (x < 1000)
		cout << x;
	else
	{
		// 这里的递归先往下执行,归来后再执行之下的代码
		ShowNum(x / 1000);
		printf(",%03d", x % 1000);
	}
}

int main()
{
	int a, b, sum;
	cin >> a >> b;
	sum = a + b;
	if (sum < 0)
	{
		cout << '-';
		sum = -sum;
	}
	ShowNum(sum);
	system("pause");
	return 0;
}
  • 1002
    bool EqualToZero(double x); fabs~cmath; transform(v1,v1+1001,v2,result,plus<double>()); count_if(result,result+1001,not1(ptr_fun(EqualToZero)))
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<iomanip>
using namespace std;

bool EqualToZero(double x)
{
	return fabs(x) < 0.05;
}

int main()
{
	int k;
	// 这里必须是double类型
	double nums[1001] = { 0 };
	cin >> k;
	for (int i = 0; i < k; i++)
	{
		int index;
		cin >> index;
		cin >> nums[index];
	}
	cin >> k;
	for (int i = 0; i < k; i++)
	{
		int index;
		double temp;
		cin >> index >> temp;
		nums[index] += temp;
	}
	//transform(v1, v1 + 1001, v2, result, plus<double>()); // 这里是transform的用法
	int sumNum = count_if(nums, nums + 1001, not1(ptr_fun(EqualToZero)));
	cout << sumNum;
	for (int i = 1000; i >= 0; i--)
	{
		if (!EqualToZero(nums[i]))
		{
			//cout << ' ' << i << " " << fixed << setprecision(1) << nums[i];
			// 这里的浮点数用%f
			printf(" %d %.1f", i, nums[i]);
		}
	}
	system("pause");
	return 0;
}
  • 1004
    层遍历;已知非叶子节点,要运用在程序中;set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s,s.end()));

Day six (basic idea about graph)

Day seven (connectivity about graph)

Day eight (Dijkstra algorithm in graph)

Day nine (practice 1016~1026)

Day ten (practice 1027~1036)

Day eleven (practice 1037~1045)

Day twelve (practice )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值