検索: 二分探索、平衡二分木、ハッシュ テーブル (演習 1、5、6) 二分ソート木 (演習 2、3、4)

蒋胡の名で知られる無名の大学生
原著者: jacky Li
電子メール: [email protected]

完成時期:2023.1.1
最終編集日:2023.1.1

目次

検索: 二分探索、平衡二分木、ハッシュ テーブル (演習 1、5、6)

レベル 1: 二分探索の再帰的アルゴリズム (アルゴリズム設計問題 1)

ミッション詳細

関連情報

プログラミング要件

テスト命令

参照コード

レベル 2: 二分木の高さのバランスを取る (アルゴリズム設計の質問 5)

ミッション詳細

関連情報

プログラミング要件

テスト命令

参照コード

レベル 3: ハッシュ テーブル キーワードの挿入と削除 (アルゴリズム設計の質問 6)

ミッション詳細

関連情報

プログラミング要件

テスト命令

参照コード

 検索: バイナリ ソート ツリー (演習 2、3、4)

レベル 1: 二分ソート木判別 (アルゴリズム設計問題 2)

ミッション詳細

関連情報

プログラミング要件

テスト命令

参照コード

レベル 2: x 以上のすべてのデータ (アルゴリズム設計の質問 3)

ミッション詳細

関連情報

プログラミング要件

テスト命令

参照コード

レベル 3: バイナリ ソート ツリーと検索 (アルゴリズム設計の質問 4)

ミッション詳細

関連情報

プログラミング要件

テスト命令

参照コード

作者には言いたいことがある


検索: 二分探索、平衡二分木、ハッシュ テーブル (演習 1、5、6)

レベル 1: 二分探索の再帰的アルゴリズム (アルゴリズム設計問題 1)

ミッション詳細

二分探索の再帰アルゴリズムを書きます。

関連情報

半分を見つけます。

プログラミング要件

プロンプトに従って、右側のエディタの Begin と End の間にコードを追加して、このレベルのタスクを完了します。

テスト命令

プラットフォームは、記述したコードをテストします。

テスト入力(全3行、1行目要素数n、2行目スペース区切りn要素、3行目検索対象要素):

5

1 2 3 4 5 4

予想される出力 (合計 1 行、チェックする要素の場所):

4

参照コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <unordered_map>
#include <unordered_set>

#define IOS std::ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define YES cout << "YES" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define NO cout << "NO" << endl;
//#define int long long
#define x first
#define y second
//#define cmp [&](PII a, PII b){ return a.y < b.y; }

const int N = 5e5+10, mod = 1e9+7, M = 1e7+5, K = 1e5+10, Z = 2e5+7;

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

int n;

int BinSearch_Cur(int a[],int key,int low,int high)
{
	/***********************Begin**********************/
	low = 1,  high = n;
	while(low <= high)
	{
		int mid = (low + high) >> 1;
		if(key == a[mid]) return mid;
		else if(key < a[mid]) high = mid - 1;
		else low = mid + 1;
	}
	return 0;
	/*********************** End **********************/
}
int main()
{
	while(cin>>n)
	{
		if(n==0) break;
        int a[99], key;
        for(int i = 1; i <= n; i ++) cin>>a[i];
        cin >> key;								
        cout << BinSearch_Cur(a, key, 0, n - 1) << endl;	
	}
	return 0;
}

レベル 2: 二分木の高さのバランスを取る (アルゴリズム設計の質問 5)

ミッション詳細

このレベルのタスク: バランス バイナリ ツリーの各ノードはバランス ファクター b でマークされ、アルゴリズムはバランス バイナリ ツリーの高さを見つけるために記述されます。

関連情報

平衡二分木

プログラミング要件

プロンプトに従って、右側のエディターの Begin と End の間にコードを追加して、必要なタスクを完了します。

テスト命令

プラットフォームは、記述したコードをテストします。

テスト入力 (バイナリ ツリーを順番に構築するためのシーケンスである文字列の合計 1 行):

110###0##

期待される出力 (合計 1 行、バイナリ ツリーの高さ):

3

参照コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <unordered_map>
#include <unordered_set>

#define IOS std::ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define YES cout << "YES" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define NO cout << "NO" << endl;
//#define int long long
#define x first
#define y second
//#define cmp [&](PII a, PII b){ return a.y < b.y; }

const int N = 5e5+10, mod = 1e9+7, M = 1e7+5, K = 1e5+10, Z = 2e5+7;

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

