剑指offer二叉树等的操作(第四章)

16 篇文章 0 订阅

   今天把剑指offer第四章的内容学习了遍,按照自己的理解,编写代码如下:


#include <iostream>
#include <stack>
#include <string>
#include <regex>
#include <math.h>
using namespace std;

//面试题21:包含min函数的最小栈
template<class T>
class my_stack
{
public:
	void push(T t)
	{
		if(s1.empty())
		{
			s1.push(t);
			s2.push(t);
		}
		else
		{
			s1.push(t);
			if(t<=s2.top())
			{
				s2.push(t);
			}
		}
	}
	void pop()
	{
		if(s1.empty())
		{
			cout<<"error"<<endl;
			return;
		}
		if(s1.top()==s2.top())
		{
			s1.pop();
			s2.pop();
		}
		else
		{
			s1.pop();
		}
	}

	T min()   //返回最小值
	{
		if(s2.size()==0)
		{
			cout<<"error"<<endl;
			return NULL;
		}
		return s2.top();
	}
private:
	stack<T> s1;   //主栈
	stack<T> s2;   //辅助栈
};

//面试题22:求栈的压入和弹出栈序列
class push_pop
{
public:
	bool  IspopOrder(int *popOrder,int *pushOrder,int length)
	{
		if(popOrder==nullptr||pushOrder==nullptr||length<=0)
			return false;
		int i=0,j=0;
		for(;;)
		{
			if(!s1.empty()&&j<length&&popOrder[j]==s1.top()) //防止地址访问出界
			{
				j++;
				s1.pop();
			}
			if(s1.empty()||popOrder[j]!=s1.top())
			{
				if(i>=length)
					break;
				s1.push(pushOrder[i]);
				i++;
			}					
		}
		if(i==length&&j==length)
			return true;
		else
			return false;
	}
private:
	stack<int> s1;
	//stack<int> s2;
};

//模拟正则表达式匹配
class  my_regexp
{
public:
	bool Match(char* str,char* pattern) //自定义正则表达式匹配
	{
		if(str==nullptr||pattern==nullptr)
			return false;
		while(*str!='\0'&&*pattern!='\0')
		{
			if(*(pattern+1)=='*')
			{
				if(*str==*pattern||*pattern=='.')
				{
					while(*str==*pattern||*pattern=='.')
					{
						if(Match(str,pattern+2))
							return true;
						str++;
					}
				}
				else
				{
					pattern=pattern+2;
				}
			}
			else
			{
				if(*str==*pattern||*pattern=='.')
				{
					str++;
					pattern++;
				}
				else
					return false;
			}
		}
		if((*str!='\0'&&*pattern=='\0')||(*str=='\0'&&*pattern!='\0'))
			return false;
		return true;
	}
	bool _Match(char* str,char* pattern)  //运用库函数的正则表达式 
	{
		regex p(pattern);
		smatch m;
		string s(str);
		regex_match(s,m,p);
		cout<<m.str()<<endl;
		if(m.str()==s)
			return true;
		else
			return false;
	}
};

//二叉树的结点
struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

//面试题23:从上往下打印二叉树
class print_tree
{
public:
	void create_tree(BinaryTreeNode* &header)
	{
		int num=0;
		cin>>num;
		if(num==-1)
		{
			header=nullptr;
		}
		else
		{
			header=new BinaryTreeNode;
			header->m_nValue=num;
			cout<<num<<"的左孩子为:"<<endl;
			create_tree(header->m_pLeft);
			cout<<num<<"的右孩子为:"<<endl;
			create_tree(header->m_pRight);
		}
	}
	BinaryTreeNode* create(BinaryTreeNode** header)
	{
		int num=0;
		cin>>num;
		if(num==-1)
		{
			*header=nullptr;
		}
		else
		{
			BinaryTreeNode* tem=new BinaryTreeNode;
			header=&tem;
			(*header)->m_nValue=num;
			cout<<num<<"的左孩子为:"<<endl;
			create_tree((*header)->m_pLeft);
			cout<<num<<"的右孩子为:"<<endl;
			create_tree((*header)->m_pRight);
		}
		return *header;
	}

	void print(BinaryTreeNode *root) const
	{
		if(!root)
			return;
		deque<BinaryTreeNode> result;
		result.push_back(*root);
		while(!result.empty())
		{
			BinaryTreeNode tem=result.front();
			cout<<tem.m_nValue<<" ";
			result.pop_front();
			if(tem.m_pLeft)
				result.push_back(*tem.m_pLeft);
 			if(tem.m_pRight)
				result.push_back(*tem.m_pRight);
		}
	}
};

