【数据结构】day3-查找

1.二分查找

【问题描述】

请输入10个整数至一维数组a中,并采用冒泡排序算法将这10个数按从小到大排序;然后输入一个数至变量n,并采用二分查找法判断该数是否为数组a中的一个数,是则输入“yes”,否则输入“no”。

【样例输入】

10 9 8 7 6 5 4 3 2 1 

5

【样例输出】

yes
yes

【注意】请采用非递归和递归两种方法实现,结果输出两次

//2.二分查找
#include<iostream>
#include<algorithm>
using namespace std;
int a[15];
int Sort(int key)
{
	int low=0,high=10; 
	while(low<=high)
	{
		int mid=(low+high)/2;
		if(key==a[mid]) return mid;
		else if(key>a[mid]){
			low=mid+1;
		}
		else{
			high=mid-1;
		}
	}
	return -1;
}
int SSort(int low,int high,int key)
{
	if(low>high) return -1;
		int mid=(low+high)/2;
		if(key==a[mid]) return mid;
		else if(key>a[mid]){
			return SSort(mid+1,high,key);
		}
		else{
			return SSort(low,mid-1,key);
		}
}
int main()
{
	for(int i=0;i<10;i++)
	cin>>a[i];
	int key;
	cin>>key;
	sort(a,a+10);
	int ww=Sort(key);
	cout<<(ww==-1?"no":"yes");
	cout<<endl;
	int www=SSort(0,10,key);
	cout<<(www==-1?"no":"yes");
 } 

2. 二叉查找树的后序遍历

【问题描述】输入一个整数数组,判断该数组是不是某二叉查找树(折半查找树)后序遍历的结果。如果是返回true,否则返回false。
【输入形式】输入任意长度的数组,数字之间空格分开
【输出形式】true 或者 false
【样例输入】输入5 7 6 9 11 10 8
【样例输出】true
【样例说明】由于这一整数序列是如下树的后序遍历结果:

          8
       /      \
      6      10
    /   \     /   \
   5   7   9  11

因此返回true。

【评分标准】暴力求解法不得分。

【提示】后序遍历的最后一个结点一定是根结点,那么前面的数据就可以划分为比根小的、比根大的。依此类推下去。

#include<bits/stdc++.h>
using namespace std;

//判断 
bool judge(vector<int> a)
{
	vector<int>v1,v2;
	int i;
	for(i=0;i<a.size()-1;i++)
	{
		if(a[i]<a[a.size()-1])
		{
			v1.push_back(a[i]);
		}
		else 
		  break;
	}
	for(int j=i;j<a.size()-1;j++)
	{
		if(a[j]>a[a.size()-1])
		{
			v2.push_back(a[j]);
		}
		else
		  return false;
	}
	bool l=true,r=true;
	if(!v1.empty())
	   l=judge(v1);
	if(!v2.empty())
	   r=judge(v2);
	return l&&r;
	
}

int main()
{
	int data;
	vector<int> a;
	char c;
	while(cin>>data)
	{
		a.push_back(data);
//		cout<<data;
		c=cin.get();
		if(c=='\n') break;
	}
	if(judge(a))
	   {
	   cout<<"true";return 0;}
	
	cout<<"false";return 0;

}
二叉排序树的判定

【问题描述】课后作业第6题。试写一个判别给定二叉树是否为二叉排序树的算法。以前序遍历序列和中序遍历序列给出该二叉树的结点,并创建该二叉树。然后再进行判断。请注意,树中结点关键字可能相同。

【样例输入1】

6 4 5 8 6 9 0

4 5 6 6 8 9 0
【样例输出1】

true

【样例输入2】

6 4 7 8 0

4 7 6 8 0
【样例输出2】

false

【提示】若直接根据给定的中序是否有序来进行判断,此种判断方法不得分。务必先创建二叉树的链式存储,再对其进行判断。

//4.二叉排序树的判定 
#include<iostream>
using namespace std;
typedef struct node{
	int data;
	struct node *left;
	struct node *right;
}Node,*TreeNode;

