关于查找的题目
二叉排序树
【问题描述】
请根据输入的数据创建一棵二叉排序树。然后执行相应操作。
1 删除某一值为x的结点
2 求指定结点y在二叉排序树中的层数
【输入形式】
结点数据,以0代表结束输入。
待删除的x,待求层数的y
【输出形式】
创建好的二叉排序树的拓展的前序遍历结果
删除后的二叉排序树的中序遍历结果
y所在的层数
【样例输入】
29 39 15 25 28 10 11 2 0
10
11
【样例输出】
29 15 10 2 # # 11 # # 25 # 28 # # 39 # #
2 11 15 25 28 29 39
4
【样例说明】
若待删除的结点包含左右子树,则以其左子树的最右结点代替它。
运行代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
using namespace std;
typedef struct Node {
int data;
struct Node* LChild;
struct Node* RChild;
}BiTNode, * BiTree;
int cnt = 1;
void Insert(BiTree &bt,int n)//插入排序二叉树结点
{
BiTree s;
if (bt == NULL)
{
s = new BiTNode;
s->data = n;
s->LChild = s->RChild = NULL;
bt = s;
}
else if (n < bt->data)
{
Insert(bt->LChild, n);
}
else if (n > bt->data)
{
Insert(bt->RChild, n);
}
}
void PrePrint(BiTree bt)//前序遍历,空的结点输出“#”
{
if (bt == NULL)
{
cout << "#" << " ";
}
else
{
cout << bt->data << " ";
PrePrint(bt->LChild);
PrePrint(bt->RChild);
}
}
void Delete(BiTree& bt, int n)
{
BiTree p = bt, f = NULL, q, s;
while (p)
{
if (p->data == n) break;
f = p;
if (p->data > n)
{
p = p->LChild;
}
else
{
p = p->RChild;
}
}
if (p->LChild == NULL)//p无左子树
{
if (f == NULL)
{
bt = p->RChild;
}
else if (f->LChild == p)
{
f->LChild = p->RChild;
}
else {
f->RChild = p->RChild;
}
free(p);
}
else
{
q = p; s = p->LChild;
while (s->RChild)
{
q = s; s = s->RChild;
}
if (q == p)
{
q->LChild = s->LChild;
}
else
{
q->RChild = s->LChild;
}
p->data = s->data;
free(s);
}
}
void InPrint(BiTree bt)
{
if (bt != NULL)
{
InPrint(bt->LChild);
cout << bt->data << " ";
InPrint(bt->RChild);
}
}
void layerfind(BiTree bt, int n)
{
if (bt->data == n)
{
return;
}
else if (bt->data > n)
{
layerfind(bt->LChild, n);
cnt++;
}
else if (bt->data < n)
{
layerfind(bt->RChild, n);
cnt++;
}
}
int main()
{
BiTree bt = NULL;
int n, x, num;
while (cin >> n)
{
if (n == 0)
{
break;
}
Insert(bt, n);
}
cin >> x >> num;
PrePrint(bt);
cout << endl;
Delete(bt, x);
InPrint(bt);
layerfind(bt, num);
cout << endl;
cout << cnt;
}
二叉排序树主要是建树的过程,每要插入一个新数据需要从上至下来扫描然后插入,其他思路在树的学习中已经有体现,不多赘述。
折半查找法的使用
【问题描述】给定一个按值有序(升序)的N元整数数组A,采用折半查找法查找关键值k的位置,并给出查找的过程
【输入形式】
第一行:N
第二行:A[0], A[1], … , A[N-1]
第三行:k
【输出形式】
第一行:k的位置(索引),若不存在则输出‘no’
第二行:查找的过程,每一次折半的中间(mid)位置的值,以逗号分隔。例如,1 2 3 4 5的中间位置为3,1 2 3 4的中间位置为2。
【样例输入】
样例1
11
2,5,8,11,15,16,22,24,27,35,50
22
样例2
11
2,5,8,11,15,16,22,24,27,35,50
10
【样例输出】
样例1
6
16,27,22
样例2
no
16,8,11
【样例说明】
【评分标准】必须使用折半法,其他方法不能得分。
运行代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, k; cin >> n;
int* num, step[100];
num = new int[n];
int len = 0;
while (len+1 != n)
{
int data;
char temp;
cin >> data >> temp;
num[len] = data;
len++;
}
cin >> num[len];
cin >> k;
int low = 0, high = n - 1, i = 0, flag = 0;
while (low <= high)
{
int mid = (low + high) / 2;
step[i] = num[mid];
i++;
if (k == num[mid])
{
cout << mid << endl;
flag = 1;
break;
}
else if (k < num[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
if (flag == 0)
{
cout << "no" << endl;
}
for (int j = 0; j < i-1; j++)
{
cout << step[j] << ",";
}
cout << step[i - 1];
}
二叉查找树的后序遍历
【问题描述】输入一个整数数组,判断该数组是不是某二叉查找树的后序遍历的结果。如果是返回true,否则返回false。
【输入形式】输入任意长度的数组,数字之间空格分开
【输出形式】true 或者 false
【样例输入】输入5 7 6 9 11 10 8
【样例输出】true
【样例说明】由于这一整数序列是如下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
因此返回true。
【评分标准】暴力求解法不得分。
【提示】后序遍历的最后一个结点一定是根结点,那么前面的数据就可以划分为比根小的、比根大的。依此类推下去。
运行代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
using namespace std;
bool judge(vector<int> &s)
{
vector<int>pre, after;
int i = 0;
while (s[i]<s[s.size()-1])
{
pre.push_back(s[i]);
i++;
}
for (int i = pre.size(); i < s.size()-1; i++)
{
after.push_back(s[i]);
}
for (int i = 0; i < after.size(); i++)
{
if (after[i] < s[s.size() - 1]) {
return false;
}
}
if (pre.size() != 0)
{
judge(pre);
}
if (after.size() != 0)
{
judge(after);
}
return true;
}
int main()
{
vector<int>s;
int temp;
while (cin >> temp)
{
s.push_back(temp);
}
int len = s.size() - 1;
if (judge(s))
{
cout << "true";
}
else {
cout << "false";
}
}
雪花
【题目来源】3349 – Snowflake Snow Snowflakes (poj.org)
Description
You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your program will read information about a collection of snowflakes, and search for a pair that may be identical. Each snowflake has six arms. For each snowflake, your program will be provided with a measurement of the length of each of the six arms. Any pair of snowflakes which have the same lengths of corresponding arms should be flagged by your program as possibly identical.
Input
The first line of input will contain a single integer n, 0 < n ≤ 100000, the number of snowflakes to follow. This will be followed by n lines, each describing a snowflake. Each snowflake will be described by a line containing six integers (each integer is at least 0 and less than 10000000), the lengths of the arms of the snow ake. The lengths of the arms will be given in order around the snowflake (either clockwise or counterclockwise), but they may begin with any of the six arms. For example, the same snowflake could be described as 1 2 3 4 5 6 or 4 3 2 1 6 5.
Output
If all of the snowflakes are distinct, your program should print the message:
No two snowflakes are alike.
If there is a pair of possibly identical snow akes, your program should print the message:
Twin snowflakes found.
Sample Input
2
1 2 3 4 5 6
4 3 2 1 6 5
Sample Output
Twin snowflakes found.
运行代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<cstdio>
#include<algorithm>
#include<cstring>
const int HASH = 99991;
const int MAXN = 100000 + 5;
typedef int snow[6];
snow st[MAXN];
int head[HASH], next[MAXN];
int hash(snow& s)
{
int i, v = 0;
for (i = 0; i < 6; i++)
v = v + s[i];//printf("%d\n",v);
return v % HASH;
}
bool compare(snow& s, snow& t)
{
int i;
for (i = 0; i < 6; i++)
if ((s[i % 6] == t[0] &&
s[(i + 1) % 6] == t[1] &&
s[(i + 2) % 6] == t[2] &&
s[(i + 3) % 6] == t[3] &&
s[(i + 4) % 6] == t[4] &&
s[(i + 5) % 6] == t[5]) ||
(s[i % 6] == t[5] &&
s[(i + 1) % 6] == t[4] &&
s[(i + 2) % 6] == t[3] &&
s[(i + 3) % 6] == t[2] &&
s[(i + 4) % 6] == t[1] &&
s[(i + 5) % 6] == t[0]))
return true;
return false;
}
bool search(int r)
{
int h = hash(st[r]);
int u = head[h];
while (u)
{
if (compare(st[u], st[r])) return true;
u = next[u];
}
next[r] = head[h];
head[h] = r;
return false;
}
int main()
{
int n, i, k = 1;
memset(head, 0, sizeof(head));
memset(next, 0, sizeof(next));
scanf("%d", &n);
while (n--)
{
for (i = 0; i < 6; i++)
scanf("%d", &st[k][i]);
if (search(k)) { printf("Twin snowflakes found."); return 0; }
k++;
}
printf("No two snowflakes are alike.");
return 0;
}