//面试题25:二叉树中和为某一值的路径
class FindPath
{
public:
	void find_path(BinaryTreeNode* root,int current,int values)
	{
		int current_value=current;
		bool isleaf=false;

		current_value+=root->m_nValue;
		path.push_back(root->m_nValue); //把当前结点加入路径中
		if(root->m_pLeft==nullptr&&root->m_pRight==nullptr)
			isleaf=true;
		if(isleaf&&values==current_value)
		{
			cout<<"one path's:"<<endl;
			for(size_t i=0;i<path.size();i++)
				cout<<path[i]<<"-->";
			cout<<"NULL"<<endl;
		}
		if(root->m_pLeft!=nullptr)
			find_path(root->m_pLeft,current_value,values);
		if(root->m_pRight!=nullptr)
			find_path(root->m_pRight,current_value,values);
		path.pop_back();
	}
private:
	vector<int> path;
};

//面试题26:复杂链表的复制
//1、暴力解法,O(n^2),通过从头遍历来找到m_pSibling;
//2、以空间换时间,通过维护一个当前点和m_pSibling的映射表,可以快速定位m_pSibling,时间复杂度O(n);
//3、(巧妙解法)如下代码
//复杂链表的数据结构
struct ComplexListNode
{
public:
	char m_nValue;
	ComplexListNode* m_pNext;
	ComplexListNode* m_pSibling;
};
class clone_ComplexListNode
{
private:
	ComplexListNode* header;
public:
	clone_ComplexListNode()  //为了方便创建我用连续空间的数组来代替链表,其实链表空间不一定是连续的
	{
		ComplexListNode* p=new ComplexListNode[5];
		p[0].m_nValue='A';
		p[0].m_pNext=p+1;
		p[0].m_pSibling=p+2;

		p[1].m_nValue='B';
		p[1].m_pNext=p+2;
		p[1].m_pSibling=p+4;

		p[2].m_nValue='C';
		p[2].m_pNext=p+3;
		p[2].m_pSibling=nullptr;

		p[3].m_nValue='D';
		p[3].m_pNext=p+4;
		p[3].m_pSibling=p+1;

		p[4].m_nValue='E';
		p[4].m_pNext=nullptr;
		p[4].m_pSibling=nullptr;

		header=p;
	}
	void clone()
	{
		_clone(header);
		_clone_Sibling(header);
		_spart_List(header);
	}

private:
	void _clone(ComplexListNode* header)   //每个节点复制一个新的节点,接在该节点的后面
	{
		while(header!=nullptr)
		{
			ComplexListNode* tem=header->m_pNext;
			ComplexListNode* new_node=new ComplexListNode;
			new_node->m_nValue=header->m_nValue;
			header->m_pNext=new_node;
			new_node->m_pNext=tem;
			header=tem;
		}
	}
	void _clone_Sibling(ComplexListNode* header)
	{
		while(header!=nullptr)
		{
			if(header->m_pSibling!=nullptr)
				header->m_pNext->m_pSibling=header->m_pSibling->m_pNext;
			else
				header->m_pNext->m_pSibling=nullptr;
			header=header->m_pNext->m_pNext;
		}
	}
	void _spart_List(ComplexListNode* header)
	{
		ComplexListNode* start_node1=header;
		ComplexListNode* start_node2=header->m_pNext;
		while(true)   
		{	
			if(start_node2->m_pNext==nullptr)
			{
				start_node1->m_pNext=nullptr;
				break;
			}
			else
			{
				start_node1->m_pNext=start_node2->m_pNext;
				start_node2->m_pNext=start_node2->m_pNext->m_pNext;
				start_node1=start_node1->m_pNext;
				start_node2=start_node2->m_pNext;
			}
		}
		cout<<"row List is:"<<endl;
		ComplexListNode* tem=header;
		while(header!=nullptr)
		{
			if(header->m_pSibling)
				cout<<(header->m_nValue)<<","<<header->m_pSibling->m_nValue<<"-->";
			else
				cout<<(header->m_nValue)<<","<<"NULL"<<"-->";
			header=header->m_pNext;
		}
		cout<<"NULL"<<endl;

		cout<<"copy List is:"<<endl;
		while(tem!=nullptr)
		{
			if(tem->m_pSibling)
				cout<<(tem->m_nValue)<<","<<tem->m_pSibling->m_nValue<<"-->";
			else
				cout<<(tem->m_nValue)<<","<<"NULL"<<"-->";
			tem=tem->m_pNext;
		}
		cout<<"NULL"<<endl;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	clone_ComplexListNode  cl;
	cl.clone();
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值