第四次实验
数据结构第四次实验
题目描述
给你一个无重复数的有序序列,如果采用折半查找的方式,对于给定的数,需要比较几次找到,请编程实现。
输入
第一行是N,表示序列中数的个数,序列最长1000,第二行是一个有序序列,第三行是要找的数x。
输出
如果找到x,输出折半比较的次数,否则输出NO。
样例输入
11
5 13 19 21 37 56 64 75 80 88 92
19
样例输出
2
#include <iostream>
using namespace std;
int cnt;
int a[20005];
void search(int x,int a[],int n){
int l=1,r=n;
while(l<r){
int i=(r+l)/2;
if(x==a[i]) {
cnt++;
r=i;
break;//不能少
}
else if(x>a[i]){
l=i+1;
cnt++;
}
else {
r=i-1;
cnt++;
}
}
if(a[r]==x) cout<<cnt;
else cout<<"NO";
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int x;cin>>x;
search(x,a,n);
return 0;
}
二叉搜索树中的查找
题目描述
给你一个数据序列,请构造一个二叉搜索树,然后计算出找到给定数据需比较的次数。
输入
第一行是N,表示序列中数的个数,序列最长1000,第二行是一个数据序列,第三行是要找的数x。
输出
如果找到x,输出比较的次数,没找到则输出NO。
样例输入
5
1 2 3 5 4
5
样例输出
4
#include<bits/stdc++.h>
using namespace std;
struct node{
int val;
node *l;
node *r;
};
int ans=0;
int flag=0;
void insert(node * &p,int c){
if(p==NULL){
p=new node;
p->val=c;
p->l=NULL;
p->r=NULL;
}
if(c<p->val){
insert(p->l,c);
}
if(c>p->val){
insert(p->r,c);
}
}
void search(node *T,int x){
if(T){
ans++;
if(T->val==x){
flag=1;
cout<<ans;
}else if(x<T->val)
search(T->l,x);
else
search(T->r,x);
}
}
int main(){
int n,m;
cin>>n;
node *T=NULL;
for(int i=1;i<=n;i++){
int x;
cin>>x;
insert(T,x);
}
cin>>m;
search(T,m);
if(flag==0)
cout<<"NO";
}
有向图的最短路径长度
题目描述
已知一个有向图,每个边都有一个正整数表示边长,请编程求出其中两个顶点间的最短路径长度。
输入
第一行是M、N,分别表示顶点数和有向边数(0<M,N<=100》),紧接着N行的每一行是X、Y、H,分别表示有向边的起点和终点以及边长。最后一行是要求其最短路径的两个顶点。
输出
相应两个顶点的最短路径值。
样例输入
5 7
A B 10
B C 50
A E 100
A D 30
C E 10
D C 20
D E 60
A E
样例输出
60
#include <bits/stdc++.h>
using namespace std;
map<char, int> mp;
const int maxn = 1000007;
int edge[105][105];
int dist[105];
bool vis[105];
string str0 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int dij(int v, int s,int M) {
for (int i = 1; i <= M; i++) {
dist[i] = edge[v][i];
vis[i] = false;
}
vis[v] = true;
dist[v] = 0;
for (int i = 1; i <= M; i++) {
int o = maxn;
int p;
if (i == v) continue;
p = v;
for (int j = 1; j <= M; j++) {
if (j == v)continue;
if ((dist[j] < maxn) && (vis[j] == false)) {
if (o > dist[j]) {
o = dist[j];
p = j;
}
}
}
vis[p] = true;
for (int k = 1; k <= M; k++) {
if (dist[k] > (dist[p] + edge[p][k]))
dist[k] = dist[p] + edge[p][k];
}
}
return dist[s];
}
int main() {
for (int i = 0; i < 105; i++) {
for (int j = 0; j < 105; j++) {
edge[i][j] = maxn;
}
}
int M, N,w;
cin >> M >> N;
char p, q;
for(int i = 0; i < 26; i++) mp[str0[i]] = i + 1;
for (int i = 0; i < N; i++) {
cin >> p >> q>>w;
edge[mp[p]][mp[q]] = w;
}
cin >> p >> q;
int v = mp[p],s = mp[q];
cout<<dij(v, s,M);
return 0;
}
哈希排序
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[]={3,8,67,45,11,0,34,67,23,8} ;
int arr[100];//注意开辟的数组大小要超过排序数字的最大值
for(int i=0;i<100;i++)
{
arr[i]=0;
}
for(int i=0;i<10;i++)
arr[a[i]]++;
for(int i=0;i<100;i++)
{
while(arr[i]--)
{
cout<<i<<" ";
}
}
return 0;
}
归并算法
#include<iostream>
using namespace std;
void Merge(int arr[], int l, int q, int r){
int n=r-l+1;//临时数组存合并后的有序序列
int* tmp=new int[n];
int i=0;
int left=l;
int right=q+1;
while(left<=q && right<=r)
tmp[i++] = arr[left]<= arr[right]?arr[left++]:arr[right++];
while(left<=q)
tmp[i++]=arr[left++];
while(right<=r)
tmp[i++]=arr[right++];
for(int j=0;j<n;++j)
arr[l+j]=tmp[j];
delete [] tmp;//删掉堆区的内存
}
void MergeSort(int arr[], int l, int r){
if(l==r)
return; //递归基是让数组中的每个数单独成为长度为1的区间
int q = (l + r)/2;
MergeSort(arr, l, q);
MergeSort(arr, q + 1, r);
Merge(arr, l, q, r);
}
int main(){
int a[8] = {3,1,2,4,5,8,7,6};
MergeSort(a,0,7);
for(int i=0;i<8;++i)
cout<<a[i]<<" ";
}