符号表
在了解查找之前,首先我们要知道符号表,符号表有时被称为字典,也就是类似于单词的参考书。有时也被称为索引,即书本最后将术语按字母顺序列出以方便查找的那部分。
符号表主要分为键和值,键就是查找目录中的关键字,而值目录所指向的信息。
定义:符号表是一种存储键值对的数据结构。支持两种操作:
插入(put),即将一组新的键值对存入表中;
查找(get),即根据给定的键得到相应的值。
符号表规则:
1.每个键只对应一个值(表中不允许存在重复的键);
2.当用例代码向表中存入的键值对和表中已有的键冲突时,新的值会代替旧的值;
3.键不能为空;
4.值不能为空。
例外情况:
当一个方法需要返回一个键但表中没有合适的键时,我们约定抛出一个异常,书中约定的方式为返回NULL,但是在c++中常用类型函数返回NULL是不成立的,所以我在这个地方统一将“No key”作为异常抛出。
顺序查找:
简单的来说,顺序查找就是直接对符号表进行遍历,查找到相同的键(key)时,后返回值(data),如果没有便返回“No key”。
符号表API(基于无序链表):
class ST{ | |
ST() | 创建符号表 |
void put(string key,string item) | 将键值对插入表中 |
void get(string key) | 获取key对应的值 |
void delete_1(string key) | 删除key对应的键值对 |
bool Empty() | 判断表是否为空 |
int size() | 表中键值对的数量 |
vector<string> keys() | 键的集合 |
代码:
class Node
{
friend class ST;
string key;
string data;
Node* next;
public:
Node(string key, string item, Node* next) :
key(key), data(item),next(next){}
};
class ST
{
private:
Node* first = NULL;
public:
void put(string key, string item);//插入
string get(string key);//顺序查找
void delete_1(string key);//删除
bool Empty(){ return first ? 0 : 1; }
int size();//长度
queue<string> keys();//键的集合
};
void ST::put(string key, string item)//头插法
{
for (Node* x = first; x; x = x->next)
if (key == x->key)
{
x->data = item;
return;
}
first = new Node(key, item, first);
}
string ST::get(string key)
{
for (Node* x = first; x; x = x->next)
if (key == x->key)return x->data;
return "No key";
}
void ST::delete_1(string key)
{
if (first->key == key)
{
Node* x = first;
first = x->next;
delete x;
return;
}
for (Node* x = first; x->next;x=x->next)
if (key == x->next->key)
{
Node* t = x->next;
x->next = t->next;
delete(t);
return;
}
}
int ST::size()
{
int n = 0;
for (Node* x = first; x; x = x->next)
n++;
return n;
}
queue<string> ST::keys()
{
queue<string> a;
for (Node* x = first; x; x = x->next)
a.push(x->key);
return a;
}
测试用例:
int main()
{
ST p;
string key,item;
int m;
queue<string> a;
cout << "**********************************" << endl;
cout << "0.查看菜单. 1.插入." << endl;
cout << "2.查找. 3.删除." << endl;
cout << "4.链表是否为空. 5.链表长." << endl;
cout << "6.键的集合." << endl;
cout << "**********************************" << endl;
while (cin >> m)
{
switch (m)
{
case 0:
cout << "**********************************" << endl;
cout << "0.查看菜单. 1.插入." << endl;
cout << "2.查找. 3.删除." << endl;
cout << "4.链表是否为空. 5.链表长." << endl;
cout << "6.键的集合." << endl;
cout << "**********************************" << endl;
break;
case 1:
cout << "输入元素键与值:" << endl;
cin >> key >> item;
p.put(key, item);
break;
case 2:
cout << "输入查找元素的键:" << endl;
cin >> key;
cout << p.get(key) << endl;
break;
case 3:
cout << "输入删除元素的键:" << endl;
cin >> key;
p.delete_1(key);
break;
case 4:
p.Empty() == 1 ? cout << "表为空。" << endl :
cout << "表不为空" << endl;
break;
case 5:
cout << "输出表长:" << p.size() << endl;
break;
case 6:
cout << "输入表键的集合:" << endl;
a = p.keys();
while (!a.empty())
{
cout << a.front() << " ";
a.pop();
}
cout << endl;
break;
}
}
system("pause");
return 0;
}