1:将二叉查找树转化为排序的双向链表
要求不创建任何新的己节点,仅仅是改变指针的方向
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16
下面的是二叉树的节点
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
其实这个问题可以这样子想,我们可以以上面的那个例子为例,转换之后的双向链表为4,6,8,10,12,14,16,我们可以发现在10左边的元素都是原来二叉树中对应的左子树上的节点,
而10右边的元素都是原二叉树中对应的右子树上的节点,而上述节点的顺序正好是中序遍历二叉树时我们所需要走过的节点的顺序,同时在数据结构的课程上我们学过一种叫做线索二叉树的东西,这种二叉树说白了就是将左右子树为空的节点重新利用起来,指向其在某种遍历中的前驱节点或者是后继节点,那么这样的话,对于这个问题,我们完全可以采用中序遍历时建立线索二叉树的过程,来完成双向链表的建立,但是这里与建立中序 遍历线索二叉树不同的是,这里完全破坏了树的结构,因为在中序遍历中当节点的左子节点存在时我们是不做任何改变的,但是对于双向链表,我们会将其变成左子树的最右子节点的指针
struct node
{
int value;
node* p_Left;
node* p_Right;
};
typedef node* pnode;
pnode Covert(pnode root)
{
pnode prv=NULL;
CovertNode(root,&prv);
pnode Head=prv;
while(Head->P_Left!=NULL)
Head=Head->P_Left;
return Head;
}
void CovertNode(pnode& root,pnode* pre)
{
if(root!=NULL)
{
CovertNode(root->P_Left,pre);
if(*pre!=NULL)
{
root->P-Left=*pre;
*pre->P_Right=root;
}
*pre=root;
CovertNode(root->P_Right,pre);
}
}
2.设计包含min函数的栈。
定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O(1)。
这个问题是 剑指上的原题,在看剑指上的答案之前,我是这样想的,确实需要一个辅助栈这是肯定没问题的,关键在于往辅助栈中压入什么元素?我一开始想的是当压入的元素比当前辅助栈的栈顶元素小的时候我们什么也不做,只是把这个元素压入原来的栈就行了,只有在当辅助栈的栈顶元素小于要压入的元素的时候才真的将其也压入辅助栈,这样的话,就会出现辅助栈的长度可能小于真正的栈的长度,这个时候可能出现问题阿,因为可能在有限步之后由于栈顶元素的弹出使得辅助栈为空,而原本的栈却不为空,这样子肯定是错误的,所以我们需要保持两个栈的长度必须相同,那么当当前元素大于辅助栈的栈顶元素的时候我们只需要把辅助栈的栈顶元素再压入一次就行了,这样的话两个栈的长度相同,同时当 原数据栈的栈顶元素弹出的时候辅助栈的栈顶元素也弹出,两者不一定相等,但这个时候新的辅助栈的栈顶元素一定是 原数据栈中的当前最小元素
void push(int value)
{
m_data.push(value);
if(m_mindata.size()==0||value<=m_minsize.top())
m_mindata.push(value);
else
m_mindata.push(m_minsize.top());
}
void pop()
{
assert(m_data.size()>0);
m_data.pop();
m_min.pop();
}
int min()
{
assert(m_data.size()>0);
return m_mindata().top();
}
3.求子数组的最大和
这个问题我们可以利用动态规划的思想,假设f(i)保存的是以i为下标结尾的子数组的最大和,那么我们需要求的是max[f(i)],,而f(i)之间存在着下面的递推关系
当f(i-1)<0的时候,f(i)=data[i],否则会越加越小,当f(i-1)>=0的时候,f(i)=data(i)+f(i-1),这个时候最起码可以保证f(i)比data(i)大。
int FincThemaxsum(int *a ,int length)
{
if(a==NULL||lengthM=0)
exit(1);
int currentmaxsum=-1;
int maxsum=-INT_MAX;
for(int i=0;imaxsum)
maxsum=currentmaxsum;
}
return maxsum;
}