void CreateBitree(TreeNode &root,int pre[],int in[],int preleft,int preright,int inleft,int inright)
{
	if( preleft > preright ) root=NULL;
	else
	{
		int mid=inleft;
		while(in[mid]!=pre[preleft])//根 
		    mid++;
		//找到根所在位置 递归创建
		root=new Node;
		root->data=pre[preleft];
		CreateBitree(root->left,pre, in,preleft+1,preleft+mid-inleft,inleft,mid-1);
		CreateBitree(root->right,pre,in,preleft+mid-inleft+1,preright,mid+1,inright); 
	}
}
//6 4 5 8 6 9 0
//4 5 6 6 8 9 0
int getmax(Node *p)
{
//	Node *t=p;
	while(p->right!=NULL)
		p=p->right;
	return p->data;
}
int getmin(Node *p)
{
//	Node *t=p;
	while(p->left!=NULL)
		p=p->left;
	return p->data;
}
bool check(TreeNode root)//TreeNode root
{
	if(root==NULL)return true;
	if(root->left==NULL&&root->right==NULL) return true;
	else{
		if(root->left!=NULL&&root->data<getmax(root->left))return false;
		else if(root->right!=NULL&&root->data>getmin(root->right))return false;
		else return (check(root->left)&&check(root->right));
	}
}
int main()
{
	TreeNode root=NULL; 
	int in[100],pre[100];
	int i=0,j=0;
	while(1) //6 4 5 8 6 9 0
	{
		cin>>pre[i++];
		if(pre[i-1]==0) break; 
	}
	i--;//i代表长度 
	for(j=0;j<=i;j++)
		cin>>in[j];
//	
//	for(int j=0;j<=i;j++)
//	cout<<pre[j]<<" ";
//	
//	for(int j=0;j<=i;j++)
//	cout<<in[j]<<" ";
	CreateBitree(root,pre,in,0,i-1,0,i-1);
//	dfs(root);
	if(check(root)==true) cout<<"true";
	else cout<<"false"; 
	return 0;
}

二叉排序树

【问题描述】

请根据输入的数据创建一棵二叉排序树。然后执行相应操作。

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

【样例说明】

若待删除的结点包含左右子树,则以其左子树的最右结点代替它。

10.00

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
struct BiTNode{
	int data;
	BiTNode *LChild;
	BiTNode *RChild;
};
void Insert(BiTNode *&root,int x)
{
	BiTNode *pre=NULL,*p;
	p=root;
	while(p!=NULL)
	{
		pre=p;
		if(p->data > x) p=p->LChild;
		else if(p->data < x) p=p->RChild;
		else return;
	}
	BiTNode *s;
	s=new BiTNode;
	s->data=x;
	s->LChild=NULL;
	s->RChild=NULL;
	if(pre->data>x) pre->LChild=s;
	else pre->RChild=s;
}
void Create(BiTNode *&root)
{
   int x;
   root=new BiTNode;
   cin>>x;
   root->data=x;
   root->LChild=NULL;
   root->RChild=NULL;
   cin>>x;
   while(x!=0)
   {
   	Insert(root,x);
   	cin>>x;
   }	
}
void PreOrder(BiTNode *root)
{
	if(root==NULL) {
		cout<<"# ";
		return ;
	}
		cout<<root->data<<" ";
	PreOrder(root->LChild);

	PreOrder(root->RChild);
}
void InOrder(BiTNode *root)
{
	if(root==NULL) {
		return ;
	}
	
	InOrder(root->LChild);
		cout<<root->data<<" ";
	InOrder(root->RChild);
}
/*
void Delete(BiTNode *&root,int x)
{
	BiTNode *pre=NULL,*p;
	p=root;
	while(p!=NULL)
	{
		if(p->data==x) break;
		pre=p;
		if(p->data >x) p=p->LChild;
		else p=p->RChild;
	}
	if(p==NULL) return;
	if(p->LChild==NULL) //2 situation
	{
		//delete root
		root=p->RChild;
		
		if(pre->LChild==p) pre->LChild=p->RChild;
		else pre->RChild=p->LChild;
	}
	else //p have left
	{
		BiTNode *q=p;
		BiTNode *s=p->LChild;
		while(s->RChild!=NULL)
		{
			q=s;
			s=s->RChild;
		}
		if(q==p) q->LChild=s->LChild;
		else q->RChild=s->LChild;
		p->data=s->data;
	}
}*/
void Delete(BiTNode *&root,int x)
{
	//寻找该节点
	BiTNode* p=root;
	BiTNode* f=NULL;
	BiTNode *s,*q;
	while(p)
	{
		if(p->data==x) break;
		f=p;//记录节点的父母节点 
		if(x>p->data)
		p=p->RChild;
		else
		p=p->LChild;
	}
	if(p==NULL) return;//节点不存在 
	if(!p->LChild)
	{
		if(f==NULL) root=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);	
	}
}
 
