1 出栈&入栈问题

一个栈的入栈序列为ABCDE,则不可能的出栈序列为?(不定项选择题)
A:ECDBA  B:DCEAB   C:DECBA   D:ABCDE   E:EDCBA

正确答案是:AB

解析如下:

首先,入栈与出栈是交错进行的,也就是A入栈后可能立马就出栈了。也可能A、B都入栈后,再让B出栈。

  • 选项A:A入,B入,C入,D入,E入。想要出栈顺序为ECD,那么E要先出,也就是E必须是最后一个入栈,第一个出栈的,那么CD先后出栈的情况是不存在的。即选项A为false;
  • 选项B:A入,B入,C入,D入,D出,C出,E入,E出,B出,A出,也就是说,按照DCE的顺序,最后出栈的应该是BA才对。即选项B为false;
  • 选项C:A入,B入,C入,D入,D出,E入,E出,C出,B出,A出,即选项C为true;
  • 选项D:A入,A出,B入,B出,C入,C出,D入,D出,E入,E出,即选项D为true;
  • 选项E:A入,B入,C入,D入,E入,E出,D出,C出,B出,A出,即选项E为true。

故,选项A与B是不可能出现的。

2 计算完全二叉树的叶子数目

一个完全二叉树有770个节点,那么其叶子的个数为 :_____?

解析:对于一个完全二叉树,如果总结点数为偶数,则度为 1 的结点数为1,如果总结点数为奇数且大于 1,则度为 1 的结点数为 0;而总结点数 770 为偶数,所以度为 1 的结点数 n1 = 1;度为 0 的结点数与度为 2 的结点数:n0 = n2 + 1;所以总结点数:n0+n1+n2 = 2n0 - 1 + 1 = 770,所以n0 = 385,即叶子结点的个数。

3 怎么判断链表中是否有环?

有多种思路可以解决,这里我们只介绍快慢指针法

首先我们要理解什么是快慢指针。快指针 fast 每次移动 2 个节点,慢指针 slow 每次移动 1 个节点,如果快指针能够追上慢指针,那就说明其中有一个环,否则不存在环。

// 快慢指针法
int testLinkRing(LinkList *head)
{
LinkList *slow = head, *fast = head;
while (slow->next && fast->next)
{
slow = slow->next;
if (NULL == (fast = fast->next->next))
return 0; //无环
if (slow == fast)
return 1; //有环
} return 0;
}

4 返回链表倒数第N个节点

5 删除链表中的重复项

采用三个指针来进行遍历,同时删除重复的节点,因为是有序的链表,我们就可以确定,重复的元素肯定是在一块链接,所以我们就可以,用三指针,我们这里就叫 pre、cur、next 分别代表的是前中后三个指针,我们在考虑的情况中,如果头节点开始就重复,我们就处理很起来多了一种情况就需要额外处理,所以我们添加一个头节点,变成带头节点,保证了头节点开始不会重复,那么我们就可以让 pre 指向带头的节点,cur 指向 pre 的next,nex 指向 cur 的next。

接下来我们就可以看 cur 是否和 nex 相等,相等就让 next 继续向下走,不相等然后再处理删除,cur 开始到 next 中间节点都是要删除的(包含 cur 指向,不包含 next 指向)删除,就用到了 pre,删除完成让 pre 指向 cur 就可以了。

如果 cur 值与 next 值不相等,那么就可以三个指针各自往前移动一个。

ListNode* deleteDuplication(ListNode* pHead)
{
// 先判断空
if (pHead == NULL)
{
return NULL;
}
// 判断是否只有一个节点
if (pHead->next == NULL)
{
return pHead;
}
// 我们采用带头链表,自己添加一个头
ListNode* pre = new ListNode();
pre->next = pHead; // 把头节点链接在链表上
ListNode* pre_head = pre; // 用来保存头节点,用于返回删除后的链表
ListNode* cur = pHead; //中指针
ListNode* nex = pHead->next; // 后面指针
while (nex != NULL) // 结束条件
while (nex != NULL && cur->val == nex->val)
{
nex = nex->next;
}
// 如果没有重复的那么cur的next一定等于nex
if (cur->next != nex) // 如果相等说明没有相同的节点
{
while (cur != nex) // 删除动作
{
pre->next = cur->next;
delete cur;
cur = pre->next;
}
if (nex != NULL) // 这里一定要要注意,要防止走到NULL发生段错误
nex = nex->next;
}
else
{
// 处理没有重复的情况
pre = cur;
nex = nex->next;
cur = cur->next;
}
}
ListNode* head = pre_head->next; // 释放空间,防止内存泄漏
delete pre_head;
return head;
}

