#include "stdafx.h"
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
/*** 异常类 ***/
class MyException{
private:
string mesg;
public:
MyException(const char* str) :mesg(const_cast<char*>(str)){ }
const string what(){ return mesg; }
};
/* 结点结构体 */
template <class T>
struct DNode{
T data;
DNode<T>* prior;
DNode<T>* next;
DNode(DNode<T>* ptr = NULL){
prior = next = ptr;
}
DNode(T item, DNode<T>* ptr = NULL){
prior = next = ptr;
data = item;
}
};
/************ 双向循环链表类 ************/
// 双向循环链表类
template <typename T>
class DoubleList{
private:
DNode<T>* head;
public:
DoubleList();
DoubleList(T item);
void AddNodeHead(T item); // 头插法,插入结点
void AddNodeTail(T item); // 尾插法,插入结点
void ShowAllNodes(); // 显示所有结点
void InsertNodestartfromHead(T, int); // 在指定位置插入结点,从头结点开始
void InsertNodestartfromTail(T, int); // 在指定位置插入结点,从尾结点开始
int GetLength(); // 获取链表长度
bool IsEmpty(); // 判断链表是否为空
DNode<T>* GetItemByIndex(int); // 通过下标获取元素的值
int GetIndexByItem(T); // 获取指定元素在链表中的位置
void ModifyNode(T, int); // 修改结点
static T GetInputItem(); // 获取输入元素
static int GetInputIndex(); // 获取输入下标
};
// 获取链表长度
template <typename T>
int DoubleList<T>::GetLength(){
int n = 0;
DNode<T>* list = head;
while (list->next != head){
list = list->next;
n++;
}
return n;
}
// 构造函数
template <typename T>
DoubleList<T>::DoubleList(){
head = new DNode<T>;
head->next = head;
head->prior = head;
}
// 构造函数,带参数
template <typename T>
DoubleList<T>::DoubleList(T item){
head = new DNode<T>;
head->next = head;
head->prior = head;
head->data = item;
}
// 头插法
template <typename T>
void DoubleList<T>::AddNodeHead(T item){
DNode<T>* newNode = new DNode<T>;
newNode->data = item;
newNode->next = head->next;
newNode->prior = head;
head->next->prior = newNode;
head->next = newNode;
}
// 尾插法
template <typename T>
void DoubleList<T>::AddNodeTail(T item){
DNode<T>* newNode = new DNode<T>;
newNode->data = item;
newNode->next = head;
newNode->prior = head->prior;
head->prior->next = newNode;
head->prior = newNode;
}
// 显示所有结点
template <typename T>
void DoubleList<T>::ShowAllNodes(){
DNode<T>* list = head;
while (list->next != head){
list = list->next;
cout << list->data << endl;
}
}
// 在指定位置插入结点,从头结点开始
template <typename T>
void DoubleList<T>::InsertNodestartfromHead(T item,int pos){
if (pos < 0 || pos > GetLength())
throw MyException("InsertNodestartfromHead, pos out of range");
int n = 0;
DNode<T>* list = head;
while (list->next != head && n < pos){
list = list->next;
n++;
}
DNode<T>* newNode = new DNode<T>;
newNode->data = item;
newNode->next = list->next;
newNode->prior = list;
list->next->prior = newNode;
list->next = newNode;
}
// 在指定位置插入结点,从尾结点开始
template <typename T>
void DoubleList<T>::InsertNodestartfromTail(T item, int pos){
if (pos < 0 || pos > GetLength())
throw MyException("InsertNodestartfromHead, pos out of range");
int n = 0;
DNode<T>* list = head;
while (list->prior != head && n < pos){
list = list->prior;
n++;
}
DNode<T>* newNode = new DNode<T>;
newNode->data = item;
newNode->next = list->next;
newNode->prior = list;
list->next->prior = newNode;
list->next = newNode;
}
// 判断链表是否为空
template <typename T>
bool DoubleList<T>::IsEmpty(){
if (head->next = head) return 1;
return 0;
}
// 通过下标获取元素的值
template <typename T>
DNode<T>* DoubleList<T>::GetItemByIndex(int index){
if (index <= 0 || index > GetLength())
throw MyException("GetItemByIndex, pos out of range");
int n = 0;
DNode<T>* list = head;
while (list->next != head && n < index){
list = list->next;
n++;
}
return list;
}
// 修改结点
template <typename T>
void DoubleList<T>::ModifyNode(T item, int pos){
if (pos <= 0 || pos > GetLength())
throw MyException("ModiyNode, pos out of range.");
int n = 0;
DNode<T>* list = head;
while (list->next != head && n < pos){
list = list->next;
n++;
}
list->data = item;
}
// 获取指定元素在链表中的位置
template <typename T>
int DoubleList<T>::GetIndexByItem(T item){
int n = 1;
DNode<T>* list = head;
while (list->next != head && n <= GetLength()){
list = list->next;
if (list->data == item)
return n;
n++;
}
return -1;
}
// 获取输入下标
template <typename T>
int DoubleList<T>::GetInputIndex(){
cout << "Input index:" << endl;
int n;
cin >> n;
fflush(stdin);
return n;
}
// 获取输入元素
template <typename T>
T DoubleList<T>::GetInputItem(){
cout << "Input item:" << endl;
T data;
cin >> data;
fflush(stdin);
return data;
}
/*************** 图书类 ***************/
// 图书类
class Book{
private:
double price;
char *bookName;
int num;
public:
Book(const char *name="", double price=0.0, int num=0){
bookName = new char[32]{ 0 };
strcpy(bookName, name);
this->price = price;
this->num = num;
}
const char* getName(){ return bookName; }
const int getNum(){ return num; }
const double getPrice(){ return price; }
void setName(char *name){ strcpy(this->bookName,name); }
void setPrice(double price){ this->price = price; }
void setNum(int num){ this->num = num; }
friend ostream& operator<<(ostream &out, Book& book);
friend istream& operator>>(istream &in, Book& book);
bool operator==(const Book& book);
};
// 输出运算符重载
ostream& operator<<(ostream& out, Book &book){
out << "《" << setiosflags(ios::right) << book.getName() << "》\t";
out << book.getPrice() << "$\t" << book.getNum() << endl;
return out;
}
// 输入运算符重载
istream& operator>>(istream& in, Book &book){
cout << "book name:";
in >> book.bookName;
cout << "book num:";
in >> book.num;
cout << "book price:";
in >> book.price;
return in;
}
// ==运算符重载
bool Book::operator==(const Book &book){
if (strcmp(this->bookName, book.bookName) == 0) return 1;
return 0;
}
/********* 其他函数 **********/
// 菜单
int menu(){
cout << "\t 操作选项" << endl;
cout << "\t1.在开头插入图书信息 2.在结尾插入图书信息" << endl;
cout << "\t3.显示所有图书信息 4.插入图书,从头起始" << endl;
cout << "\t5.插入图书,从末尾起始 6.获取链表长度" << endl;
cout << "\t7.通过下标获取结点元素 8.获取图书在链表中的位置" << endl;
cout << "\t9.修改结点 0.退出" << endl;
cout << "SELECT:";
string sel;
cin >> sel;
return atoi(sel.c_str());
}
int main(int argc, char *argv[]){
DoubleList<Book> books(Book("Index",0,0));
books.AddNodeHead(Book("C++ Pirmer Plus",78.5,1000));
books.AddNodeHead(Book("C Pirmer Plus", 65.5, 1001));
books.AddNodeHead(Book("C# Pirmer Plus", 68.5, 1002));
books.AddNodeHead(Book("Linux", 78.5, 1003));
while (true){
try{
switch (menu()){
case 0:
system("cls");
cout << "Bey Bey!" << endl;
return 0;
case 1:books.AddNodeHead(DoubleList<Book>::GetInputItem()); break;
case 2:books.AddNodeTail(DoubleList<Book>::GetInputItem()); break;
case 3:books.ShowAllNodes(); break;
case 4:books.InsertNodestartfromHead(DoubleList<Book>::GetInputItem(), DoubleList<Book>::GetInputIndex()); break;
case 5:books.InsertNodestartfromTail(DoubleList<Book>::GetInputItem(), DoubleList<Book>::GetInputIndex()); break;
case 6:cout << "length = " << books.GetLength() << endl; break;
case 7:cout << books.GetItemByIndex(DoubleList<Book>::GetInputIndex())->data; break;
case 8:cout << "index = " << books.GetIndexByItem(DoubleList<Book>::GetInputItem())<< endl; break;
case 9:books.ModifyNode(DoubleList<Book>::GetInputItem(),DoubleList<Book>::GetInputIndex()); break;
}
}
catch (MyException ex){
cout << ex.what() << endl;
}
}
return 0;
}
双向循环链表-模板-自定义类型
最新推荐文章于 2022-02-24 18:09:08 发布