int Depth(BiTNode *&root,int x,int &d)
{
	if(root==NULL) return 0;
	else if(root->data==x) return 0;
	else if(root->data>x)
	{
		d++;
		return Depth(root->LChild,x,d);
	}
	else{
		d++;
		return Depth(root->RChild,x,d);
	}
}
int main()
{
	BiTNode *root;
	Create(root);
	PreOrder(root);
	cout<<endl;
	int x;
	cin>>x;
	Delete(root,x);
	InOrder(root);
	cout<<endl; 
	cin>>x;
	int d=1;
	Depth(root,x,d);
	cout<<d;
	return 0;		
}

世界上有2片相同的雪花吗

【题目来源】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.

10.00

#include<bits/stdc++.h>
#include<iostream>
#define prime 999983
using namespace std;


struct node
{
    int len[6];
}leaf[100001];


typedef struct HashTable
{
    int len[6];
    HashTable *next;
}HashTable;


HashTable *Hash[prime+1];


int get_Key(int k)
{
    int key = 0;
    for(int i = 0; i < 6; i++)
    {
        key += (leaf[k].len[i])%prime;
        key %= prime;
    }


    return ++key;
}


/*顺时针判断两片雪花是否形同*/


bool clowkwise(HashTable *H,int k)
{
    for(int j = 0; j < 6; j++)
    {
        bool flag = true;
        for(int i = 0; i < 6; i++)
        {
            if(leaf[k].len[i] != H->len[(i+j)%6])
            {
                flag = false;
                break;
            }
        }
        if(flag)
            return true;
    }
    return false;
}

bool counterclowkwise(HashTable *H,int k)
{
    for(int j = 0; j < 6; j++)
    {
        bool flag = true;
        for(int i = 0; i < 6; i++)
        {
            if(leaf[k].len[i] != H->len[(5-i-j+6)%6])
            {
                flag = false;
                break;
            }
        }
        if(flag)
            return true;
    }
    return false;
}


/*把第K个雪花信息插入HashTable*/
/*如果位置有元素则比较*/


bool Insert(int k)
{
    int key = get_Key(k);


    if(!Hash[key])
    {
        HashTable *temp = new HashTable;
        temp->next = NULL;


        for(int i = 0; i < 6; i++)
            temp->len[i] = leaf[k].len[i];


        Hash[key] = temp;
    }
    else
    {
        HashTable *temp = Hash[key];
        if(clowkwise(temp,k) || counterclowkwise(temp,k))
            return true;

        while(temp->next)
        {
            temp = temp->next;


            if(clowkwise(temp,k) || counterclowkwise(temp,k))
                return true;
        }


        temp->next = new HashTable;
        temp->next->next=NULL;
        for(int i = 0; i < 6; i++)
            temp->next->len[i] = leaf[k].len[i];
    }
    return false;
}


int main()
{
    int n;
    while(~scanf("%d",&n))
    {
            int i,j;
            memset(Hash,0,sizeof(Hash));
            bool flag = false;
            for(i = 1; i <= n; i++)
            {
                for( j = 0; j < 6; j++)
				    cin>>leaf[i].len[j];

                if(!flag)
                    flag = Insert(i);
            }
            if(flag)
                printf("Twin snowflakes found.\n");
            else
                printf("No two snowflakes are alike.\n");
    }
    return 0;
}
求第k大的数

