您的位置:首页 > 理论基础 > 数据结构算法

数据结构——BinarySearch两种方法的代码实现

2017-04-06 11:35 477 查看
Reference Book: 《Data Structures and Program Design in C++》

---------------------------------------------------------------------------------------------------------------------------------------------------

1. Double_Linked_List见文章Double_Linked_List代码实现

2. (1) Record.h

#ifndef RECORD_H
#define RECORD_H

#include <iostream>

using namespace std;

typedef int Key_type;
typedef Key_type Record_type;
class Key
{
private:
Key_type key;

public:
static Key_type comparisons;
Key(int x=0);
Key_type the_key()const;

};
bool operator == (const Key &x, const Key &y);
bool operator > (const Key &x, const Key &y);
bool operator < (const Key &x, const Key &y);
bool operator >= (const Key &x, const Key &y);
bool operator <= (const Key &x, const Key &y);
bool operator != (const Key &x, const Key &y);
ostream &operator << (ostream &output, Key &x);
/*
class Record
{
public:
Record(int x=0, int y=0);
int the_key()const;

protected:

private:
int key;
int other;
};
*/
#endif // RECORD_H


2. (2) Record.cpp

#include "Record.h"

int Key::comparisons = 0;
Key::Key(int x)
{
key = x;
}

Key_type Key::the_key()const
{
return key;
}

bool operator == (const Key &x, const Key &y)
{
Key::comparisons++;
return x.the_key()==y.the_key();
}

bool operator > (const Key &x, const Key &y)
{
Key::comparisons++;
return x.the_key()>y.the_key();
}

bool operator < (const Key &x, const Key &y)
{
Key::comparisons++;
return x.the_key()<y.the_key();
}

bool operator >= (const Key &x, const Key &y)
{
Key::comparisons++;
return x.the_key()>=y.the_key();
}

bool operator <= (const Key &x, const Key &y)
{
Key::comparisons++;
return x.the_key()<=y.the_key();
}

bool operator != (const Key &x, const Key &y)
{
Key::comparisons++;
return x.the_key()!=y.the_key();
}

ostream &operator << (ostream &output, Key &x)
{
output << x.the_key();
output << endl;
return output;
}
/*
Record::Record(int x, int y)
{
key = x;
other = y;
}

int Record::the_key()const
{
return key;
}
*/


3. 有序表

Ordered_list.h

#ifndef ORDERED_LIST_H
#define ORDERED_LIST_H
#include "Doubly_Linked_List.h"
#include "Record.h"

using namespace std;

class Ordered_list:public Doubly_Linked_List<Key>
{
public:
Ordered_list();
Error_code insert(const Key &data);
Error_code insert(int position, const Key &data);
Error_code replace(int position, const Key &data);

protected:

private:
};

/*
C++的类模板继承不支持分离编译,声明和定义均需放在头文件中
*/
Ordered_list::Ordered_list()
{
//ctor
}

Error_code Ordered_list::insert(const Key &data)
/*Pre:
Post: 自动检索插入data不破坏原有序表的合适的pos, 并调用基类的insert操作.
*/
{
int s = size();
int position;
for(position = 0; position < s; position++)
{
Key list_data;
retrieve(position, list_data);
if(data < list_data)break;
}
return Doubly_Linked_List<Key>::insert(position, data);
// 派生类中有覆盖基类insert的方法, 此处需要用作用域解析运算符::调用
// 基类中的insert方法
}

Error_code Ordered_list::insert(int position, const Key &data)
/*Pre:
Post: 先检查插入元素是否保持了原有序表的有序性, 若不是则返回fail;
再调用基类的insert操作(包含了pos合法性的检查).
*/
{
Key list_data;
if(position>0)
{
retrieve(position-1, list_data);
if(data<list_data)return fail;
}
if(position<size())
{
retrieve(position, list_data);
if(data>list_data)return fail;
}
// 当在pos位置插入不破坏有序性时才执行insert操作
return Doubly_Linked_List<Key>::insert(position, data);
}