6 根据要求写出函数(链表相关)。

有两个双向循环链表 A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中 data 值相同的结点删除。

typedef struct node
{
int data;
struct node *prior,*next;
}LinkNode; void deleteSame(LinkNode *pHeadA, LinkNode *pHeadB)
{
// 判断链表是否存在
if(!pHeadA || pHeadB)
{
printf("链表不存在!\n");
return;
} // 双层遍历链表
int breakFalg = 0; // 用于跳出第一层循环
LinkNode *curA = pHeadA->next;
while(curA != pHeadA)
{
LinkNode *curB = pHeadB->next;
while(curB != pHeadB)
{
if(curB->data == curA->data)
{
// 删除A节点
if(curA->next != NULL)
curA->next->prior = curA->prior;
curA->prior->next = curA->next;
free(curA);
curA = NULL; // 删除B节点
if(curB->next != NULL)
curB->next->prior = curB->prior;
curB->prior->next = curB->next;
free(curB);
curB = NULL; breakFalg = 1;
break;
} curB = curB->next;
} if(breakFalg == 1)
break; curA = curA->next;
}
}

7 二叉树的3种非递归遍历方法

1. 前序遍历的非递归实现

运用了一个栈结构实现。先序遍历的遍历顺序为根节点-->左孩子-->右孩子,所以往栈中放数时先放右孩子,在放左孩子(左右孩子都不为空的情况下)。根据栈的先进后出的性质,所以先打印左孩子再打印右孩子,但是有的人可能会有疑问,那根节点呢。根节点在往栈中放左右孩子的时候就已经打印完了,所以根节点肯定在左右孩子打印之前就打印完了。这样打印顺序就为:根节点-->左孩子-->右孩子。

实现代码如下:

// 前序遍历(非递归方式)
void preorder(BiTree *T)
{
// 判断二叉树是否存在
if (T == NULL)
return; stack<BiTree *> stack; // 利用栈结构实现
stack.push(T); // 将头节点放入栈中去
while (!stack.empty())
{
T = stack.top(); // T指向弹出剩下后的最顶端结点
stack.pop();
printf("%c", T->data); // 显示结点数据,可以更改为其它对结点操作
if (T->rchild != NULL) // 如果右孩子不为空,先放右孩子.
stack.push(T->rchild);
if (T->lchild != NULL) // 如果左孩子不为空,后放左孩子,这样才能保证打印顺序为:头节点-->左孩子-->右孩子
stack.push(T->lchild);
}
}

代码执行过程如下图所示:

2. 中序遍历的非递归实现

运用了一个栈结构实现。如果当前节点不为空,就往栈中放入该节点,然后让指向该节点的指针指向该节点的左孩子。如果当前节点为空,就弹出栈顶的节点,打印。然后让指向该节点的指针指向该节点的右孩子。

实现代码如下:

// 中序遍历(非递归方式)
void inorder(BiTree *T)
{
// 判断二叉树是否存在
if (T == NULL)
return; stack<BiTree *> stack; // 利用栈结构实现
while (!stack.empty() || T != NULL) // 这两个条件只要满足一个,就执行下面过程
{
if (T != NULL) // 如果当前节点不为空,就把当前节点放入栈中去,然后让head指向当前节点的左节点,没有打印过程
{
stack.push(T);
T = T->lchild;
}
else if (T == NULL) // 如果当前节点为空,那么就弹出栈顶的元素,打印。然后让head指向栈顶节点的右节点
{
T = stack.top();
stack.pop();
printf("%c", T->data); // 显示结点数据,可以更改为其它对结点操作
T = T->rchild;
}
}
}

代码执行过程如下图所示:

上面圈的那两个状态是一样的,所以没写的部分和上层圈的那个状态后面的状态是一样的(只不过一个是左子树,一个是右子数)

3. 后序遍历的非递归实现

运用了一个栈结构和 vector 结构实现。最先将根节点数据插入在 vector 的位置 0,然后插入左子树的节点数据在位置0(造成逆序),再插入右子树的节点数据在位置0(也是逆序)。

实现代码如下:

//后序遍历(非递归方式)
void postorder(BiTree *T)
{
// 判断二叉树是否存在
if (T == NULL)
return; stack<BiTree *> stack;
vector<ElemType> vec;
stack.push(T); BiTree *p = nullptr;
while (!stack.empty())
{
p = stack.top();
stack.pop();
vec.insert(vec.begin(), p->data); // 一直在位置0插入,则根节点会在vector的最末尾(相当于逆序插入)
if (p->lchild)
stack.push(p->lchild);
if (p->rchild)
stack.push(p->rchild);
} for (int i = 0; i < vec.size(); i++)
printf("%c", vec[i]);
}

