From 83048b3835a503b6be6f7971ccffc2a8806fa5cd Mon Sep 17 00:00:00 2001
From: yuan-fei0 <2029284928@qq.com>
Date: Tue, 11 Apr 2023 22:44:51 +0800
Subject: [PATCH] yf
---
alg.md | 204 +++++++++++++++++++++++++++++++++++--------------------
alg.py | 62 +++++++++--------
gen.py | 9 ++-
main.cpp | 90 ++++++++++++++++++++++++
test.py | 20 +-----
5 files changed, 264 insertions(+), 121 deletions(-)
diff --git a/alg.md b/alg.md
index 6529d80..3f7c3a3 100644
--- a/alg.md
+++ b/alg.md
@@ -1,90 +1,148 @@
-# 解题报告:构建最大二叉树
-
-## 题目描述
-
- 给定一个不重复的整数数组 `nums`,构建一个最大二叉树,其中根节点的值为 `nums` 中的最大值,左子树是构建在最大值左边的子数组的最大二叉树,右子树是构建在最大值右边的子数组的最大二叉树。
-
-## 思路分析
-
- 对于一个不重复的整数数组 `nums`,我们可以通过以下步骤构建一个最大二叉树:
+# 算法设计分析
+
+### 输出数组中第K大的数
+
+###### 1.测试数据生成
+
+```c++
+int num[5] = { 0 };
+ while (num[4] == 0)
+ {
+ srand((int)time(0)); // 产生随机种子 把0换成NULL也行
+ for (int i = 0; i < 5; i++)
+ {
+ int a = (rand() % 100) + 1;
+ num[i] = a;
+ }
+ }
+ cout << "生成随机数组:" << endl;
+ for (int i = 0; i < 5; i++)
+ cout << num[i] << ' ';
+ cout << endl;
+```
-1. 找到数组中的最大值及其索引。
-2. 创建根节点,其值为最大值。
-3. 递归地在最大值左边的子数组前缀上构建左子树。
-4. 递归地在最大值右边的子数组后缀上构建右子树。
-5. 返回构建好的最大二叉树的根节点。
+思路:srand()产生随机种子,以此产生随机数。将num[]初始化为0,再将数组各元素替换成生成的随机数。
+
+###### 2.算法实现及测试
+
+```c++
+void merge(int* a, int low, int mid, int hight) //合并函数
+{
+ int* b = new int[hight - low + 1]; //用 new 申请一个辅助函数
+ int i = low, j = mid + 1, k = 0; // k为 b 数组的小标
+ while (i <= mid && j <= hight)
+ {
+ if (a[i] <= a[j])
+ {
+ b[k++] = a[i++]; //按从小到大存放在 b 数组里面
+ }
+ else
+ {
+ b[k++] = a[j++];
+ }
+ }
+ while (i <= mid) // j 序列结束,将剩余的 i 序列补充在 b 数组中
+ {
+ b[k++] = a[i++];
+ }
+ while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中
+ {
+ b[k++] = a[j++];
+ }
+ k = 0; //从小标为 0 开始传送
+ for (int i = low; i <= hight; i++) //将 b 数组的值传递给数组 a
+ {
+ a[i] = b[k++];
+ }
+ delete[]b; // 辅助数组用完后,将其的空间进行释放(销毁)
+}
+
+
+
+void mergesort(int* a, int low, int hight) //归并排序
+{
+ if (low < hight)
+ {
+ int mid = (low + hight) / 2;
+ mergesort(a, low, mid); //对 a[low,mid]进行排序
+ mergesort(a, mid + 1, hight); //对 a[mid+1,hight]进行排序
+ merge(a, low, mid, hight); //进行合并操作
+ }
+}
+
+int main()
+{
+ int num[5] = { 0 };
+ while (num[4] == 0)
+ {
+ srand((int)time(0)); // 产生随机种子 把0换成NULL也行
+ for (int i = 0; i < 5; i++)
+ {
+ int a = (rand() % 100) + 1;
+ num[i] = a;
+ }
+ }
+ cout << "生成随机数组:" << endl;
+ for (int i = 0; i < 5; i++)
+ cout << num[i] << ' ';
+ cout << endl;
+
+ mergesort(num, 0, 4);
+ cout << "归并排序后的结果:" << endl;
+ for (int i = 0; i < 5; i++)
+ cout << num[i] << ' ';
+ cout << endl;
+
+ int k;
+ cout << "输入k:";
+ cin >> k;
+ if (k > 4) {
+ cout << "超过数组大小!";
+ return 0;
+ }
+ cout << "第k大的数为:";
+ cout << num[k - 1];
+
+
+ return 0;
+
+
+}
+```
-## 代码实现
+*思路*:归并排序,将产生的随机数组进行排序。输出第K-1个数即可。
- 下面是python代码实现,其中`TreeNode`类定义了二叉树节点的结构,`constructMaximumbinaryTree`函数接收一个整数数组 `nums`,返回该数组构建的最大二叉树的根节点。在函数内部,首先判断如果 `nums` 数组为空,则直接返回 `None`。否则,找到数组中的最大值及其索引,创建根节点,其值为最大值。然后,递归地在最大值左边的子数组前缀上构建左子树,递归地在最大值右边的子数组后缀上构建右子树。最后,返回构建好的最大二叉树的根节点。
+**归并排序**:归并排序是比较稳定的排序方法。它的基本思想是把待排序的元素分解成两个规模大致相等的子序列。如果不易分解,将得到的子序列继续分解,直到子序列中包含的元素个数为1。因为单个元素的序列本身就是有序的,此时便可以进行合并,从而得到一个完整的有序序列。
-```python
-# Definition for a binary tree node.
-class TreeNode:
- def __init__(self, val=0, left=None, right=None):
- self.val = val
- self.left = left
- self.right = right
-
-def constructMaximumBinaryTree(nums):
- # 如果数组为空,则返回None
- if not nums:
- return None
-
- max_num = max(nums)
+**分治算法**:将一个大问题分成多个规模较小的子问题,分而治之。
- # 找到数组中的最大值及其索引
- idx = nums.index(max_num)
+###### 3.性能分析
- # 创建根节点,其值为最大值
- root = TreeNode(max_num)
- # 递归地在最大值左边的子数组前缀上构建左子树
- root.left = constructMaximumBinaryTree(nums[:idx])
- # 递归地在最大值右边的子数组后缀上构建右子树
- root.right = constructMaximumBinaryTree(nums[idx+1:])
-
- # 返回构建好的最大二叉树的根节点
- return root
+**空间性能**:
+$$
+O(log~2^n)+O(n)
+$$
+**时间性能**:
+$$
+O(nlogn)
+$$
-```
+###### 4.代码测试
-## 测试示例
-
- 下面是一个测试代码的例子:
-
-```python
-import alg
-nums = [3, 2, 1, 6, 0, 5]
-# 构建最大二叉树
-root = alg.constructMaximumBinaryTree(nums)
-# 前序遍历二叉树
-def preorderTraversal(root):
- res = []
- def helper(root):
- # 如果树为空,则返回None
- if not root:
- return None
- res.append(root.val)
- helper(root.left)
- helper(root.right)
- helper(root)
- return res
-# 打印遍历结果
-print(preorderTraversal(root))
-```
+
- 这个测试代码将一个整数数组传递给 `constructMaximumBinaryTree` 函数,得到该数组构建的最大二叉树的根节点。然后,使用 `preorderTraversal` 函数进行前序遍历,并打印遍历结果。运行该测试代码将输出 `[6,3,2,1,5,0]`,即最大二叉树的前序遍历结果。
+###### 5.心得体会
-## 时间复杂度分析
+git用起来没有第一次那么坎坷,基本的操作都没有问题,也在不断地用一些新东西。这次代码部分我用了自己更加熟悉的c++,写起来更加流畅一点点。
- 对于一个长度为 `n` 的不重复的整数数组 `nums`,构建最大二叉树的时间复杂度为 $O(n\log n)$。
+###### 6.实验环境
- 在构建最大二叉树的过程中,每个节点最多会被访问两次,因此时间复杂度为 $O(n)$。而在最坏情况下,数组中的每个数都会成为树的根节点,因此二叉树的深度为 $O(n)$,所以总的时间复杂度为 $O(n\log n)$。
+win11.
-## 空间复杂度
+python3.11
- 对于一个长度为 `n` 的不重复的整数数组 `nums`,构建最大二叉树的空间复杂度为 $O(n)$。
+vs2022
-在构建最大二叉树的过程中,每个节点最多会被访问两次,因此递归栈的空间复杂度为 $O(n)$。此外,由于最大二叉树的节点数为 $n$,因此需要额外的 $O(n)$ 的空间来存储二叉树的节点。因此总的空间复杂度为 $O(n)$。
\ No newline at end of file
+git.
\ No newline at end of file
diff --git a/alg.py b/alg.py
index 35282b9..5052390 100644
--- a/alg.py
+++ b/alg.py
@@ -1,28 +1,34 @@
-# Definition for a binary tree node.
-class TreeNode:
- def __init__(self, val=0, left=None, right=None):
- self.val = val
- self.left = left
- self.right = right
-
-def constructMaximumBinaryTree(nums):
- # 如果数组为空,则返回None
- if not nums:
- return None
-
- max_num = max(nums)
-
- # 找到数组中的最大值及其索引
- idx = nums.index(max_num)
-
- # 创建根节点,其值为最大值
- root = TreeNode(max_num)
-
- # 递归地在最大值左边的子数组前缀上构建左子树
- root.left = constructMaximumBinaryTree(nums[:idx])
-
- # 递归地在最大值右边的子数组后缀上构建右子树
- root.right = constructMaximumBinaryTree(nums[idx+1:])
-
- # 返回构建好的最大二叉树的根节点
- return root
+def merge(a,b):
+ l=[]
+ f=s=0
+ while f
+#include
+using namespace std;
+
+
+void merge(int* a, int low, int mid, int hight) //合并函数
+{
+ int* b = new int[hight - low + 1]; //用 new 申请一个辅助函数
+ int i = low, j = mid + 1, k = 0; // k为 b 数组的小标
+ while (i <= mid && j <= hight)
+ {
+ if (a[i] <= a[j])
+ {
+ b[k++] = a[i++]; //按从小到大存放在 b 数组里面
+ }
+ else
+ {
+ b[k++] = a[j++];
+ }
+ }
+ while (i <= mid) // j 序列结束,将剩余的 i 序列补充在 b 数组中
+ {
+ b[k++] = a[i++];
+ }
+ while (j <= hight)// i 序列结束,将剩余的 j 序列补充在 b 数组中
+ {
+ b[k++] = a[j++];
+ }
+ k = 0; //从小标为 0 开始传送
+ for (int i = low; i <= hight; i++) //将 b 数组的值传递给数组 a
+ {
+ a[i] = b[k++];
+ }
+ delete[]b; // 辅助数组用完后,将其的空间进行释放(销毁)
+}
+
+
+
+void mergesort(int* a, int low, int hight) //归并排序
+{
+ if (low < hight)
+ {
+ int mid = (low + hight) / 2;
+ mergesort(a, low, mid); //对 a[low,mid]进行排序
+ mergesort(a, mid + 1, hight); //对 a[mid+1,hight]进行排序
+ merge(a, low, mid, hight); //进行合并操作
+ }
+}
+
+
+
+
+int main()
+{
+ int num[5] = { 0 };
+ while (num[4] == 0)
+ {
+ srand((int)time(0)); // 产生随机种子 把0换成NULL也行
+ for (int i = 0; i < 5; i++)
+ {
+ int a = (rand() % 100) + 1;
+ num[i] = a;
+ }
+ }
+ cout << "生成随机数组:" << endl;
+ for (int i = 0; i < 5; i++)
+ cout << num[i] << ' ';
+ cout << endl;
+
+ mergesort(num, 0, 4);
+ cout << "归并排序后的结果:" << endl;
+ for (int i = 0; i < 5; i++)
+ cout << num[i] << ' ';
+ cout << endl;
+
+ int k;
+ cout << "输入k:";
+ cin >> k;
+ if (k > 4) {
+ cout << "超过数组大小!";
+ return 0;
+ }
+ cout << "第k大的数为:";
+ cout << num[k - 1];
+
+
+ return 0;
+
+
+}
\ No newline at end of file
diff --git a/test.py b/test.py
index 3af3054..339b894 100644
--- a/test.py
+++ b/test.py
@@ -1,19 +1 @@
-import gen
-import alg
-
-n = gen.nums
-root = alg.constructMaximumBinaryTree(n)
-# 前序遍历二叉树
-def preorderTraversal(root):
- res = []
- def helper(root):
- # 如果树为空,则返回None
- if not root:
- return None
- res.append(root.val)
- helper(root.left)
- helper(root.right)
- helper(root)
- return res
-# 输出遍历结果
-print(preorderTraversal(root))
+包含在alg中
--
Gitee