void CreatBiTree(BiTree &T)
{  
	//按先序次序输入二叉树中结点的值 创建二叉链表表示的二叉树 
    char ch;
	cin>>ch;
	if(ch=='#') T = NULL;         //递归结束 空树 
	else{                         //递归创建二叉树 
		T = new BiTNode;          //生成根节点
		T->data = ch;             //根结点数据域置ch 
		CreatBiTree(T->lchild);   //递归创建左子树 
		CreatBiTree(T->rchild);   //递归创建右子树 
	} 
} 
int Depth(BiTree T)
{
	/***********************Begin**********************/
	if(!T) return 0;
	else if(!(T -> lchild) && !(T -> rchild)) return 1;
	return Depth(T -> lchild) >= Depth(T -> rchild) ? Depth(T -> lchild) + 1 : Depth(T -> rchild) + 1;
	/*********************** End **********************/
}
int main()
{
	BiTree T;
	CreatBiTree(T);
	cout<<Depth(T)<<endl;
	return 0;
}

レベル 3: ハッシュ テーブル キーワードの挿入と削除 (アルゴリズム設計の質問 6)

ミッション詳細

このレベルのタスク: ハッシュ テーブルを作成し、そこに n 個のキーワードを挿入し、指定されたキーワード K を削除します。ハッシュ関数をH、競合解決方式をチェーンアドレス方式とする。

関連情報

ハッシュ表

プログラミング要件

プロンプトに従って、右側のエディターの Begin と End の間にコードを追加して、必要なタスクを完了します。

テスト命令

The platform will test the code you write. 以下は、テスト ケースの 2 つの例です。

テスト入力 (合計 3 行: 1 行目はキーワードの数 n、2 行目は空白で区切られた n 個のキーワード、3 行目は削除するキーワード K):

 予想される出力 (合計 2 つのグループ: 最初のグループは、挿入後に設定されたアドレスとキーワードのペアであり、2 番目のグループは、次のように K が削除された後に設定されたアドレスとキーワードのペアです):

参照コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <unordered_map>
#include <unordered_set>

#define IOS std::ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define YES cout << "YES" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define NO cout << "NO" << endl;
//#define int long long
#define x first
#define y second
//#define cmp [&](PII a, PII b){ return a.y < b.y; }

const int N = 5e5+10, mod = 1e9+7, M = 1e7+5, K = 1e5+10, Z = 2e5+7;

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

#define LENGTH 7

typedef struct LNode
{
	int data;
	struct LNode *next;
}LNode, *LinkList;

LinkList HT[LENGTH];

int H(int data)
{
	return data % LENGTH;
}

bool Insert_K( )
{
	/***********************Begin**********************/
	int n; cin >> n;
	int res = H(n);
	LNode *p = HT[res];
	while(p -> next)
		if(p -> next -> data == n) return false;
		else p = p -> next;
//	LNode *p = HT[res] -> next;            // 被 segmentation fault 啦,气死我啦…… 
//	while(p)
//		if(p -> data == n) return false;
//		else p = p -> next;
	LNode *s = new LNode;
	s -> data = n; 
	s -> next = p -> next;
	p -> next = s;
//	p -> data = n;
	return true;
	/*********************** End **********************/
}
bool Delete_K(int data)
{
	/***********************Begin**********************/
	int res = H(data);
	LNode *p = HT[res];
	while(p -> next)
		if(p -> next -> data == data) 
		{
			LNode *s = p -> next;
			p -> next = s -> next;
			delete s;
			return true;
		}
		else if(p -> next -> data != data) p = p -> next;
	return false;
	/*********************** End **********************/
}
void Output()
{//输出数据
	for(int i=0;i<LENGTH;i++)
	{
		cout<<i<<":";             		//输出散列地址
		LinkList p=HT[i]->next;  		//p初始化为链表的首元结点
		while(p)
		{
			cout<<p->data;
			p=p->next;
			if(p) cout<<" ";
		}
		cout<<endl;
	}
}
void initHash()
{
	for(int i=0;i<LENGTH;i++)
	{
		HT[i]=new LNode;
		HT[i]->next=NULL;
	}
}
int main()
{
	initHash();
	int n,ndel;
	cin>>n;
	for(int i=0;i<n;i++)
		Insert_K();
	Output();
	cin>>ndel;
	Delete_K(ndel);
	Output();
	return 0;
}

 検索: バイナリ ソート ツリー (演習 2、3、4)

レベル 1: 二分ソート木判別 (アルゴリズム設計問題 2)

ミッション詳細

与えられた二分木がソート済み二分木かどうかを判断するアルゴリズムを書きなさい。

関連情報

バイナリ ソート ツリー。

プログラミング要件

プロンプトに従って、右側のエディタの Begin と End の間にコードを追加して、このレベルのタスクを完了します。

テスト命令

プラットフォームは、記述したコードをテストします。

テスト入力 (合計 1 行):

ba##c##

期待される出力:

YES

参照コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <unordered_map>
#include <unordered_set>

#define IOS std::ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define YES cout << "YES" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define NO cout << "NO" << endl;
//#define int long long
#define x first
#define y second
//#define cmp [&](PII a, PII b){ return a.y < b.y; }

const int N = 5e5+10, mod = 1e9+7, M = 1e7+5, K = 1e5+10, Z = 2e5+7;

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

typedef struct BiTNode
{
   char data; 
   struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

void CreateBiTree(BiTree &T,char a[],int &i)
{//先序建立二叉树
	/***********************Begin**********************/
	if(a[i] == '#')  T = NULL;			
	else
	{							
		T = new BiTNode, T -> data = a[i];					
		CreateBiTree(T -> lchild, a, ++ i);	
		CreateBiTree(T -> rchild, a, ++ i);
	}
	/*********************** End **********************/
}

BiTree pre=NULL;									//前驱指针

void JudgeBST(BiTree T,int &flag)
{//判断二叉树T是否是二叉排序树,flag初值为1
	if(T!=NULL&&flag)
	{ 
		/***********************Begin**********************/
		JudgeBST(T -> lchild, flag);
		if (!pre) pre = T;
		else if (pre -> data < T -> data) pre = T;
		else flag = false;
		/*********************** End **********************/
	}
	else return;
	JudgeBST(T -> rchild, flag);
}
int main()
{
	char a[99];
	//输入先序序列
	cin>>a;
	if(strcmp(a,"#")!=0){
		int i=-1;
		int flag=1;
		BiTree T;
		CreateBiTree(T,a,++i);
		JudgeBST(T,flag);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}

レベル 2: x 以上のすべてのデータ (アルゴリズム設計の質問 3)

ミッション詳細

このレベルのタスク: 二分ソート ツリーは二分連結リスト格納構造を使用し、ルート ノードのポインタは T であり、リンク ノードの構造は (lchild, data, rchild) であることがわかっています。ここで、lchild とrchild はそれぞれノードの左側と右側を指し、右側の子のポインタである data フィールドにはノードのデータ情報が格納されます。二分ソート木でデータ値≧xの全ノードのデータを小さいものから大きいものへと出力する再帰アルゴリズムを書いてください。最初に条件を満たすノードを見つけてから、条件に合うノードを順番に出力する必要があります。

関連情報

バイナリソートツリー

プログラミング要件

プロンプトに従って、右側のエディターの Begin と End の間にコードを追加して、必要なタスクを完了します。

テスト命令

プラットフォームは、記述したコードをテストします。

テスト入力 (合計 3 行、1 行目はリスト要素の数 n、2 行目はスペースで区切られたリスト内の要素、3 行目は x の値):

5 1 3 4 2 5 3

期待される出力 (合計 2 行、1 行目はソートされたリスト、2 行目は x 以上のすべての要素)

1 2 3 4 5 3 4 5

参照コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <unordered_map>
#include <unordered_set>

#define IOS std::ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define YES cout << "YES" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define NO cout << "NO" << endl;
//#define int long long
#define x first
#define y second
//#define cmp [&](PII a, PII b){ return a.y < b.y; }

const int N = 5e5+10, mod = 1e9+7, M = 1e7+5, K = 1e5+10, Z = 2e5+7;

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

typedef struct BSTNode
{//二叉排序树的二叉链表存储表示
	int data;
	struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;

void InsertBST(BSTree &T,int e){
	/***********************Begin**********************/
	if(!T)
	{
		BSTNode *S = new BSTNode;
		S  -> data = e, S -> lchild = S -> rchild = NULL, T = S;
	}
    else if(e < T -> data) InsertBST(T -> lchild, e);
    else InsertBST(T -> rchild, e);
	/*********************** End **********************/
}
void Print(BSTree T)
{//中序输出以T为根的二叉排序树的所有结点
	/***********************Begin**********************/
	if(T)
	{
	    Print(T -> lchild);
        cout << T -> data << ' ';
	    Print(T -> rchild);
	}
	/*********************** End **********************/	
}
void PrintAllx(BSTree T,int x)
{//在二叉排序树T中,查找值≥x的结点并输出
	/***********************Begin**********************/
	if(T == NULL) return;
	PrintAllx(T -> lchild, x);
	if(T -> data >= x) cout << T -> data << ' ';
	PrintAllx(T -> rchild, x);
	/*********************** End **********************/
}
int main()
{
	BSTree T=NULL;
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		int e;
		cin>>e;
		InsertBST(T,e);
	}
	Print(T);
	cout<<endl;
	int x;
	cin>>x;
	PrintAllx(T,x);
}

レベル 3: バイナリ ソート ツリーと検索 (アルゴリズム設計の質問 4)

ミッション詳細

このレベルのタスク: 二分ソート ツリー T のノード形式は (llink, data, count, rlink) であることがわかっており、空のツリーから開始し、ツリー内の n 個のノード要素を順番に検索します。存在する場合はそれらを数えます (count ) + 1; そうでない場合は、新しいノードとしてツリーに挿入され、挿入後もバイナリ ソート ツリーのままになります. その非再帰アルゴリズムを記述してください.

関連情報

バイナリ ソート ツリー (バイナリ ソート ツリー) は、バイナリ検索ツリーとも呼ばれ、並べ替えと検索に役立つ特別なバイナリ ツリーです。1. バイナリ ソート ツリーの定義 バイナリ ソート ツリーは、空のツリー、または次のプロパティを持つバイナリ ツリーのいずれかです。(1) 左のサブツリーが空でない場合、左のサブツリーのすべてのノードの値はそれより小さい(2) 右のサブツリーが空でない場合、右のサブツリーのすべてのノードの値は、そのルート ノードの値よりも大きくなります; (3) その左と右のサブツリーもバイナリ ソート ツリーです。二分ソートツリーは再帰的に定義されます。バイナリ ソート ツリーの重要なプロパティは、定義から引き出すことができます。バイナリ ツリーを順番にトラバースすると、ノード値が増加する順序付けられたシーケンスを取得できます。

プログラミング要件

プロンプトに従って、右側のエディターの Begin と End の間にコードを追加して、必要なタスクを完了します。

テスト命令

The platform will test the code you write. 以下は、テスト ケースの 2 つの例です。

テスト入力 (合計 2 行: 1 行目は要素数 n、2 行目はスペースで区切られた n 要素):

6 1 3 4 2 5 3

予想される出力 (合計 2 行: 1 行目は並べ替えられた要素、2 行目は各要素に対応するカウント):

1 2 3 4 5 1 1 2 1 1

参照コード

#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <unordered_map>
#include <unordered_set>

#define IOS std::ios::sync_with_stdio(false)
#define inf 0x3f3f3f3f
#define YES cout << "YES" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define NO cout << "NO" << endl;
//#define int long long
#define x first
#define y second
//#define cmp [&](PII a, PII b){ return a.y < b.y; }

const int N = 5e5+10, mod = 1e9+7, M = 1e7+5, K = 1e5+10, Z = 2e5+7;

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

typedef struct BiTNode
{
	int data;
	int count;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void SearchBST(BiTree &T,int X)
{
	/***********************Begin**********************/
	BiTNode *s = new BiTNode;
	s -> data = X, s -> count = 1, s -> lchild = s -> rchild = NULL;
	if(T == NULL) T = s;
	else
	{
		BiTNode *r = T, *p = NULL;
		while(r)
		{
			if(r -> data == X) {r -> count ++; return;}
			else
			{
				p = r;
				if(r -> data > X) r = r -> lchild;
				else r = r -> rchild;
			}
		}
		if(p -> data > X) p -> lchild = s; 
		else p -> rchild = s; 
	}
	/*********************** End **********************/
}
void PrintData(BiTree T)
{//中序遍历输出二叉树T
    /***********************Begin**********************/
	if(T)
	{
		PrintData(T -> lchild);
        cout << T -> data << ' ';
		PrintData(T -> rchild);
    }
    /*********************** End **********************/
}
void PrintCount(BiTree T)
{//中序遍历输出二叉树T计数
    /***********************Begin**********************/
	if(T)
	{
	    PrintCount(T -> lchild);
	    cout << T -> count << ' ';
	    PrintCount(T -> rchild);
	}
    /*********************** End **********************/
}
int main()
{
	int n;
	cin>>n;
	int e;        			//变量e用于接收输入数据
  	BiTree T=NULL;
	for(int i=0;i<n;i++)
	{//基于非递归的二叉排序树的结点的查找和插入
		cin>>e;
		SearchBST(T,e);
	}
	PrintData(T);			//中序遍历输出二叉树T结点
	cout<<endl;
	PrintCount(T);   		//中序遍历输出二叉树T计数
	cout<<endl;
	return 0;
}

作者には言いたいことがある

ブロガーの発言が役に立ったと思われる場合は、クリックしてサポートしてください。そのような問題は引き続き更新されます...

おすすめ

転載: blog.csdn.net/weixin_62075168/article/details/128511483