Error_code Ordered_list::replace(int position, const Key &data)
/*Pre:
Post: 先检查插入元素是否保持了原有序表的有序性(注意第二个if语句),
若不是则返回fail; 再调用基类的replace操作(包含了pos合法性的检查).
*/
{
Key list_data;
if(position>0)
{
retrieve(position-1, list_data);
if(data<list_data)return fail;
}
if(position<size()-1)   // 不需要比较size()-1位置
{
retrieve(position+1, list_data);
if(data>list_data)return fail;
}
return Doubly_Linked_List<Key>::replace(position, data);
}

#endif // ORDERED_LIST_H


4. main.cpp

#include <iostream>
#include "Ordered_list.h"

using namespace std;

/*********************************************
The Forgetful Version of Binary Search
*********************************************/
Error_code recursive_binary_1(const Ordered_list &the_list, const Key &target,
int bottom, int top, int &position)
/*Pre: 通过下标bottom和top框定待查找的Key的范围.
Post: 不断缩小范围至bottom和top限定至仅有1个元素, 若与搜索的target相等则返回
success并将设置position; 否则返回not_present.
*/
{
Key data;
if(bottom<top) // 表中至少还有两个元素
{
int mid = (bottom + top) / 2; // 结果向0舍入
the_list.retrieve(mid, data);
if(data<target)
return recursive_binary_1(the_list, target, mid+1, top, position);
else
return recursive_binary_1(the_list, target, bottom, mid, position);
}
else if(top<bottom)return not_present;
// 表中仅有一个元素
else
{
position = bottom;
the_list.retrieve(bottom, data);
if(data==target)return success;
else return not_present;
}
}

Error_code run_recursive_binary_1(const Ordered_list &the_list,
const Key &target, int &position)
{
return recursive_binary_1(the_list, target, 0, the_list.size()-1, position);
}

/********************************************************
The Recognizing Equality Version of Binary Search
********************************************************/
Error_code recursive_binary_2(const Ordered_list &the_list, const Key &target,
int bottom, int top, int &position)
/*Pre: 通过下标bottom和top框定待查找的Key的范围.
Post: 不断缩小bottom和top限定的范围, 且每次进行递归调用前都判断mid位置的元素与
target是否相等, 若相等则返回success; 重复以上步骤至找到target, 若未找到则
返回not_present.
*/
{
Key data;
if(bottom<=top)
{
int mid = (bottom + top) / 2;
the_list.retrieve(mid, data);
if(data==target)
{
position = mid;
return success;
}
else if(data<target)
return recursive_binary_2(the_list, target, mid+1, top, position);
else
return recursive_binary_2(the_list, target, bottom, mid-1, position);
}
else
return not_present;
}

Error_code run_recursive_binary_2(const Ordered_list &the_list, const Key &target,
int &position)
{
return recursive_binary_2(the_list, target, 0, the_list.size()-1, position);
}

void print(Key &x)
{
cout << x;
}

void test_forgetful_version()
{
Key target(5);
Ordered_list mylist;
for(int i=0; i<10; i++)
mylist.insert(Key(i));
cout<<"The ordered list is: "<<endl;
mylist.traverse(print);
cout<<endl<<"The target is: "<<target.the_key()<<endl;
int bottom = 0;
int top = mylist.size()-1;
int position = -1;

cout << endl << "Use recursive_binary_1 Method:" << endl;

if(recursive_binary_1(mylist, target, bottom, top, position)==success)
cout<<"Get the target in position: " << position <<endl;
else
cout<<"Target not present."<<endl;
}

void test_recognizing_equality_version()
{
Key target(5);
Ordered_list mylist;
for(int i=0; i<10; i++)
mylist.insert(Key(i));
cout<<"The ordered list is: "<<endl;
mylist.traverse(print);
cout<<endl<<"The target is: "<<target.the_key()<<endl;
int bottom = 0;
int top = mylist.size()-1;
int position = -1;

cout << endl << "Use recursive_binary_2 Method:" << endl;

if(recursive_binary_2(mylist, target, bottom, top, position)==success)
cout<<"Get the target in position: " << position <<endl;
else
cout<<"Target not present."<<endl;
}

int main()
{
test_forgetful_version();
test_recognizing_equality_version();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: