/DS_Model_C

2021王道数据结构考研复习指导、2019天勤数据结构、Essentail C++、剑指offer、leetcode

Primary LanguageC


声明

本人本着以学习为目的整合了2021年王道数据结构考研复习指导2019年天勤数据结构高分笔记中的大部分算法题、并给出相应的解答和示例, 在此不保证所有的题解均正确无误,仅供学习参考,请勿用于商业用途,如若侵权,请联系并删除。 如果你觉得这个仓库对你有帮助,请不要吝啬你的star!!!谢谢!!!

目录


1. 王道数据结构

1.1 环境配置
  • 编译器版本
g++ --version

g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1.2 data_struct/wangdao
  • 编译
g++ -o ch02.o ch02.cpp ch02_linear_table/*.cpp
g++ -o ch03.o ch03.cpp ch03_stack_queue/*.cpp
g++ -o ch05.o ch05.cpp ch05_tree/*.cpp
g++ -o ch08.o ch08.cpp ch08_sort/*.cpp -std=c++11
  • 目录结构
├── README.md
├── ch02.cpp
├── ch02_linear_table (顺序表、单链表)
│   ├── LinkList.cpp
│   ├── LinkList.hpp
│   ├── SqList.cpp
│   ├── SqList.hpp
│   ├── exercises.cpp
│   └── exercises.hpp
├── ch03.cpp
├── ch03_stack_queue (栈、队列)
│   ├── SqQueue.cpp
│   ├── SqQueue.hpp
│   ├── SqStack.cpp
│   ├── SqStack.hpp
│   ├── exercises.cpp
│   └── exercises.hpp
├── ch05.cpp
├── ch05_tree (二叉树、二叉排序树、树、森林)
│   ├── BiTree.cpp
│   ├── BiTree.hpp
│   ├── BinarySearchTree.cpp
│   ├── BinarySearchTree.hpp
│   ├── ThreadTree.cpp
│   ├── ThreadTree.h
│   ├── Tree.cpp
│   ├── Tree.hpp
│   ├── exercises.cpp
│   └── exercises.hpp
├── ch08.cpp
├── ch08_sort (插入、交换、选择、归并)
    ├── exercises.cpp
    ├── exercises.hpp
    ├── sort.cpp
    └── sort.hpp
1.3 习题汇总
1.3.1 线性表

详见: data_struct/wangdao/ch02_linear_table/exercises.hpp

  • 练习 2.2 线性表的顺序实现 p19-p21
void Reverse(SqList &L);                                // 2. 将顺序表 L 的所有元素逆置
void Reverse(ElemType A[], int m, int n, int size);     // 8. 将数组顺序表位置互换
                                                        // 10. 将 R 中保存的序列循环左移 p (O<p<n ) 个位置
void del_x_2(SqList &L,ElemType x);                     // 3. 删除线性表中所有值为 x 的数据元素
bool Delete_Same(SqList& L);                            // 6. 从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
bool Del_s_t(SqList &L, ElemType s, ElemType t);        // 4. 从有序顺序表中删除其值在给定值s与t之间(要求s<t) 的所有元素
bool Del_s_t2(SqList &L, ElemType s, ElemType t);       // 5. 从顺序表中删除其值在给定值s与t之间(要求s<t) 的所有元素
bool Merge(SqList A, SqList B, SqList &C);              // 7. 将两个有序顺序表合并为一个新的有序顺序表
void SearchExcgIst(ElemType A[], int n, ElemType x);    // 9. 线性表递增有序,在表中查找数值为 x 的元素
int MSearch(int A[],int B[],int n);                     // 11. 找出两个序列 A 和 B 的中位数。
double MSearch1(int A[], int m, int B[],int n);
int MSearch2(int A[],int B[],int n);                    /** ❌ */
bool Del_Min(SqList &L, ElemType &value);               // 1. 从顺序表中删除具有最小值的元素
int Majority (int A[], int n);                          // 12. 找出数组 A 的主元素
int findMissMin(int A[] , int n);                       // 13. 找出数组中未出现的最小正整数
  • 练习 2.2 线性表的链式表示 p40-p44
LinkList Search_Lst_Common(LinkList L1, LinkList L2);   // 8. 给定两个单链表,编写算法找出两个链表的公共结点。
LNode* find_addr(LNode *strl , LNode *str2);            // 22.找出由 str1 和 str2 所指向两个链表共同后缀的起始位置
int Search_k(LinkList list, int k);                     // 21.查找链表中倒数第 k 个位直上的结点(k为正整数)
LNode* FindLoopStart(LNode *head);                      // 24.判断一个链表是否有环,如果有,找出环的入口点并返回,否则返回 NULL。
void change_list(LNode*&h);                             // 25. 单链表{a1,a2,··· ,an}转换为{a1,an,a2,an-1,a3,an-2,···}
void Del_X_1(LinkList &L, ElemType x);                  // 1. 设计一个递归算法, 删除不带头结点的单链表 L 中所有值为 x 的结点。
void Del_X_2(LinkList &L, ElemType x);                  // 2. 在带头结点的单链表 L 中,删除所有值为 x 的结点
void RangeDelete(LinkList &L, int min, int max);        // 7. 删除表中所有介于给定的两个值(作为函数参数给出)之间的元素的元素
void Del_Same(LinkList &L);                             // 12.递增有序的单链表表去重(去掉数值相同的元素)
LinkList Delete_Min(LinkList &L);                       // 4. 带头结点的单链表 L 中删除一个最小值结点
void MinDelete(LinkList &head);                         // 9. 按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间
void Del_All(LinkList &L);                              // 19.反复找出单链表中结点值最小的结点并输出,然后将该结点从中删除,直到单链表空为止,再删除表头结点。
void R_Print(LinkList L);                               // 3. 带头结点的单链表从尾到头反向输出每个结点的值
LinkList Reverse_1(LinkList &L);                        // 5. 将带头结点的单链表就地逆置
void Sort(LinkList &L);                                 // 6. 有一个带头结点的单链表 L,设计一个算法使其元素递增有序。
LinkList DisCreat_1(LinkList &A);                       // 10.将一个带头结点的单链表 A 分解为两个带头结点的单链表 A 和 B
LinkList DisCreat_2(LinkList &A);                       // 11.单链表 A 分解为A={a1,a2,··· , an,}, B={bn,bn-1,...,b2,b1}
LinkList MergeList(LinkList La,LinkList Lb);            // 13.将两个按元素值递增次序排列的单链表归并为一个递减的单链表
LinkList Get_Common(LinkList A, LinkList B);            // 14.从两个元素递增有序的单链表(带头结点)中的公共元素产生单链表C
void Union(LinkList &la, LinkList &lb);                 // 15.求两个元素递增排列的单链表 A 与 B 的交集,并存放于 A 链表中。
int Symmetry(DLinkList L);                              // 17.判断带头结点的循环双链表是否对称。
LinkList Link(LinkList &h1 , LinkList &h2);             // 18.将循环单链表h2 链接到循环单链表h1,要求链接后的链表仍保持循环链表。
DLinkList Locate(DLinkList &L,ElemType x);              // 20.非循环双向链表符合要求的 Locate(L,x) 运算的算法
int Pattern(LinkList A,LinkList B);                     // 16. 判断序列 B 是否是序列 A 的连续子序列
void func(LNode* &h, int n);                            // 23.对于链表中 data 的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点
1.3.2 栈、队列

详见: data_struct/wangdao/ch03_stack_queue/exercises.hpp

  • 练习 3.1 栈 p71
int dc(LNode<char> *L, int n);                                  // 4. 判断链表的全部 n 个字符是否中心对称
typedef struct sstk{                                            // 5. 共享栈
    int top[2];
    ElemType data[MaxStackSize];
};
int push(ElemType i, ElemType x);
int pop (ElemType i);
  • 练习 3.2 队列
typedef struct tqueue{                                          // 1. 设置一个标志域 tag 的入队和出队算法
    ElemType data[MaxStackSize];
    int front,rear,tag;
};
int tEnQueue(tqueue &s, ElemType x);
int tDeQueue(tqueue &s, ElemType &x);
void Inverse(SqQueue<ElemType> &Q, SqStack<ElemType> &S);       // 2. Q 是一个队列,S 是一个空栈,实现将队列中的元素逆置的算法。
typedef struct SSQueue{                                         // 3. 利用两个栈 S1, S2 来模拟一个队列
    SqStack<ElemType> S1,S2;
};
int EnSSQueue(SSQueue &q, ElemType x);
int DeSSQueue(SSQueue &q, ElemType &x);
int SSQueueEmpty(SSQueue q);
  • 3.3 核和队列的应用 p96-97
bool BracketsCheck(char *str);                                 // 1. 判别表达式中的括号是否配对
double p(int n,double x);                                      // 2. 利用一个找实现递归函数的非递归计算
1.3.3 二叉树