参考:

如何检测链表中是存在循环

删除链表中重复的节点(经典链表面试题)

二叉树的3种遍历方法 6种实现

[C++进阶] 数据结构与算法的更多相关文章

  1. 学习JavaScript数据结构与算法---前端进阶系列

    学习建议 1.视频学习---认知 建议:在中国慕课上找"数据结构"相关的视频教程.中国大学MOOC 推荐清华大学.北京大学.浙江大学的教程,可先试看,然后根据自身的情况选择视频进行 ...

  2. Java进阶专题(十六) 数据结构与算法的应用(上)

    前言 ​ 学习算法,我们不需要死记硬背那些冗长复杂的背景知识.底层原理.指令语法--需要做的是领悟算法思想.理解算法对内存空间和性能的影响,以及开动脑筋去寻求解决问题的最佳方案.相比编程领域的其他技术 ...

  3. 数据结构与算法 C++ 视频教程(4 套)百度网盘

    为了大二有实力参加算法比赛,大一暑假我选择了留校,提前学习了一下数据结构和算法,这是我找的一些视频资源,分享给大家! 分别是 慕课网 玩转算法与数据结构.慕课网 玩转算法面试.慕课网 玩转数据结构 从 ...

  4. 开启基本数据结构和算法之路--初识Graphviz

    在我的Linux刀耕开荒阶段,就想开始重拾C,利用C实现常用的基本数据结构和算法,而数据结构和算法的掌握的熟练程度正是程序的初学者与职业程序员的分水岭. 那么怎么开启这一段历程呢? 按照软件工程的思想 ...

  5. 【转】MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  6. [转]MySQL索引背后的数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  7. MySQL索引背后的数据结构及算法原理【转】

    本文来自:张洋的MySQL索引背后的数据结构及算法原理 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持 ...

  8. 数据结构与算法JavaScript (一) 栈

    序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...

  9. 数据结构与算法 Big O 备忘录与现实

    不论今天的计算机技术变化,新技术的出现,所有都是来自数据结构与算法基础.我们需要温故而知新.        算法.架构.策略.机器学习之间的关系.在过往和技术人员交流时,很多人对算法和架构之间的关系感 ...

随机推荐

  1. Oracle的创建表空间及用户

    学习笔记: 1.创建表空间 --创建表空间 create tablespace thepathofgrace datafile 'c:\thepathofgrace.dbf' size 100m au ...

  2. 构造命题公式的真值表--biaobiao88

    对给出的任意一个命题公式(不超过四个命题变元),使学生会用C语言的程序编程表示出来,并且能够计算它在各组真值指派下所应有的真值,画出其真值表. #include<iostream> usi ...

  3. 搞Jedis案例出现问题,有大佬帮我看看怎么解决吗?先感谢大佬点进来看了---Day31

    今天学了Jedis的相关内容,然后做了一个案例,但是出现了错误,然后我百度了一晚上没有解决,想到看看发个博客能不能有大佬帮我看一下问题出现在哪里,百度了一晚上有点懵逼.求大佬帮我解决,在这小弟我先万分 ...

  4. vue 利用路由跨页传参

    第一页,点击进入第二页进行传值: <template> <div id="app"> <div><router-link to=" ...

  5. 推荐收藏 —— MySQL视图详细介绍

    前言:  在MySQL中,视图可能是我们最常用的数据库对象之一了.那么你知道视图和表的区别吗?你知道创建及使用视图要注意哪些点吗?可能很多人对视图只是一知半解,想详细了解视图的同学看过来哟,本篇文章会 ...

  6. tomcat server.xml 中 host 元素

    测试偶然发现: <Host name="127.0.0.1" appBase="webapps" unpackWARs="true" ...

  7. <code> 标签 让一段计算机代码显示在网页中

    <code> 标签 解释:要让一段计算机代码显示在网页中,那么这段代码需要用<code> 标签包起来,不然他会被当作网页的代码被 运行. 例如: <code>< ...

  8. Iconfont技术

    什么是 IconFont 顾名思义,IconFont 就是字体图标.严格地说,就是一种字体,但是,它们不包含字母或数字,而是包含符号和字形.您可以使用 CSS 设置样式,就像设置常规文本一样,这使得 ...

  9. JDK1.8 LocalDate 使用方式;LocalDate 封装Util,LocalDate工具类(二)

    未完待续 ........ java.time.*代替方案 1.Instant 代替 Date2.LocalDateTime 代替 Calendar3.DateTimeFormatter 代替 Sim ...

  10. oneinstack——证书更新

    如果你安装好 oneinstack 你的定时任务就会自动添加 "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh ...