第四次实验

数据结构第四次实验

题目描述

给你一个无重复数的有序序列,如果采用折半查找的方式,对于给定的数,需要比较几次找到,请编程实现。

输入

第一行是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]<<" ";
}
posted @ 2022-07-09 14:19  xu~~~  阅读(45)  评论(0)    收藏  举报