数组循环右移K位
【问题描述】将一个数组中的元素循环右移K位,要求只使用一个元素大小的附加存储空间,时间复杂度为O(n)。
【样例输入】
1 2 3 4 5 6 7 8 0
2
【样例输出】
7 8 1 2 3 4 5 6
【提示】0代表输入结束
#include<iostream>
#define N 1000
using namespace std;
void swap(int s[N], int front, int behind)
{
int temp = 0;
for( ; front < behind; front ++)
{
temp = s[front];
s[front] = s[behind];
s[behind] = temp;
behind --;
}
}
int main()
{
int s[N];
int i = 0;
int num = 0;
int len = 0;
for(i = 0; ; i ++) // 输入数组
{
cin>>num;
if(num == 0) break;
else
{
len ++;
s[i] = num;
}
}
int k = 0;
cin>>k;
k = k % len;
int j = len - k; //分割点
swap(s, 0, j - 1 );
swap(s, j, len - 1);
swap(s, 0, len - 1);
for(i = 0; i < len; i ++)
{
cout<<s[i]<<" ";
}
return 0;
}
二叉树的创建及遍历
【问题描述】
给出一个按照先序遍历得出的字符串,‘#’ 代表空的子节点,大写字母代表节点内容。请通过这个字符串建立二叉树,并分别采用“递归”和“非递归”的先序、中序、后序遍历的算法分别输出每一个非空节点。
【输入形式】
输入只有一行,包含一个字符串S,用来建立二叉树。保证S为合法的二叉树先序遍历字符串,节点内容只有大写字母,且S的长度不超过100。
【输出形式】
共有6行,每一行包含一串字符,表示分别按递归和非递归的先序、中序、后序遍历得出的节点内容,每个字母后输出一个空格。请注意行尾输出换行。
【样例输入】
ABC##DE#G##F###
【样例输出】
A B C D E G F
C B E G D F A
C G E F D B A
A B C D E G F
C B E G D F A
C G E F D B A
#include<iostream>
#include<stack>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct Bnode //定义二叉树节点
{
char data;
struct Bnode * LChild;
struct Bnode * RChild;
}BiTreeNode,*BiTree;
void CreatBt(BiTree * root) //创建二叉树
{
char s;
s = getchar();
if(s == '#')
{
*root = NULL;
}
else
{
*root = (BiTree)malloc(sizeof(BiTreeNode));
(*root)->data = s;
CreatBt(&(*root)->LChild);
CreatBt(&(*root)->RChild);
}
}
void RePreOder(BiTree root) //递归前序遍历
{
if(root == NULL)
{
return ;
}
else
{
cout<<root->data<<" ";
RePreOder(root->LChild);
RePreOder(root->RChild);
}
return ;
}
void ReInOrder(BiTree root) //递归中序遍历
{
if(root == NULL)
{
return ;
}
else
{
ReInOrder(root->LChild);
cout<<root->data<<" ";
ReInOrder(root->RChild);
}
return ;
}
void RePostOrder(BiTree root) //递归后序遍历
{
if(root == NULL)
{
return ;
}
else
{
RePostOrder(root->LChild);
RePostOrder(root->RChild);
cout<<root->data<<" ";
}
return ;
}
void PreOrder(BiTree root) //前序遍历
{
stack<BiTree> S; //元素定义为指针类型
while(root != NULL)
{
cout<<root->data<<" ";
S.push(root);
if(root->LChild != NULL)
{
root = root->LChild;
}
else if(!S.empty())
{
while(!S.empty())
{
root = S.top(); //无参有返回值
S.pop(); //无参无返回值
root = root->RChild;
if(root != NULL) break;
}
}
else
{
root = NULL;
}
}
}
void InOrder(BiTree root) //中序遍历
{
stack<BiTree> S;
while(root != NULL)
{
S.push(root);
if(root->LChild != NULL)
{
root = root->LChild;
}
else if(!S.empty())
{
while(!S.empty())
{
root = S.top();
S.pop();
cout<<root->data<<" "; //出栈顺序左根右
root = root->RChild;
if(root != NULL) break;
}
}
else
{
root = NULL;
}
}
}
void PostOrder(BiTree root) //后序遍历
{
stack<BiTree> S;
BiTree p = root;
BiTree q = NULL;
while(p != NULL || !S.empty())
{
while(p != NULL)
{
S.push(p);
p = p->LChild;
}
BiTree t = S.top();
if(t->RChild == NULL || t->RChild == q)
{
cout<<t->data<<" ";
S.pop();
q = t;
}
else
{
p = t->RChild;
}
}
}
int main()
{
BiTree root = NULL;
CreatBt(&root); //创建二叉树
RePreOder(root); //sting类传值,原string类不改变
cout<<endl;
ReInOrder(root);
cout<<endl;
RePostOrder(root);
cout<<endl;
PreOrder(root);
cout<<endl;
InOrder(root);
cout<<endl;
PostOrder(root);
return 0;
}
//总结:string类初始状态无空间,不可以s[0]这样使用
二叉树根据中序和后序求前序遍历
【问题描述】 根据一棵二叉树的中序遍历序列和后序遍历序列,求这棵树的前序遍历序列。
【输入形式】 一棵树的中序遍历序列和该树后序遍历序列。输入序列中仅含有小写字母,且没有重复的字母
【输出形式】 一棵树的前序遍历序列
【样例输入】
dbeafcg
debfgca
【样例输出】
abdecfg
#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
typedef struct Bnode
{
char data;
struct Bnode * LChild;
struct Bnode * RChild;
}BtNode,*BTree;
void CreatBt(BTree * root, string post, string in, int postleft, int postright, int inleft, int inright)
{
if(postleft > postright)
{
*root = NULL;
}
else
{
*root = (BTree)malloc(sizeof(BtNode));
(*root)->data = post[postright];
//cout<<(*root)->data<<" ";
int mid = 0;
while(in[mid] != post[postright])
{
mid ++;
}
CreatBt(&((*root)->LChild), post, in, postleft, postleft + mid - inleft - 1, inleft, mid -1);
CreatBt(&((*root)->RChild), post, in, postleft + mid - inleft, postright - 1, mid + 1, inright);
}
}
void PreOrder(BTree root)
{
if(root == NULL)
{
return ;
}
else
{
cout<<root->data;//root不为空才能输出
PreOrder(root->LChild);
PreOrder(root->RChild);
}
}
int main()
{
string post;
string in;
cin>>in;
cin>>post;
int len = post.length();
BtNode * root = NULL;
CreatBt(&root, post, in, 0, len - 1, 0, len - 1);
PreOrder(root);
}
二叉树结点的共同祖先问题
【问题描述】假设二叉树采用二叉链表方式存储,root指向根结点,p所指结点和q所指结点为二叉树中的两个不同结点,且互不成为根到该结点的路径上的点,编程求解距离它们最近的共同祖先。
【输入形式】二叉树的前序和中序遍历序列,用以创建该二叉树的链式存储结构;以及二叉树的两个结点数据 x 和 y
【输出形式】结点数据值为 x 和结点数据值为 y 的最近的共同祖先,若没有共同祖先则输出NULL,请注意一个结点本身不能成为另一个结点的共同祖先。
【样例输入】
GABDCEF
BDAEFCG
DF
【样例输出】
A
#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;
typedef struct node
{
char data;
struct node * LChild;
struct node * RChild;
}BtNode, *BTree;
void Creat(BTree * root, string Pre, string In, int preleft, int preright, int inleft, int inright)
{
if(inleft > inright)
{
*root = NULL;//此时二叉树没有节点,应该让指针为空
}
else
{
int mid = 0;
while(In[mid] != Pre[preleft])
{
mid ++;
}
*root = (BTree)malloc(sizeof(BtNode));
(*root)->data = Pre[preleft];
Creat(&((*root)->LChild), Pre, In, preleft + 1, preleft + mid - inleft, inleft, mid - 1);
Creat(&((*root)->RChild), Pre, In, preleft + mid - inleft + 1, preright, mid + 1, inright);
}
}
BTree Find(BTree root, BTree p, BTree q)
{
if(root == NULL) return NULL;
if(root->data == p->data || root->data == q->data) //NULL为假
{
return root;
}
BtNode * left = Find(root->LChild, p, q);
BtNode * right = Find(root->RChild, p, q);
if(!left && !right) return NULL;
else if(!left && right) return right;
else if(left && !right) return left;
return root;
}
void PreOrder(BTree root)
{
if(root == NULL)
{
return ;
}
else
{
cout<<root->data;
PreOrder(root->LChild);
PreOrder(root->RChild);
}
}
int main()
{
string Pre;
string In;
cin>>Pre;
cin>>In;
BtNode * root = NULL;
int len = Pre.length();
Creat(&root, Pre, In, 0, len - 1, 0, len - 1);
BtNode * p = (BTree)malloc(sizeof(BtNode));
BtNode * q = (BTree)malloc(sizeof(BtNode));
//PreOrder(root);
cout<<endl;
string s;
cin>>s;
p->data = s[0];
q->data = s[1];
//cout<<p->data<<q->data;
BtNode * res = Find(root, p, q);
if(res == NULL || res->data == root->data) cout<<"NULL";
else cout<<res->data;
return 0;
}
二叉树左右子树交换操作
【问题描述】二叉树按照二叉链表的方式存储。编写程序,计算二叉树中叶子结点的数目并输出;编写程序,将二叉树的每个结点的左、右子树进行交换,请注意不是只交换结点的data值,而是左、右孩子指针指向的交换,最后输出交换后的二叉树的后序遍历序列。
【输入形式】二叉树的前序遍历序列,空指针的位置输入字符#
【输出形式】叶子结点的数目;左右子树交换后,后序遍历的序列,空子树的位置输出字符#
【样例输入】
ABE##F##CG###
【样例输出】
3
###GC##F##EBA
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct node //建立二叉树节点
{
char data;
struct node * LChild;
struct node * RChild;
}BtNode, *BTree;
void CreatBt(BTree * root) //创建二叉树
{
char c;
c = getchar();
if(c == '#')
{
*root = NULL;
}
else
{
*root = (BTree)malloc(sizeof(BtNode)); //要申请空间的
(*root)->data = c;
CreatBt(&((*root)->LChild));
CreatBt(&((*root)->RChild));
}
}
int CountLeave(BTree root) //分治法求叶子数
{
int leave = 0;
if(root == NULL)
return 0;
else
{
if(root->LChild == NULL && root->RChild == NULL)
return 1;
else
return CountLeave(root->LChild) + CountLeave(root->RChild);
}
return leave;
}
void ChangeLR(BTree root)
{
if(root == NULL)
{
return ;
}
else
{
BTree temp = root->LChild;
root->LChild = root->RChild;
root->RChild = temp;
ChangeLR(root->LChild);
ChangeLR(root->RChild);
}
return ;
}
/*void Addheight(BTree * root)
{
if(*root == NULL)
{
*root = (BTree)malloc(sizeof(BtNode));
(*root)->data = '#';
(*root)->LChild = NULL;
(*root)->RChild = NULL;
return ;
}
else
{
Addheight(&((*root)->LChild));
Addheight(&((*root)->RChild));
}
}*/
void PostOrder(BTree root)
{
if(root == NULL)
{
cout<<'#';
return ;
}
else
{
PostOrder(root->LChild);
PostOrder(root->RChild);
cout<<root->data;
}
return ;
}
int main()
{
BtNode * root;
CreatBt(&root);//传指针的地址
cout<<CountLeave(root)<<endl;
ChangeLR(root);
//Addheight(&root);
PostOrder(root);
return 0;
}