Q19 求二叉树的镜像
void MirrorRecursively(TreeNode* pNode)
{
if(!pNode || (!pNode->left && !pNode->right)
return;
TreeNode* pmid = NULL;
pmid = pNode->right;
pNode->right = pNode->left;
pNode->left = pmid;
if(pNode->left)
MirrorRecursively(pNode->left);
if(pNode->right)
MirrorRecursively(pNode->right);
}
Q20 顺时针打印矩阵
用递归来解决,从右上角第一个数(index,index)来标识相应的圈;
int main()
{
void PrintMatrixClockwisely(int **numbers, int col, int row);
int col = 4, row = 5; // 生成二维数组
int **a = new int*[col];
for (int i = 0; i < col;++i)
{
a[i] = new int[row];
for (int j = 0; j < row; ++j )
a[i][j] = i + j*2;
}
for(int i = 0; i< col;++i) // 打印生成的二维数组
{
for(int j = 0; j < row; ++j)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
PrintMatrixClockwisely(a,col,row); // 顺时针打印
}
void PrintMatrixOuter(int **numbers,int col,int row,int index);
void PrintMatrixClockwisely(int **numbers, int col, int row)
{
if(numbers==NULL || col <= 0|| row <= 0)
return;
int index = 0;
PrintMatrixOuter(numbers,col,row,index); // 递归依次打印最外一圈的数据
}
void PrintMatrixOuter(int **numbers,int col,int row,int index)
{
if(col <= 0 || row <= 0) // 递归退出条件
return;
// 最后肯定是只剩下1行n列或是2行m列
int i, j;
// 打印最上一行
for (i = index,j = index; j <= index+row-1;++j)
cout<< numbers[i][j]<<" ";
// 打印最右一列
if(row >= 1) // 这里要=1因为如果是只有一列的话可以直接打印
for(i = index+1,j = index+row-1; i <= index+col-1; ++i)
cout<< numbers[i][j]<<" ";
// 打印最下一行
if(col > 1)
for(i = index+col-1,j = index+row-2; j >= index; --j)
cout<< numbers[i][j]<<" ";
// 打印最左一列
if(row >1)
for(i = index+col-2,j = index; i > index; --i)
cout<< numbers[i][j]<<" ";
cout<<endl;
PrintMatrixOuter(numbers,col-2,row-2,++index);
}
Q21 包含min函数的栈
功能是实现:push, pop 时间复杂度0(1),min函数时间复杂度也为0(1)
过程:
用两个栈,一个用于正常的push, pop,另一个辅助栈用于压入与删除当前最小值;
即每次压入一个值时,将最小值也压入,每次删除一个值时,将辅助栈当前的栈顶也删除;
Q22 判断栈的弹出序列
如压栈序列是1 2 3 4 5,则4 5 3 2 1是其一个弹出序列,而 4 5 2 3 1不是其弹出序列;
解决:
1. 弹出栈的当前值为4,而栈顶当前为空值不为4,则将还未入栈的值一直往里面压,直到找到4;
2. 弹出栈的当前值为5, 而栈顶值不为5,继续压入栈,直到找到5;
...
如果所有的数都压入栈还没找到当前值,则说明该序列不是弹出序列;
如果弹出序列的最后一个值也从栈中或是未压入的序列中找到,则说明是弹出序列;
bool IsPopOrder(cinst int* bPush,const int* bPop,const int len)
if bPush == NULL || bPop == NULL || len <= 0
return false;
int *pPush = bPush, *pPop = bPop;
bool isPopOrder = false;
stack<int>stackData;
while(pPop - bPop < len) // 没有越界
while(stackData.empty() || stackData.top() != *pPop || pPush < bPush + len)
stackData.push(*pPush++);
// 上面循环退出时,栈顶元素与当前值相等的或是已经全部找完
if(pPush = bPush + len) // 越界
break;
// 否则是栈顶元素与弹出值相等
stackData.pop();
++bPop;
if(stackData.empty() && pPop - bPop = len) // 最后是栈为空,pPop指向出界处
isPopOrder = true;
return isPopOrder;
Q24 判断某数组序列是二叉搜索树的后序排列
如:
5 7 6
9 11 10 8; 其中8为根结点,左子树为结点都<8,右子树结点都>8,递归进入左右子树再次判断;
递归结束条件:当前结点为叶子结点;
bool VerifySquenceOfPostBST(int sequen[],int len)
{
if(sequen==NULL || len < 0)
return false;
if(len == 1)
return true;
int rootVal = sequen[len-1];
int pos = 0;
for (;pos < len;++pos)
if(sequen[pos] > rootVal)
break; // 找到右子树的第一个数
for (int j = pos; j < len; ++j)
if(sequen[j] < rootVal)
return false; // 如果右子树中有存在比根值小的数则说明非二叉搜索树
// 这时,根结点的左右两边是满足二叉搜索树条件的
bool resLeft = true, resRight = true;
if(pos > 0)
resLeft = VerifySquenceOfPostBST(sequen,pos);
if(len - pos -1 > 0)
resRight = VerifySquenceOfPostBST(sequen,len-pos-1);
return resLeft&&resRight;
}
Q26 复杂链表的复制
下面的代码还未测试
// 复制结点
void CopyNode(ComplexListNode* pHead)
{
if(!pHead)
return;
ComplexListNode* pNode = pHead;
while(pNode)
{
ComplexListNode *cpyNode = new ComplexListNode;
cpyNode->val = pNode->val;
cpyNode->pNext = pNode->pNext;
cpyNode->pSibling = NULL;
pNode->pNext = cpyNode;
pNode = cpyNode->pNext;
}
}
// 连接另一结点
void CopySibling(ComplexListNode* pHead)
{
if(!pHead)
return;
ComplexListNode* pNode = pHead, *pCpyNode = pHead->pNext;
while(pNode) // 在非空原始结点的后面插入它的复制结点
{
pCpyNode->pSibling = pNode->pSibling->pNext;
pNode = pCpyNode->pNext;
pCpyNode = pCpyNode->pNext->pNext;
}
}
// 分离链表
ComplexListNode* DivList(ComplexListNode* pHead)
{
if(!pHead)
return NULL;
ComplexListNode* cpyHead = pHead->pNext, *pNode = pHead; // 复制链表的新头结点
ComplexListNode* pClone = cpyHead;
while(pClone->pNext) // 复制结点的下一个不为空
{
pNode->pNext = pClone->pNext; // 两个链表重新指向对应的结点
pNode = pNode->pNext;
pClone->pNext = pNode->pNext;
pClone = pClone->pNext;
}
// 达到最后 一个空结点
pNode->pNext = pClone->pNext;
pClone->pNext = NULL;
return cpyHead;
}
ComplexListNode* Clone(ComplexListNode* pHead) // 主调 函数
{
CopyNode(pHead);
CopySibling(pHead);
return DivList(pHead;)
}
Q27 二叉搜索树转换成排序的双向链表
二叉搜索树从小到大输出应该是按左中右输出的;因此将树转换成双向链表也应该是先获得左子树的链表,并返回尾结点指针;
这时,将根结点与尾结点之间形成双向链表,将这里的尾结点传递到右子树中;
在右子树中的过程与前面的一样,递归完成;
void convert(BTreeNode* root,BTreeNode** pLastLinkNode)
{
// 递归实现将左子树的链表与根结点相结合,并传递进右子树递归
// *pLastLinkNode为已经指向的双向链表的尾结点
if(root == NULL)
return;
if(root->left == NULL && root->right ==NULL) // 如果*pLastLinkNode已经指向了双向链表,则重新指向,否则直接赋值
{
if(*pLastLinkNode)
{
(*pLastLinkNode)->right = root;
root->left = *pLastLinkNode;
}
*pLastLinkNode = root;
return;
}
if(root->left != NULL) // 左子树不为空
convert(root->left,pLastLinkNode);
BTreeNode* pCur = root;
// 当前结点与左子树结合
root->left = *pLastLinkNode;
(*pLastLinkNode)->right = root;
*pLastLinkNode = root;
if(root->right != NULL)
convert(root->right,pLastLinkNode);
}
BTreeNode* BTreeToDouLink(BTreeNode* root) // left代表上一个结点,右代表下一个结点
{
if(!root)
return NULL;
if(root->left == NULL && root->right == NULL)
return root;
// 多于一个结点
BTreeNode* pLastLinkNode = NULL;
convert(root,&pLastLinkNode);
// pLastLinkNode该结点是双向链一有的最后一个结点,因此要获得头结点
BTreeNode* pListHead = pLastLinkNode;
while(pListHead->left != NULL)
pListHead = pListHead->left;
// 头尾结点的下一个置空
pListHead->left = NULL;
pLastLinkNode->right = NULL;
return pListHead;
}
Q29 打印出字符串的所有排列或组合
递归:循环当前位置的字符,递归打印循环下一字符
排列相对来说简单,这里不给出,下面给出所有组合的输出(字符串中
没有相同的字符的情况下)
组合
组合问题可以分解成这样:
组合问题可以分解成这样:
长度为n的ch = "abcdef";打印m个字符的组成;
该问题可以分解成:
1. 组合中包含当前的字符串的第一个字符,后面将是在n-1个字符里先m-1个字符组合;
2. 组合中不包含当前的字符串中的第一个字符,后面将是在n-1个字符里先出m个字符组合;
string str = ""; // 一个全局变量来保存当前的组合
int num = 0;<span style="white-space:pre"> </span>// 用来保存组合的个数
// 将长度为n的字符串ch里的m个字符的组合打印出来
void PrintConbinatio(char* ch, int m)
{
if(!ch || m < 0) // 输入边界判断
return;
// 递归结束判断
int len = strlen(ch);
if(len < m) // 剩余的字符串长度不够
return;
else if(len == m) // 剩余的字符个数与还要打印的个数相等
{
cout<<str + ch<<"第"<<++num<<"个" <<endl;
return;
}
else if(m == 0) // 所要打印的字符串长度已经够了
{
cout << str<<"第"<<++num<<"个" <<endl;
return;
}
string s = str;
str += *ch;
PrintConbinatio(ch+1,m-1); // 当前字符加入
str = s;
PrintConbinatio(ch+1,m); // 当前字符不加入
}
int main()
{
char* str = "abcde";
PrintConbinatio(str,3);
}