前言:搁置许久的更新要继续开始了!前一段时间一直在忙项目和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 = 0; i < 5; i++)
{
p = (linknode_t *)malloc(sizeof(linknode_t));
p->data = i+1;
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 == 0)
return NULL;
ListNode *pAhead = pListHead;
ListNode *pBehind = NULL;
for(unsigned int i=0;i<k-1;++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,2);
cout << "data:" << S->data << endl;
return 0;
}
总结:要熟练对单链表的使用!当我们用一个指针不能解决问题,可以尝试用两个指针遍历链表,可以让其中一个指针遍历的速度快一些(比如一次在链表上走两步),或者让它在链表上走若干步!
面试题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 = 0; i < 4; i++)
{
p = (linknode_t *)malloc(sizeof(linknode_t));
p->data = i+1;
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 0;
}
面试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=1) // 初始化一个空的链表
{
linknode_t *r, *p;
int i;
r = H; // r 指向 队尾位置
for(i = 0; i < 4; 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,2);
ShowLink(H);
ShowLink(H1);
linknode_t *S = Merge(H->next,H1->next);
while(S != NULL){
cout << " " << S->data;
S = S->next;
}
cout << endl;
return 0;
}
总结:理解递归部分的思想。
面试题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(2*i, max);
T->rchild = CreateTree(2*i+1, 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(1,4);
FirstRoot_DLR(T1);
cout << endl;
tree_t *T2 = CreateTree(1,2);
FirstRoot_DLR(T2);
cout << endl;
//使用boolalpha输出为bool类型
cout << boolalpha <<HasSubtree(T1,T2) << endl;
return 0;
}
总结:书中第三章主要强调了代码的规范性、完整性和鲁棒性,鲁棒性例如对空指针的判断和处理...,用链表和二叉树做的例子,要熟悉掌握这两种数据结构!
作者:
柳德维出处:
https://www.cnblogs.com/liudw-0215/-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ⁾⁾!