![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Data Structure
xupeng1644
道阻且长,行则将至!
展开
-
树中两节点的最低公共祖先
上图中节点C、D的最低公共祖先为B;节点B、E 的最低公共祖先为A;节点D、F的最低公共最先为A;其与的依次类推即可。代码如下:BTNode* GetAncestorOfTwoNode(BTNode* pRoot, int nData1, int nData2){ if (NULL == pRoot) return NULL; std::deque myDe原创 2015-10-17 22:53:19 · 339 阅读 · 0 评论 -
二叉树中获取从根节点到某个节点的路径
这个概念大家都懂,直接上代码bool GetThePathOfNode(BTNode* pRoot, int nData, std::deque& myDeque){ if (NULL == pRoot) return false; if (pRoot->nData == nData) { myDeque.push_back(pRoot); return true原创 2015-10-17 21:55:54 · 2409 阅读 · 0 评论 -
树的子结构
判断一棵树是否是另外一棵树的子树。bool DoesTree1HasTree2(BTNode* pRoot1, BTNode* pRoot2){ if (NULL == pRoot1) return false; if (NULL == pRoot2) return true; if (pRoot1->nData != pRoot2->nData) return fal原创 2015-10-05 12:32:15 · 289 阅读 · 0 评论 -
判断二叉树是否相等
如果两个二叉树根节点值相等,同时其左子树,右子树都相等,则两二叉树相等。// 判断两二叉树是否相等bool IsBiTreeEqual(BTNode* pRoot1, BTNode* pRoot2){ if (NULL == pRoot1 && NULL == pRoot2) return true; if (pRoot1 != NULL && NULL == pRoot原创 2015-10-02 22:54:42 · 915 阅读 · 0 评论 -
二叉树的深度
如果二叉树既没有左子树也没有右子树,深度为1。其余情况下二叉树的深度等于左右子树中较大的深度加上1。// 获取二叉树的深度int GetBiTreeDepth(BTNode* pRoot){ if (NULL == pRoot) return 0; if (NULL == pRoot->pLeft && NULL == pRoot->pRight) return 1;原创 2015-10-02 21:34:08 · 323 阅读 · 0 评论 -
二叉树的镜像
二叉树的镜像指的是将所有节点的左右子树互换,使用递归进行处理非常方便。void MirrorBiTree(BTNode* pRoot){ if (NULL == pRoot) return; // 左右子树不存在 if (NULL == pRoot->pLeft && NULL == pRoot->pRight) return; // 交换左右子树 BTNode*原创 2015-10-02 19:09:46 · 233 阅读 · 0 评论 -
遍历二叉树
二叉树遍历:访问节点:void Visit(BTNode* pNode){ std::cout nData << " ";}前序遍历:// 前序遍历(递归)void PreOrderTraverse1(BTNode* pRoot){ if (NULL == pRoot) return; Visit(pRoot); PreOrderTraverse1原创 2015-10-02 18:18:35 · 277 阅读 · 0 评论 -
二叉树创建
二叉树节点的结构如下:struct BTNode{ int nData; BTNode* pLeft; BTNode* pRight;};以前序方式进行二叉树的创建// 前序方式创建二叉树void CreateBiTree(BTNode* &pRoot){ int data; cin >> data; if (data == -1) { pRoot = N原创 2015-10-02 18:17:46 · 341 阅读 · 0 评论 -
倒置链表(递归方式)
前面已经有一个循环形式的。现在加一个递归形式。当然,如果循环形式的已经写出,递归也就信手拈来。源代码:struct ListNode{ int nData; ListNode* pNext;};ListNode* Reverse(ListNode* pPrev, ListNode* pCur){ if (NULL == pCur->pNext) { p原创 2015-10-14 20:04:19 · 878 阅读 · 0 评论 -
删除链表中相邻重复元素
删除链表中相邻元素,如1, 2, 3,3,4, 4操作之后得到1, 2, 3, 4代码:struct ListNode{ int nData; ListNode* pNext;};void Unique(ListNode* pHead){ // 链表无节点或者只有1个节点 if (NULL == m_pHead || NULL == m_pHead->原创 2015-10-11 15:57:39 · 684 阅读 · 0 评论 -
用两个栈实现队列
两个栈,一个称之为主栈,另外一个次栈。在主栈直接进行Push操作。次栈辅助进行Pop和Front操作。源代码:NewQueue.h#include class NewQueue{public: void Push(int data); void Pop(); int Front(); int Back(); bool Empty();private原创 2015-09-29 20:30:38 · 294 阅读 · 0 评论 -
使用链表实现队列
使用链表实现队列和堆栈不一样的地方在于:需要另外的一个指针指向队列尾部。每次Push()在链表尾部进行。每次Pop()则在链表头部进行。同样,在查看队列头尾元素时(Front()、Back()),对队列进行判空操作由调用者进行。源代码MyQueue.h#include struct ListNode{ int nData; ListNode* pN原创 2015-09-28 20:41:22 · 1377 阅读 · 0 评论 -
使用链表实现堆栈
链表实现堆栈比较简单。只需要在链表的头部进行push和pop即可。注意:pop和top操作需要由调用者进行判空操作,否则程序会崩溃。源代码:MyStack.h#include struct ListNode{ int nData; ListNode* pNext;};class MyStack{ public: MyStack() : m_pH原创 2015-09-28 17:49:09 · 775 阅读 · 0 评论 -
归并链表
归并链表是将两个链表合成一个链表,合并后的链表依旧有序(升序)。当然,前提是两个链表归并之前已经是有序的。好了,废话不多说。要是想了解MyList类的结构,请参考链表常用函数源代码:MyList.h void Merge(MyList& other); // 归并链表MyList.cppvoid MyList::Merge(MyList& other)原创 2015-09-27 22:29:06 · 597 阅读 · 0 评论 -
链表排序
这里的链表排序其实比较简单,就是从原链表中取出链首节点,按照排序规则(从小到大)插入到新的链表中。最后将链表的头指针指向新链表的头指针。源代码:ListNode.h void Sort(); // 排序(从小到大)ListNode.cppvoid MyList::Sort(){ if (NULL == m_pHead || NULL == m_pHea原创 2015-09-27 19:08:19 · 1911 阅读 · 0 评论 -
倒置链表
链表倒置的过程看似比较复杂,只要理解透彻其过程,其实还是蛮简单的。这里具体的过程就不叙述了。想要了解其实现机理,可以参考,其中有对链表倒置过程的详细分析。源代码:MyList.h void Reverse(); // 逆转链表MyList.cppvoid MyList::Reverse(){ if (NULL == m_pHead || NUL原创 2015-09-27 11:33:32 · 507 阅读 · 0 评论 -
链表的倒序输出
链表的倒序输出1. 可以将链表中原始依次存入栈中,然后依次弹出即可。2. 可以通过递归输出。这里只给出递归方式删除,当然是因为简单嘛!源代码:MyList.h void PrintReversely(); // 逆序输出MyList.cppvoid MyList::PrintReversely(ListNode* pNode){原创 2015-09-27 11:18:52 · 629 阅读 · 0 评论 -
链表常用函数
链表的常用操作包括:1. 插入(依序插入链尾)2. 查找3. 删除4. 打印输出5. 判空源代码如下:MyList.h#include struct ListNode{ int nData; ListNode* pNext;};class MyList{public: MyList() : m_pHead(NULL) {}原创 2015-09-27 11:09:14 · 610 阅读 · 0 评论 -
链表小思
革命工作不能停啊, 长期坚持才能出效果。这一段时间准备找工作,看了下书,链表的相关知识忘得差不多了。整理下思路,写点关于链表的东西。内容没什么深度,权当复习练手。原创 2015-09-26 21:43:54 · 253 阅读 · 0 评论 -
二叉树最小结构(C++版本)
二叉树节点类型为ListNodestruct BinaryTreeNode{ BinaryTreeNode(int newData) : data(newData), pLeft(nullptr), pRight(nullptr) {} int data; BinaryTreeNode* pLeft; BinaryTreeNode* pRight;};二叉树类型为MyBinar...原创 2019-12-11 10:38:01 · 1475 阅读 · 0 评论 -
C++ SkipList简单实现
SkipList.h:#pragma once#include <vector>struct SkipListNode{ SkipListNode(int data, int level); int m_data; std::vector<SkipListNode*> m_forward;};class SkipList{public: Ski...原创 2019-11-11 18:27:07 · 2209 阅读 · 0 评论 -
跳跃表原理
一、跳表的基本概念1、跳表的定义跳表(SkipList):增加了向前指针的链表叫做指针。跳表全称叫做跳跃表,简称跳表。跳表是一个随机化的数据结构,实质是一种可以进行二分查找的有序链表。跳表在原有的有序链表上增加了多级索引,通过索引来实现快速查询。跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。跳表是一个随机化的数据结构,可以被看做二叉树的一个变种,它在性能上和红黑树、AVL...转载 2019-11-08 17:31:36 · 6974 阅读 · 1 评论 -
为什么hashtable中桶的数目都是用质数表示
在查看hashtable源码的时候,我们会发现,hashtable的桶数全部使用的是质数,因为我们在hashtable的定义中,hash函数使用的是标准的求模函数,因此这样定义桶数有利于元素各个桶之间的均匀分布。例子:举一个有点极端的例子,假设我们的元素全是偶数1,4,6,8,10,12,14,1,6,18,20,22如果我们使用4个桶:0: 4,8,12,16.201:2:6,10,...转载 2019-11-06 10:00:37 · 3258 阅读 · 0 评论 -
哈希表
初入数据结构的哈希表(Hash Table)这次我们来总结一下关于哈希表的知识,首先我们要了解什么是哈希表,哈希函数的构造思路有哪些?怎么解决哈希冲突?最后再去分析一下哈希查找算法。哈希表的概念 前提小知识什么是哈希表?哈希表的四个概念关键字、值、哈希函数、哈希地址、哈希表之间的关系?什么是哈希冲突常见的哈希函数构造方法 怎么样才是好的哈希函数?常见构建哈希函数的六个方法...转载 2019-11-06 09:38:22 · 3279 阅读 · 0 评论