【问题描述】 求n个数中第k大的数
【输入形式】 第一行n k,第二行为n个数,都以空格分开
【输出形式】 第k大的数
【样例输入】
10 3
18 21 11 26 12 2 9 33 43 28

【样例输出】

28

【评分标准】时间复杂度大于等于O(k*n)的方法得一半分,时间复杂度小于等于O(n*log2k)得满分。

【提示】

1. 分析各种排序或查找算法的优缺点,分析解决具体问题的时间复杂度,进而找出更高效的算法。

2. n与k的值不同,不同算法的效率也会有影响,如n=10, k=9时,可以找第2小的数。

10.00
//求第k大的数

#include<bits/stdc++.h>
using namespace std;
int k,n;

int search(int a[],int low,int high)
{
	int mid=(low+high)/2;
	if(mid==k) return a[mid];
	else{
		if(mid>k) search(a,low,mid-1);
		else  search(a,mid+1,high);
	}
}
int main()
{
	int s;
	cin>>n>>s;
	k=n-s+1;
	int a[100];
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	} 
	sort(a+1,a+n+1);
//	for(int i=1;i<=n;i++)
//	{
//		cout<<a[i]<<" ";
//	}
	int low=0,high=n;
	cout<<search(a,low,high);
 } 


查找3个数组的最小共同元素

【问题描述】查找3个数组的最小共同元素
【输入形式】三个数组,均以0代表输入结束
【输出形式】最小共同元素
【样例输入】

1 3 5 7 8 9 0

2 4 6 8 10 12 14 16 18 0

-1 3 8 16 18 19 20 168 198 0
【样例输出】

8

10.00下载源文件
得分10.00   最后一次提交时间:2023-05-18 17:47:21

共有测试数据:3
平均占用内存:1.277K    平均CPU时间:0.01117S    平均墙钟时间:0.01118S
 
测试数据评判结果
测试数据1完全正确
测试数据2完全正确
测试数据3完全正确
9.查找一个循环顺序数组的

 

//9. 查找3个数组的最小共同元素
#include<bits/stdc++.h>
using namespace std;
int read(int arr[])
{
	int x;
	cin>>x;
	int i=0;
	while(x!=0)
	{
		arr[i++]=x;
		cin>>x;
	}
	return i;
}
int search(int a[],int b[],int res[],int n1,int n2)
{
	int n=0;
	int i=0,j=0;
	while(i<n1)
	{
		while(j<n2)
		{
			if(a[i]==b[j]){
				res[n++]=a[i];
				i++;j++;
			}
			else if(a[i]>b[j])
			{
				j++;
			}
			else{
				i++;
			}
		}
	}
	return n;
}
void check(int b[],int res[],int n2,int n4)
{
	int i=0,j=0; 
	while(i<n4)
	{
		while(j<n2)
		{
			if(res[i]==b[j]){
				cout<<b[j];
				return ;
			}
			else if(res[i]>b[j])
			{
				j++;
			}
			else{
				i++;
			}
		}
	}
}
int main()
{
int a[100],b[100],c[100],res[100];
int n1,n2,n3,n4;
	n1=read(a);
	n2=read(b);
	n3=read(c);

	sort(a,a+n1);
	sort(b,b+n2);
	sort(c,c+n3);
//	for(int i=0;i<n1;i++)
//	  cout<<a[i]<<" ";
	n4=search(a,b,res,n1,n2);

	check(c,res,n3,n4);
}

查找一个循环顺序数组的最小元素

【问题描述】以循环排列的一组顺序的数据,存储在一维数组中,查找最小元素并输出。
【输入形式】一组数据,以0结束输入
【输出形式】最小元素
【样例输入】7 9 11 1 3 5 0
【样例输出】1

#include<iostream>
using namespace std;
int main()
{
	//read
	int x,n=0;
	int a[100];
	cin>>x;
	while(x!=0)
	{
		a[n++]=x;
		cin>>x;
	}
	//chazhao
	int min=0;
	while(a[min]<a[min+1]) min++;
	if(a[min+1]<a[0])
	cout<<a[min+1];
	else{
		cout<<a[0];
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值