【2020-MOOC-浙江大学-陈越、何钦铭-数据结构】树(第四周的笔记和编程作业)
2020-03-20 12:07
716 查看
文章目录
- 〇、前言
- 一、二叉搜索树
- 二、平衡二叉树
- 三、平衡二叉树的调整
- 四、是否同一棵二叉搜索树
- 五、课后题
- 1、04-树4 是否同一棵二叉搜索树 (25分)
- 2、04-树5 Root of AVL Tree (25分)
- 3、04-树6 Complete Binary Search Tree (30分)
- 4、04-树7 二叉搜索树的操作集 (30分)
〇、前言
这两周开始跟着【MOOC-浙江大学-陈越、何钦铭-数据结构】进行数据结构与算法的学习,特此记录复习一下,虽然记不住,但是一直记一直记一直记,成为复读机就好了。
一、二叉搜索树
二、平衡二叉树
三、平衡二叉树的调整
四、是否同一棵二叉搜索树
实现在后面的第一题!
五、课后题
1、04-树4 是否同一棵二叉搜索树 (25分)
输入样例:
4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0
输出样例:
Yes
No
No
#include <stdio.h> #include <stdlib.h> typedef struct TreeNode *Tree; struct TreeNode { int v; Tree Left, Right; int flag; }; Tree NewNode( int V ) { Tree T = (Tree)malloc(sizeof(struct TreeNode)); T->v = V; T->Left = T->Right = NULL; T->flag = 0; return T; } Tree Insert( Tree T, int V ) { if ( !T ) T = NewNode(V); else { if ( V>T->v ) T->Right = Insert( T->Right, V ); else T->Left = Insert( T->Left, V ); } return T; } Tree MakeTree( int N ) { Tree T; int i, V; scanf("%d", &V); T = NewNode(V); for (i=1; i<N; i++) { scanf("%d", &V); T = Insert(T, V); } return T; } int check ( Tree T, int V ) { if ( T->flag ) { if ( V<T->v ) return check(T->Left, V); else if ( V>T->v ) return check(T->Right, V); else return 0; } else { if ( V==T->v ) { T->flag = 1; return 1; } else return 0; } } int Judge( Tree T, int N ) { int i, V, flag = 0; /* flag: 0代表目前还一致,1代表已经不一致*/ scanf("%d", &V); if ( V!=T->v ) flag = 1; else T->flag = 1; for (i=1; i<N; i++) { scanf("%d", &V); if ( (!flag) && (!check(T, V)) ) flag = 1; } if (flag) return 0; else return 1; } void ResetT ( Tree T ) /* 清除T中各结点的flag标记 */ { if (T->Left) ResetT(T->Left); if (T->Right) ResetT(T->Right); T->flag = 0; } void FreeTree ( Tree T ) /* 释放T的空间 */ { if (T->Left) FreeTree(T->Left); if (T->Right) FreeTree(T->Right); free(T); } int main() { int N, L, i; Tree T; scanf("%d", &N); while (N) { scanf("%d", &L); T = MakeTree(N); for (i=0; i<L; i++) { if (Judge(T, N)) printf("Yes\n"); else printf("No\n"); ResetT(T); /*清除T中的标记flag*/ } FreeTree(T); scanf("%d", &N); } return 0; }
2、04-树5 Root of AVL Tree (25分)
Sample Input 1:
5
88 70 61 96 120
Sample Output 1:
70
Sample Input 2:
7
88 70 61 96 120 90 65
Sample Output 2:
88
#include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef int ElementType; typedef struct AVLNode *Position; typedef Position AVLTree; /* AVL树类型 */ struct AVLNode{ ElementType Data; /* 结点数据 */ AVLTree Left; /* 指向左子树 */ AVLTree Right; /* 指向右子树 */ int Height; /* 树高 */ }; int Max ( int a, int b ) { return a > b ? a : b; } int GetHeight(AVLTree A) { int MaxH, HR, HL; if(A) { HL = GetHeight(A->Left); HR = GetHeight(A->Right); MaxH = (HL>HR)?HL:HR; return MaxH+1; } return -1; } AVLTree SingleLeftRotation(AVLTree A) { AVLTree B = A->Left; A->Left = B->Right; B->Right = A; A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1; B->Height = Max(GetHeight(B->Left), A->Height) + 1; return B; } AVLTree SingleRightRotation(AVLTree A) { AVLTree B = A->Right; A->Right = B->Left; B->Left = A; A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1; A->Height = Max(GetHeight(B->Right), A->Height) + 1; return B; } AVLTree DoubleLeftRightRotation(AVLTree A) { A->Left = SingleRightRotation(A->Left); return SingleLeftRotation(A); } AVLTree DoubleRightLeftRotation(AVLTree A) { A->Right = SingleLeftRotation(A->Right); return SingleRightRotation(A); } AVLTree Insert( AVLTree T, ElementType X ) { /* 将X插入AVL树T中,并且返回调整后的AVL树 */ if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */ T = (AVLTree)malloc(sizeof(struct AVLNode)); T->Data = X; T->Height = 0; T->Left = T->Right = NULL; } /* if (插入空树) 结束 */ else if ( X < T->Data ) { /* 插入T的左子树 */ T->Left = Insert( T->Left, X); /* 如果需要左旋 */ if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 ) if ( X < T->Left->Data ) T = SingleLeftRotation(T); /* 左单旋 */ else T = DoubleLeftRightRotation(T); /* 左-右双旋 */ } /* else if (插入左子树) 结束 */ else if ( X > T->Data ) { /* 插入T的右子树 */ T->Right = Insert( T->Right, X ); /* 如果需要右旋 */ if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 ) if ( X > T->Right->Data ) T = SingleRightRotation(T); /* 右单旋 */ else T = DoubleRightLeftRotation(T); /* 右-左双旋 */ } /* else if (插入右子树) 结束 */ /* else X == T->Data,无须插入 */ /* 别忘了更新树高 */ T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1; return T; } int main() { int N, i; ElementType t; AVLTree T=NULL; scanf("%d", &N); for (i=0; i<N; i++) { scanf("%d",&t); T= Insert(T,t); } if(T) printf("%d", T->Data); return 0; }
3、04-树6 Complete Binary Search Tree (30分)
Sample Input:
10
1 2 3 4 5 6 7 8 9 0
Sample Output:
6 3 8 1 5 7 9 0 2 4
#include <stdlib.h> #include <stdio.h> #include <math.h> int arr[1000], rearr[1000]; int compare( const void* a, const void* b ){ return *(int*)a - *(int*)b; } int getLeftLength(int n){ //利用二叉树的性质:满二叉树第i层有 2^(i-1) 个结点, 高为h的满二叉树有 2^h - 1 个结点(从1开始) double h, x, L, t; h = (double)(int)( log((double)n+1) / log(2.0) ); //h = floor( log((double)n+1) / log(2.0) ); x = n - pow(2.0, h) + 1 ; t = pow(2.0, h - 1.0); x = x < t ? x : t; L = t - 1 + x; return (int)L; } void solve( int left, int right, int root ){ //初始调用: solve(0, n-1, 0); int n, L, leftRoot, rightRoot; n = right - left + 1; //数组中的总个数 if(n == 0) return ; //递归退出的条件 L = getLeftLength(n); //计算出左子树的结点 rearr[root] = arr[left + L]; //将新的根结点放入新的数组 leftRoot = root * 2 + 1; //左孩子 rightRoot = leftRoot + 1; //右孩子 solve(left, left + L - 1, leftRoot); solve(left + L + 1, right, rightRoot); } int main(){ int n; scanf("%d", &n); for(int i = 0; i < n; i++){ scanf("%d", &arr[i]); } qsort(arr, n, sizeof(int), compare); solve(0, n-1, 0); for(int i = 0; i < n; i++){ if( i != 0 ) printf(" "); printf("%d", rearr[i]); } system("pause"); return 0; }
4、04-树7 二叉搜索树的操作集 (30分)
#include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef struct TNode *Position; typedef Position BinTree; struct TNode{ ElementType Data; BinTree Left; BinTree Right; }; void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */ void InorderTraversal( BinTree BT ); /* 中序遍历,由裁判实现,细节不表 */ BinTree Insert( BinTree BST, ElementType X ); BinTree Delete( BinTree BST, ElementType X ); Position Find( BinTree BST, ElementType X ); Position FindMin( BinTree BST ); Position FindMax( BinTree BST ); int main() { BinTree BST, MinP, MaxP, Tmp; ElementType X; int N, i; BST = NULL; scanf("%d", &N); for ( i=0; i<N; i++ ) { scanf("%d", &X); BST = Insert(BST, X); } printf("Preorder:"); PreorderTraversal(BST); printf("\n"); MinP = FindMin(BST); MaxP = FindMax(BST); scanf("%d", &N); for( i=0; i<N; i++ ) { scanf("%d", &X); Tmp = Find(BST, X); if (Tmp == NULL) printf("%d is not found\n", X); else { printf("%d is found\n", Tmp->Data); if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data); if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data); } } scanf("%d", &N); for( i=0; i<N; i++ ) { scanf("%d", &X); BST = Delete(BST, X); } printf("Inorder:"); InorderTraversal(BST); printf("\n"); return 0; } /* 你的代码将被嵌在这里 */
输入样例:
10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3
输出样例:
Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9
BinTree Insert( BinTree BST, ElementType X ){ if( !BST ){ BST = (BinTree)malloc(sizeof(struct TNode)); BST->Data = X; BST->Left = BST->Right = NULL; } else { if( X < BST->Data ) BST->Left = Insert( BST->Left, X ); else if( X > BST->Data ) BST->Right = Insert( BST->Right, X ); //else if(X = BST->Data) do nothing } return BST; } BinTree Delete( BinTree BST, ElementType X ){ Position TMP; if( !BST ) printf("Not Found\n"); else { if( X < BST->Data ) BST->Left = Delete( BST->Left, X ); //从左子树递归删除 else if( X > BST->Data ) BST->Right = Delete( BST->Right, X ); //从右子树递归删除 else { //BST就是要删除的结点 if( BST->Left && BST->Right ){ //如果BST左右孩子都有 TMP = FindMin( BST->Right ); //从右子树中找到最小的结点来代替该结点 BST->Data = TMP->Data; BST->Right = Delete( BST->Right, BST->Data ); //从右子树中把最小的结点删除 } else { TMP = BST; if( !BST->Left ) //如果只有右结点,或者没有结点 BST = BST->Right; else //只有左结点 BST = BST->Left; free( TMP ); } } } return BST; } Position Find( BinTree BST, ElementType X ){ if( !BST ) return NULL; else if( X == BST->Data ) return BST; else if( X > BST->Data ) return Find( BST->Right, X ); else if( X < BST->Data ) return Find( BST->Left, X ); return NULL; } //递归查找最小元素 Position FindMin( BinTree BST ){ if( !BST ) return NULL; else if( !BST->Left ) return BST; else if( BST->Left ) FindMin( BST->Left ); } //非递归查找最大元素 Position FindMax( BinTree BST ){ if( BST ) while( BST->Right ) BST = BST->Right; return BST; }
总结
简单总结下这周的学习内容,继续二叉树,我觉得自己非常有做调包侠的前途!!!
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 【MOOC-浙江大学-陈越、何钦铭-数据结构】线性结构-线性表、堆栈与队列(第二周的笔记和编程作业)
- 【MOOC-浙江大学-陈越、何钦铭-数据结构】树(第三周的笔记和编程作业)
- 【MOOC-浙江大学-陈越、何钦铭-数据结构】数据结构与算法的基本概念(第一周的笔记和编程作业)
- 中国大学MOOC-陈越、何钦铭-数据结构-笔记
- PTA中国大学MOOC-陈越、何钦铭-数据结构-2017春课后作业03树1 树的同构
- [PTA-PAT]中国大学MOOC-陈越、何钦铭-数据结构-起步能力自测题-自测-3 数组元素循环右移问题
- 陈越、何钦铭《数据结构》第一讲基本概念 笔记
- [PTA-PAT]中国大学MOOC-陈越、何钦铭-数据结构-起步能力自测题-自测-4 Have Fun with Numbers
- 中国大学MOOC-陈越、何钦铭-数据结构 Maximum Subsequence Sum
- 中国大学MOOC-陈越、何钦铭-数据结构-2019夏期中考试(题目+错题分析)
- 中国大学MOOC-陈越、何钦铭-数据结构 Root of AVL Tree
- 中国大学MOOC-陈越、何钦铭-数据结构-2018春-03-树2 List Leaves
- 中国大学MOOC-陈越、何钦铭-数据结构-2019春期中考试
- 【中国大学mooc—浙江大学数据结构2018春】1.3节求最大子列和问题,算法3的实现(对应作业题目:01-复杂度1 最大子列和问题)
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春
- 中国大学MOOC-陈越、何钦铭-数据结构 一元多项式的乘法与加法运算
- 中国大学MOOC-陈越、何钦铭-数据结构-2017春
- 中国大学MOOC-陈越、何钦铭-数据结构 Insert or Merge
- 中国大学MOOC-陈越、何钦铭-数据结构 Tree Traversals Again
- 中国大学MOOC-陈越、何钦铭-数据结构 是否同一棵二叉搜索树