实验指导
1. 基于双链表实现线性表的典型操作(判空、插入、删除、查找、修改、普通构造、拷贝构造、赋值运算符重载、析构),编写简单程序使用该线性表,测试和调试程序。
链表中每个节点包含 2 个指针域,其中一个指向去向(next)节点、另一个指向回向节点(back)。采用模板完成节点的定义。
2. 基于双链表实现线性表的应用:活期储蓄帐目管理系统,测试和调试程序。这一步,主要是编写银行活期储蓄帐目管理系统,要求如下。
使用 C++语言,设计数据类型与数据存储结构,编写一个命令行菜单驱动的活期储蓄帐目管理系统,实现储户开户、销户、存入、支出、查询等功能。
储户开户。开户时需要以下信息:储户姓名、账号(假设为 6 位数字)、身份证号(假设为 18 位数字)、联系电话、账号余额。注意设置开户时的账户余额为 0。
储户销户。找到该储户的账户信息后,将其删除。
储户存款。找到该储户的账户信息后,修改该账户余额(原余额+存入金额),存入金额须大于 0。成功后记录此次存取款交易明细(交易类型:存款;交易时间:年月日时分秒;交易金额)
储户取款。找到该储户的账户信息后,修改该账户余额(原余额-取出金额),取出金额须大于 0 且不超过原余额。成功后记录此次存取款交易明细(交易类型:取款;交易时间:年月日时分秒;交易金额)
查询余额。找到该储户的账户信息后,显示该账户信息(包含余额)。查询存取款交易明细。找到该储户的账户信息后,显示该账户下的历次存取款交易记录信息(交易类型:存款或取款;交易时间:年月日时分秒;交易金额)。
永久性存储。所有账户及其存取款交易明细能够在程序结束时存至文件,程序运行时从文件读入。
注意源程序风格应符合基本要求。缩进正确;须有适当的注释。
完整代码
#pragma once
#include <iostream>
using namespace std;
#include <string>
/*********************************
六位数账号的生成
**********************************/
string id_Increase()
/*
从"000001"开始生成流水号,返回类型为string
*/
{
char buffer[80];
string num_tmp, id;
static string a = "";
static int uid_number = 0;
uid_number += 1;
sprintf(buffer, "%06d", uid_number);
cout << buffer << endl;
id = a + buffer;
return id;
}
#pragma once
#include<iostream>
using namespace std;
/*********************************
线性表的双链表实现
**********************************/
//枚举
enum Error_code {
success, fail, range, underflow, overflow, fatal,
not_present, duplicate_error, entry_inserted, entry_found,
internal_error
};
//每一个节点的结构体
template <class Node_entry> struct Node {
//data members
Node_entry entry; //当前节点的数据
Node<Node_entry>* next; //当前节点的next指针,指向它的后继
Node<Node_entry>* back; //当前节点的back指针,指向它的前驱
//constructors
Node(); //无参构造
Node(Node_entry, Node<Node_entry>* link_back = NULL, Node<Node_entry>
* link_next = NULL); //有参构造
};
//线性表类
template <class List_entry> 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); //增加
~List(); //析构
List(const List<List_entry>& copy); //拷贝构造函数
void operator =(const List<List_entry>& copy); //赋值运算符重载
protected:
//Data members for the doubly-linked list implementation follow:
int count; //线性表中的节点个数
mutable int current_position; //current指针的位置
mutable Node<List_entry>* current;
//The auxiliary function to locate list positions follows:
void set_position(int position) const; //定位
};
template <class Node_entry>Node<Node_entry>::Node()
{
back = next = NULL;
}
template <class Node_entry>Node<Node_entry>::Node(Node_entry data, Node<Node_entry>* link_back, Node<Node_entry>* link_next)
{
entry = data;
back = link_back;
next = link_next;
}
template <class List_entry>List<List_entry>::List()
{
count = 0;
current = NULL;
current_position = -1;
}
template <class List_entry>int List<List_entry>::size() const
{
return count;
}
template <class List_entry>bool List<List_entry>::full() const
{
return false;
}
template <class List_entry>bool List<List_entry>::empty() const
{
return current == NULL;
}
template <class List_entry>void List<List_entry>::clear()
{
Node<List_entry>* p, * q;
if (current == NULL)
return;
//删除空间
for (p = current->back; p; p = q)
{
q = p->back;
delete p;
}
for (p = current; p; p = q)
{
q = p->next;
delete p;
}
count = 0;
current = NULL;
current_position = -1;
}
template <class List_entry>void List<List_