前言:搁置许久的更新要继续开始了!前一段时间一直在忙项目和C++的学习,所以搁置了!要改变注意了,要用C++进行编写了,因为要不断练习C++!
面试题15:
书中要求只能遍历链表一次,所以代码如下:
#include<iostream>
#include<cstdlib>
using namespace std; struct ListNode
{
int data;
ListNode * next;
}; typedef struct ListNode linknode_t;
typedef struct ListNode* linklist_t;
linknode_t *CreateLink() // 创建空的链表 返回值 链表的首地址
{
linknode_t *H;
H = (linklist_t)malloc(sizeof(linknode_t)); H->next = NULL;
return H;
}
void InitLink(linknode_t *H) // 初始化一个空的链表
{
linknode_t *r, *p;
int i;
r = H; // r 指向 队尾位置
for(i = ; i < ; i++)
{
p = (linknode_t *)malloc(sizeof(linknode_t));
p->data = i+;
p->next = NULL; // 没有下一个节点
r->next = p; // 将p 放在 r 的后面
r = p; // r 指向新的队尾
} } void ShowLink(linknode_t* H) // 从队首->队尾 打印所有节点
{
linknode_t *p;
p = H->next;
while(p != NULL){
cout << " " << p->data;
p = p->next;
}
cout << endl;
} ListNode *FindKthToTail(ListNode *pListHead,unsigned int k)
{
if(pListHead == NULL || k == )
return NULL; ListNode *pAhead = pListHead;
ListNode *pBehind = NULL; for(unsigned int i=;i<k-;++i)
{
if(pAhead->next != NULL)
pAhead = pAhead->next;
else
{
return NULL;
}
} pBehind = pListHead;
while(pAhead->next != NULL)
{
pAhead = pAhead->next;
pBehind = pBehind->next;
} return pBehind;
} int main()
{
linknode_t *H = CreateLink();
InitLink(H);
ShowLink(H); linknode_t *S = FindKthToTail(H,);
cout << "data:" << S->data << endl; return ;
}
总结:要熟练对单链表的使用!当我们用一个指针不能解决问题,可以尝试用两个指针遍历链表,可以让其中一个指针遍历的速度快一些(比如一次在链表上走两步),或者让它在链表上走若干步!
面试题16:
主要考察链表的反转:
代码如下:
#include<iostream>
#include<cstdlib>
using namespace std; struct ListNode
{
int data;
ListNode * next;
}; typedef struct ListNode linknode_t;
typedef struct ListNode* linklist_t;
linknode_t *CreateLink() // 创建空的链表 返回值 链表的首地址
{
linknode_t *H;
H = (linklist_t)malloc(sizeof(linknode_t)); H->next = NULL;
return H;
}
void InitLink(linknode_t *H) // 初始化一个空的链表
{
linknode_t *r, *p;
int i;
r = H; // r 指向 队尾位置
for(i = ; i < ; i++)
{
p = (linknode_t *)malloc(sizeof(linknode_t));
p->data = i+;
p->next = NULL; // 没有下一个节点
r->next = p; // 将p 放在 r 的后面
r = p; // r 指向新的队尾
} } void ShowLink(linknode_t* H) // 从队首->队尾 打印所有节点
{
linknode_t *p;
p = H->next;
while(p != NULL){
cout << " " << p->data;
p = p->next;
}
cout << endl;
} ListNode *ReverseList(ListNode *pHead)
{
ListNode *pReversedHead = NULL;
ListNode *pNode = pHead;
ListNode *pPrev = NULL;
while(pNode != NULL)
{
ListNode *pNext = pNode->next; if(pNext == NULL)
pReversedHead = pNode; pNode->next = pPrev;
pPrev = pNode;
pNode = pNext;
} return pReversedHead;
} int main()
{
linknode_t *H = CreateLink();
InitLink(H);
ShowLink(H); linknode_t *S = ReverseList(H);
ShowLink(S); return ;
}
面试17:
题目如下:
代码如下:
#include<iostream>
#include<cstdlib>
using namespace std; struct ListNode
{
int data;
ListNode * next;
}; typedef struct ListNode linknode_t;
typedef struct ListNode* linklist_t;
linknode_t *CreateLink() // 创建空的链表 返回值 链表的首地址
{
linknode_t *H;
H = (linklist_t)malloc(sizeof(linknode_t)); H->next = NULL;
return H;
}
void InitLink(linknode_t *H,int n=) // 初始化一个空的链表
{
linknode_t *r, *p;
int i;
r = H; // r 指向 队尾位置
for(i = ; i < ; i+=n)
{
p = (linknode_t *)malloc(sizeof(linknode_t));
p->data = i+n;
p->next = NULL; // 没有下一个节点
r->next = p; // 将p 放在 r 的后面
r = p; // r 指向新的队尾
} } void ShowLink(linknode_t* H) // 从队首->队尾 打印所有节点
{
linknode_t *p;
p = H->next;
while(p != NULL){
cout << " " << p->data;
p = p->next;
}
cout << endl;
} ListNode *Merge(ListNode *pHead1,ListNode *pHead2)
{
//鲁棒性处理,空指针会造成程序崩溃
if(pHead1 == NULL)
return pHead2;
else if(pHead2 == NULL)
return pHead1; ListNode * pMergedHead = NULL; if(pHead1->data < pHead2->data)
{
pMergedHead = pHead1;
pMergedHead->next = Merge(pHead1->next,pHead2);//递归处理
}
else
{
pMergedHead = pHead2;
pMergedHead->next = Merge(pHead1,pHead2->next);//递归处理
} return pMergedHead;
} int main()
{
linknode_t *H = CreateLink();
InitLink(H);
linknode_t *H1 = CreateLink();
InitLink(H1,);
ShowLink(H);
ShowLink(H1); linknode_t *S = Merge(H->next,H1->next);
while(S != NULL){
cout << " " << S->data;
S = S->next;
}
cout << endl; return ;
}
总结:理解递归部分的思想。
面试题18:
面试题18是关于二叉树的,先简单介绍一下二叉树吧。
二叉树特点: 第i层 最多节点的个数 2^(i-1)
树的深度 h , 树节点 最多 2^h-1
遍历二叉树方法:先序遍历 中序遍历 后序遍历,具体遍历方法介绍可以在网上找,这里就不具体介绍了。
程序中三种方法都写出来了,但只用了先序遍历。
题目如下:
代码如下:
#include<iostream>
#include<cstdlib>
using namespace std; struct BinaryTreeNode
{
int data; //节点数据
BinaryTreeNode *lchild,*rchild; //左孩子、右孩子
};
typedef struct BinaryTreeNode tree_t; /******
构造一个二叉树 递归实现
参数:形参1:开始值,形参2:结束值
******/
tree_t *CreateTree(int i, int max)
{
//递归结束条件
if(i > max)
{
return NULL; // == return 0;
} tree_t *T; T = (tree_t *)malloc(sizeof(tree_t)); T->data = i;
T->lchild = CreateTree(*i, max);
T->rchild = CreateTree(*i+, max);
return T;
} //先序遍历输出二叉树
void FirstRoot_DLR(tree_t *p)
{
if(p == NULL)
return ;
cout << " " << p->data;
FirstRoot_DLR(p->lchild);
FirstRoot_DLR(p->rchild);
} //中序遍历输出二叉树 程序中未使用
void MiddleRoot_DLR(tree_t *p)
{
if(p == NULL)
return; MiddleRoot_DLR(p->lchild);
cout << " " << p->data;
MiddleRoot_DLR(p->rchild);
} //后序遍历输出二叉树 程序中未使用
void LastRoot_DLR(tree_t *p)
{
if(p == NULL)
return; LastRoot_DLR(p->lchild);
LastRoot_DLR(p->rchild);
cout << " " << p->data;
} bool DoesTree1HaveTree2(tree_t *pRoot1,tree_t *pRoot2)
{
//树B为空直接不检查
if(pRoot2 == NULL)
return true; if(pRoot1 == NULL)
return false; if(pRoot1->data != pRoot2->data)
return false; return DoesTree1HaveTree2(pRoot1->lchild,pRoot2->lchild)&&DoesTree1HaveTree2(pRoot1->rchild,pRoot2->rchild);
} bool HasSubtree(tree_t *pRoot1,tree_t *pRoot2)
{
bool result = false; if(pRoot1!=NULL && pRoot2!=NULL)
{
result = DoesTree1HaveTree2(pRoot1,pRoot2);
if(!result)
HasSubtree(pRoot1->lchild,pRoot2);
if(!result)
HasSubtree(pRoot1->rchild,pRoot2);
}
return result;
} int main()
{
tree_t *T1 = CreateTree(,);
FirstRoot_DLR(T1);
cout << endl;
tree_t *T2 = CreateTree(,);
FirstRoot_DLR(T2);
cout << endl;
//使用boolalpha输出为bool类型
cout << boolalpha <<HasSubtree(T1,T2) << endl; return ;
}
总结:书中第三章主要强调了代码的规范性、完整性和鲁棒性,鲁棒性例如对空指针的判断和处理...,用链表和二叉树做的例子,要熟悉掌握这两种数据结构!
剑指offer例题分享--4的更多相关文章
-
剑指offer例题分享--8
前言:继续分享,加油! 面试题44: 代码如下: #include<iostream> #include<stdlib.h> using namespace std; int ...
-
剑指offer例题分享--7
前言:继续前面的分享... 面试题31: 代码如下: #include<iostream> #include<limits.h> using namespace std; bo ...
-
剑指offer例题分享--6
前言:继续整理例题,快速做完这部分,然后继续用C++去刷数据结构和算法的题. 面试题28: 代码如下: #include<iostream> #include<stdio.h> ...
-
剑指offer例题——跳台阶、变态跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 思路: n<=0时,有0种跳法 n=1时,只有一种跳法 n=2时,有 ...
-
剑指offer 例题
题目: 实现一个排序算法,排序对象是本公司员工的年龄.要求时间复杂度O(n),空间复杂度不能超过O(n). #include<iostream> using namespace std; ...
-
剑指offer例题——反转链表
题目描述 输入一个链表,反转链表,输出新链表的表头 程序编写 将链表反转 public class Solution { public ListNode ReverseList(ListNode he ...
-
剑指offer例题——链表中倒数第K个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 编程过程 此处采用两个指针依次后移的方法来求解,首先,用一个指针移到第k个位置,之后将第二个指针放在第一位,与第二个指针一同移动,当第二个指针移动 ...
-
剑指offer例题——二进制中1的个数
题目:输入一个整数,输出该二进制表示中1的个数.其中负数用补码表示. 首先明确补码的定义: 原码 反码 补码 将最高位作为符号位(0表示正,1表示负), 其它数字位表达数值本身的绝对值的数字表示方式 ...
-
剑指offer例题——用两个栈实现队列
题目:用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 首先是概念理解,栈和对列存取的区别 栈(stack)是一种后进先出(last in first out, LI ...
随机推荐
-
shortcuts on Windows and MacOS
我现在使用Window 10与MacOS,发现各千秋,也发现Window向MacOS学习并借鉴了一些东西. MacOS有一点非常好的地方是,它可以不怎么使用鼠标,而通过TouchPad便可完成.体验起 ...
-
noi题库(noi.openjudge.cn) 1.7编程基础之字符串T21——T30
T21:单词替换 描述 输入一个字符串,以回车结束(字符串长度<=100).该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写.现需要将其中的某个单词替换成另一个单词,并输出替 ...
-
ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 D. Delay Time
Problem D. Delay Time Input file: standard input Output file: standard output Time limit: 1 second M ...
-
【07_226】Invert Binary Tree
Invert Binary Tree Total Accepted: 54994 Total Submissions: 130742 Difficulty: Easy Invert a binary ...
-
ReactNative学习实践--动画初探之加载动画
学习和实践react已经有一段时间了,在经历了从最初的彷徨到解决痛点时的兴奋,再到不断实践后遭遇问题时的苦闷,确实被这一种新的思维方式和开发模式所折服,react不是万能的,在很多场景下滥用反而会适得 ...
-
java数据结构之二叉树的实现
java二叉树的简单实现,可以简单实现深度为n的二叉树的建立,二叉树的前序遍历,中序遍历,后序遍历输出. /** *数据结构之树的实现 *2016/4/29 * **/ package cn.Link ...
-
MyEclipse 2014去除derby
在MyEclipse安装目录下打开configuration\org.eclipse.equinox.simpleconfigurator\bundles.info 搜索derby找到com.genu ...
-
c# ProxyServer 代理服务器 不是很稳定
/**C# Programming Tips & Techniquesby Charles Wright, Kris Jamsa Publisher: Osborne/McGraw-Hill ...
-
AsnycTask的内部的实现机制
AsnycTask的内部的实现机制 写在前面 我们为什么要用AsnycTask. 在Android程序开始运行的时候会单独启动一个进程,默认情况下所有 这个程序操作都在这个进程中进行.一个Androi ...
-
mysql无密码登陆
mysql登陆不上或者密码忘记可以尝试一下无密码登陆 以下一波神操作!! 首先关闭数据库服务(数据库在Centos7版本以上或者Redhat版本上被改名为mariadb) systemctl stop ...