详见: data_struct/wangdao/ch05_tree/exercises.hpp

  • 练习 5.3 二叉树的遍历和索引二叉树 (p149-p151)
void InvertLevel(BiTree T);                             // 4. 二又树自下而上、从右到左的层次遍历算法。
int Btdepth(BiTree T);                                  // 5. 非递归求二叉树的高度。
int BtdepthR(BiTree T);
BiTNode* BiTreePreinCreate(ElemType *A, int l1, int h1, // 6. 根据先序遍历序列和中序遍历序列建立二叉链表 (二叉树中各结点的值互不相同)
                           ElemType *B, int l2, int h2);
bool IsComplete(BiTree T);                              // 7. 判别二叉树是否为完全二叉树。
int DsonNodes (BiTree T);                               // 8. 计算一棵给定二叉树的所有双分支结点个数。
int DsonNodes1 (BiTree T);
void swap(BiTree T);                                    // 9. 交换二叉树中所有结点的左、右子树。
void swap1(BiTree T);
ElemType PreNode(BiTree T, int k);                      // 10. 求先序遍历序列中第 k (1<= k <= 二又树中结点个数)个结点的值。
void SearchDeleteXTree(BiTree T, ElemType x);           // 11. 对于树中每个元素值为 x 的结点,删去以它为根的子树,并释放相应的空间。
void Search (BiTree T , ElemType x);                    // 12. 在二叉树中查找值为 x 的结点,打印值为 x 的结点的所有祖先
bool SearchR (BiTree T , ElemType x);
BiTree Ancestor(BiTree ROOT, BiTNode *p, BiTNode *q);   // 13. 找到 p 和 q的最近公共祖先结点 r。
BiTree AncestorR(BiTree T, BiTNode *p, BiTNode *q);
int BTWidth(BiTree T);                                  // 14. 求非空二又树 b 的宽度(即具有结点数最多的那一层的结点个数)。
void PreToPost(ElemType pre[],int l1, int h1,           // 15. 满二叉树已知其先序序列为 pre,求后序序列 post。
               ElemType post[],int l2,int h2);
BiTNode* LeafToLinikedList(BiTNode* T);                 // 16. 二叉树的叶结点按从左到右的顺序连成一个单链表
bool Similar(BiTree T1, BiTree T2);                     // 17. 判断两棵二叉树是否相似
ThreadNode* InPostPre(ThreadNode* T , ThreadNode* p);   // 18. 写出在中序线索二叉树里查找指定结点在后序的前驱结点的算法 。
int wpl(BiTree T);                                      // 19. 二又树的带权路径长度
void BtreeToExp(BiTree T, int depth);                   // 20. 将给定的表达式树(二叉树)转换为等价的中缀表达式并输出。
  • 练习 5.4 树、森林 (p176-p177)
int leaves(CSTree T);                                   // 5. 编程求以孩子兄弟表示法存储的森林的叶子结点数。
void createCSTree_Degree(                               // 7. 己知一棵树的层次序列及每个结点的度,编写算法构造此树的孩子兄弟链表。
    CSTree&T, ElemType e[], int degree[], int n);
int Height (CSTree bt);                                 // 6. 以孩子兄弟链表为存储结构,请设计递归算法求树的深度。
  • 练习 5.5 树与二叉树的应用 (p195-p196)
bool JudgeBST(BSTree bt);                               // 6. 试编写一个算法,判断给定的二叉树是否是二叉排序树。

int level(BSTree bst, BSTNode *p);                      // 7. 设计一个算法,求出在指定结点给定二叉排序树中的层次。
int levelR(BSTree bst, BSTNode *p);
                                                        /** ★★☆ */
bool Judge_AVL(BSTree bst, int &depth);                 // 8. 利用二叉树遍历的**编写一个判断二叉树是否是平衡二叉树的算法。
int MinBST(BSTree bst);                                 // 9. 设计一个算法,求出给定二叉排序树中最小和最大的关键字。
int MaxBST(BSTree bst);
void OutPut(BSTNode *bt, int key);                      // 10. 设计一个算法 ,从大到小输出二叉排序树中所有值不小于 k 的关键字。
BSTNode *Search_Small(BSTNode*t , int k );              // 12. 二叉排序树上查找第 k (1<=k<=n) 小的元素,并返回指向该结点的指针。
  • 总结 p206-p207
void DelLeafNode(BiTree bt);                            // 6. 从二叉树中删去所有叶结点。     (层次遍历 => 参考练习5.3_11)
int GetLevel(BiTree bt,BiTNode *p);                     // 7. 计算指定结点 *p 所在的层次。  (层次遍历=>参考练习5.3_5)
1.3.4 排序

详见: data_struct/wangdao/ch08_sort/exercises.hpp

  • 8.3 交换排序 p323-p324
void BubbleSort(ElemType A[], int n);                   // 2. 双向冒泡排序算法
void move(ElemType A[], int n);                         // 3. 把所有奇数移动到所有偶数前边的算法
void move2(ElemType A[], int n);
int Partition2(ElemType A[], int low, int high);        // 4. 重新编写快速排序的划分算法,使之每次选取的枢轴值都是随机地从当前子表中选择的。
int kth_elem(ElemType A[] , int low, int high, int k);  // 5. 数组中找出第 k 小的元素
int setPartition(ElemType A[], int n);                  // 6. 将A划分为两个不相交的子集,满足 |n_1-n_2| 最小且 |S_1-S_2| 最大
int PartitionN(ElemType A[],int n);                     // 4. (8.6)数组{K_1,K_2,...,K_n}, 将 K_n,放在将元素排序后的正确位置上
void Flag_A_rrange(ElemType A[],int n);                 // 7. 荷兰国旗问题
  • 8.4 选择排序 p335
void selectSort(LNode<ElemType> *&L);                   // 4. 在基于单链表表示的待排序关键字序列上进行简单选择排序。
bool IsMinHeap(ElemType A[], int len);                  // 5. 试设计一个算法,判断一个数据序列是否构成一个小根堆。
  • 8.6 各种内部排序算法的比较和应用
void Insert_Sort(ElemType A[] , int m, int n);          // 2. 前m个元素递增有序,后n个元素递增有序,设计一个算法,使得整个顺序表有序。
1.4 参考

[1]2021年王道数据结构考研复习指导 [2]C++之函数/结构体/类 模板

2. 天勤高分笔记2019

  • 第2章 线性表

    • 顺序表的定义和基本操作
    • 单链表的定义和基本操作
    • 双链表的定义和基本操作
    • 线性表习题集
  • 第3章 栈和队列

    • 栈的存储结构和算法
    • 队列的存储结构和算法
    • 队列和栈的习题
  • 第6章 树和二叉树

    • 二叉树的存储结构和基本操作(主要是二叉树)
    • 二叉树的递归遍历
    • 二叉树的非递归遍历
    • 索引二叉树
    • 树、森林、二叉树
    • 二叉树习题
  • 第8章 内部排序

    • 插入类
      • 直接插入排序
      • 折半插入排序
      • 希尔排序
    • 交换类
      • 冒泡排序
      • 快速排序
    • 选择类
      • 简单选择排序
      • 最大堆调整
    • 选择类
      • 简单选择排序
      • 堆排序
    • 归并排序
      • 二路归并排序
  • 第9章 查找

    • 顺序查找
    • 折半查找
    • 二叉排序树
    • 平衡二叉排序树

3. Essential C++

  • 第1章 C++编程基础
extern void example_01_06();        // p7
extern void example_01_07();        // p33
extern void ex_01_01();             // p7
extern void ex_01_02();             // p7
extern void ex_01_05();             // p33
extern void ex_01_06();             // p33
extern void ex_01_07();             // p34
  • 第2章 面向过程的编程风格
extern bool example_02_01(int pos, int &elem);      // p36
extern void example_02_02();                        // p45 传值、传指针、传引用
extern const vector<int>* example_02_03(int size);  // p54 局部静态对象
extern bool example_02_04(int pos, int& elems);     // p55 内联函数

4. LeetCode 分类刷题 (暂时没时间)

lc: leetcode、面试题(smo): 剑指offer

数组
题号 题名 方法
167 两数之和 II - 输入有序数组 双指针
面试题57 和为s的两个数字 双指针
977 有序数组的平方 双指针
88 合并两个有序数组 双指针
26 删除排序数组中的重复项 双指针
283 移动零 双指针
面试题03 数组中重复的数字 哈希
面试题04 二维数组中的查找 双指针
面试题06 从尾到头打印链表 双指针
面试题21 调整数组顺序使奇数位于偶数前面 双指针
面试题39 数组中出现次数超过一半的数字
面试题63 股票的最大利润 打擂台法