数据结构 | List | Binary_search

本文详细介绍了如何使用C++实现顺序存储的List,并利用List实现二分查找功能。代码中定义了Record类,包含了key和other字段,List类实现了基本操作,如插入、删除、替换等。在二分查找过程中,通过递归函数`recursive_binary`进行查找,最终找到目标元素的下标并输出,如果目标不存在则输出-1。
摘要由CSDN通过智能技术生成

题目

(二分查找的实现)请尝试用你实现的顺序存储List实现二分查找。List中的Record包含key和other部分。其中key为英文单词,other为单词的中文解释。
【输入】
第一行,查询目标target(英文单词)
第二行,若干条包含key(string)和other(string)的序列,序列按照key的升序排列;(单词数量小于2000)
【输出】查询目标所在的下标,查询目标的内容(key和other),若单词不存在则输出-1即可。
例如
【输入】
wait
computer 电脑 eye 眼睛 hello 你好 train 火车 wait 等待 zebra 斑马
【输出】
4
wait 等待
【输入】
apple
computer 电脑 eye 眼睛 hello 你好 train 火车 wait 等待 zebra 斑马
【输出】
-1 //不存在

代码

面向过程,代码较长。

#include <bits/stdc++.h>
using namespace std;
enum Error_code{underflow,overflow,error,success,fail,not_present};
const int max_list = 2010;
class Record;

class Key
{
    string key;
public:
    Key(string x = " ");
    Key(const Record &r);
    string the_key()const;
};

class Record
{
public:
    operator Key();//implicit conversion
    Record(string x = " ",string y = " ");
    string the_key()const;
    string the_other()const;
private:
    string key;
    string other;
};

typedef Record List_entry;

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 Record &x,const Record &y);
bool operator > (const Record &x,const Record &y);
bool operator < (const Record &x,const Record &y);//别忘了Record的运算符重载!!!


class List
{
public:
    List();
    int size()const;
    bool full()const;
    bool empty()const;
    void clear();
    void traverse(void(*visit)(List_entry &));
    Error_code retrieve(int position,List_entry &x)const;
    Error_code replace(int position,const List_entry &x);
    Error_code remove(int position,List_entry &x);
    Error_code insert(int position,const List_entry &x);
 protected:
    int count;
    List_entry entry[max_list];

};

class Ordered_list:public List
{
public:
    Error_code insert(const Record &data);
    Error_code insert(int position,const Record &data);
    Error_code replace(int position,const Record &data);
};

Error_code recursive_binary(const Ordered_list &the_list,const Key &target,int bottom,int top,int &position)
{
    Record 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(the_list,target,mid + 1,top,position);
        else
            return recursive_binary(the_list,target,bottom,mid - 1,position);
    }
    else return not_present;
}

int main()
{
    string str,tmp_a,tmp_b;
    cin >> str;
    Key target(str);
    int bottom,top,position;
    Ordered_list mylist;
    while (cin >> tmp_a >> tmp_b)//input
    {
        mylist.insert(Record(tmp_a,tmp_b));
    }
    bottom = 0;
    top = mylist.size() - 1;
    position = bottom;
    if (recursive_binary(mylist,target,bottom,top,position) == success)
    {
        Record tmp;
        mylist.retrieve(position,tmp);
        cout << position << endl << tmp.the_key() << " " << tmp.the_other() << endl;
    }
    else cout << -1 << endl;
    return 0;
}

Key::Key(string x)
{
    key = x;
}

Key::Key(const Record &r)
{
    key = r.the_key();
}

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


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

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

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

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

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

bool operator == (const Record &x,const Record &y)
{
    return x.the_key() == y.the_key();
}

bool operator > (const Record &x,const Record &y)
{
    return x.the_key() > y.the_key();
}

bool operator < (const Record &x,const Record &y)
{
    return x.the_key() < y.the_key();
}

Record::Record(string x,string y)
{
    key = x;
    other = y;
}

Record::operator Key()
{
    Key tmp(key);
    return tmp;//!!一定要return!
}

string Record::the_key()const
{
    return key;
}

string Record::the_other()const
{
    return other;
}

List::List()
{
    count = 0;
}

int List::size()const
{
    return count;
}

bool List::full()const
{
    return count == max_list;
}

bool List::empty()const
{
    return count == 0;
}

void List::clear()
{
    count = 0;
}

Error_code List::insert(int position,const List_entry &x)
{
    if (full()) return overflow;
    if (position < 0 || position > count) return error;//只有这里是>!其余是>=
    for (int i = count - 1; i >= position; i--) entry[i+1] = entry[i];
    entry[position] = x;
    count++;
    return success;
}

Error_code List::remove(int position,List_entry &x)
{
    if (empty()) return overflow;
    if (position < 0 || position >= count) return error;
    x = entry[position];
    for (int i = position; i < count - 1; i++) entry[i] = entry [i + 1];
    count--;
    return success;
}

Error_code List::replace(int position,const List_entry &x)
{
    if (position < 0 || position >= count) return error;
    entry[position] = x;
    return success;
}

Error_code List::retrieve(int position,List_entry &x)const
{
    if (position < 0 || position >= count) return error;
    x = entry[position];
    return success;
}

Error_code Ordered_list::insert(const Record &data)
{
    int s = size();
    int position;
    for (position = 0; position < s; position++)
    {
        Record list_data;
        retrieve(position,list_data);
        if (data < list_data) break;
    }
    return List::insert(position,data);
}

Error_code Ordered_list::insert(int position,const Record &data)
{
    Record 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;
    }
    return List::insert(position,data);
}

Error_code Ordered_list::replace(int position,const Record &data)
{
    if (position < 0 || position >= count) return error;
    Record list_data;
    if (position > 0)
    {
        retrieve(position - 1,list_data);
        if (data < list_data) return fail;
    }
    if (position < size() - 1)
    {
        retrieve(position,list_data);
        if (data < list_data) return fail;
    }
    entry[position] = data;
    return success;
}

注意

  1. c++里,输入不知道长度,直接while(cin >> a >> b) 即可。
  2. 互相调用的class先把声明写在上边。
  3. 写了新的class后,如果有运算操作,一定要记得运算符重载!!!
  4. 解决Record == Key有两种方法:
    ①:

Key(const Record &r)
{
key = r.the_key();
}

string Record::the_key()const
{
return key;
}

②:

operator Key()
{
Key tmp(key);
return tmp;
}

两种方法分别搭配 bool operator = = (const Key &x,const Key &y);
第一种完成从RecordKey的自动转换,注意the_key函数是在Record里的,即两个class里都要有这个函数。
第二种调用Key()构造临时Key tmp,比较后,调用析构函数释放tmp。注意一定要return,否则会内存泄漏。

  1. List父类里的inserterror判断条件是position > count,而其他函数都是 position >= count。>写错会导致读不进去列表。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值