Circular List双向链表
主函数
#include "DblList.h"
#include <fstream>
#include <cassert>
using namespace std;
int main()
{
DblList<int> list(-1);
ifstream fin("list.txt");
assert(fin);
fin >> list;
cout << "The initial list in the file is:\n" << list << endl;
cout << "========================================\n";
int i, elem, d;
cout << "Test the Insert, Remove and Search function:\n";
cout << "Each test will terminate by an invaid input.";
cout << "\n----------------------------------------\n";
cout << "1. Test the Insert(int i, T &elem, int d):\n";
while (1){
cout << "Input the index i and data elem and the direction(0/1) to insert: ";
cin >> i >> elem >> d;
if (!cin){
cin.clear();
cin.ignore(100,'\n');
break;
}
if (i < 0) break;
if (list.Insert(i, elem, d)) cout << "Insert successful!\n";
else cout << "Insert failed!\n";
}
cout << "\nAfter inserted\n" << list << endl;
cout << "----------------------------------------\n";
cout << "2. Test the Remove(int i, T &elem, int d):\n";
while (1){
cout << "Input the index i and the direction(0/1) in which you want to remove: ";
cin >> i >> d;
if (!cin){
cin.clear();
cin.ignore(100,'\n');
break;
}
if (i < 0) break;
if (list.Remove(i, elem, d)) cout << "The element " << elem << " has been removed!\n";
else cout << "Remove failed!\n";
}
cout << "\nAfter removed\n" << list << endl;
cout << "----------------------------------------\n";
cout << "3. Test the Search(T &elem):\n";
while (1){
cout << "Input the element and the search direction(1/0) you want to search: ";
cin >> elem >> d;
if (!cin){
cin.clear();
cin.ignore(100,'\n');
break;
}
if (elem < 0) break;
DblNode<int> *p = list.Search(elem, d);
if (p) cout << "The element " << elem << " is in the list.\n";
else cout << "The element is not exist!\n";
}
cout << "\n----------------------------------------\n";
cout << "End test!" << endl;
return 0;
}
双向结点类定义
template <typename T>struct DblNode{
T data;
DblNode<T> *rLink, *lLink; //前后指针
DblNode(DblNode<T> *l = NULL, DblNode<T> *r = NULL){
lLink = l;
rLink = r;
}
DblNode(T value, DblNode<T> *l = NULL, DblNode<T> *r = NULL){
data = value;
lLink = l;
rLink = r;
}
};
双向链表类定义
template <typename T>class DblList{
public:
DblList(T uniqueVal){
first = new DblNode<T>(uniqueVal);
assert(first);
first->rLink = first->lLink = first;
}
~DblList() {
makeEmpty();
delete first;
}
void makeEmpty(){
DblNode<T> *q;
while (first->rLink != first){ //后向指针是rLink
q = first->rLink;
first->rLink = q->rLink;
delete q;
}
first->lLink=first; //最后只剩下头结点
}
DblNode<T> *getFirst()const{
return first;
}
DblNode<T> *Search(const T &x, int d = 1);
DblNode<T> *Locate(int i, int d = 1);
bool Insert(int i, const T &x, int d = 1);
bool Remove(int i, T &x, int d);
bool IsEmpty(){
return first->rlink == first; //当后向指针指向首节点时
}
bool IsFull(){
return false;
}
friend istream& operator >> (istream& in, DblList<T> &dbl){
int i = 0;
T data;
dbl.makeEmpty(); //在输入开始时缓存区清空?
while (!in.eof()){
in >> data;
dbl.Insert(i, data, 1); //调用Insert函数,按从头输入的方式输入
i++;
}
return in;
}
friend ostream & operator << (ostream &out, DblList <T> &dbl) {
DblNode <T> *p= dbl.first->rLink;
while ( p!=dbl.first ){
out << p->data <<'\t';
p = p->rLink;
}
cout << endl;
return out;
}
private:
DblNode<T> *first;
};
提问1:assert什么时候用?
assert是用来避免显而易见的错误的,而不是处理异常的。错误和异常是不一样的,错误是不应该出现的,异常是不可避免的。c语言异常可以通过条件判断来处理,其它语言有各自的异常处理机制。
一个非常简单的使用assert的规律就是,在方法或者函数的最开始使用,如果在方法的中间使用则需要慎重考虑是否是应该的。方法的最开始还没开始一个功能过程,在一个功能过程执行中出现的问题几乎都是异常。
提问2:为什么在输入函数定义operator>>
中需要dbl.makeEmpty()
?
Locate和Search函数
template <typename T>DblNode<T> *DblList<T>::Locate(int i, int d){
if (first->rLink == first || i==0){
return first;
}
DblNode<T> *current = (d == 0)?first->lLink:first->rLink;
while (current != first && --i > 0){
current = (d == 0)?current->lLink:current->rLink;
}
return (current == first)?NULL:current;
}
template <typename T>DblNode<T> *DblList<T>::Search(const T &x, int d){
DblNode<T> *current = (d == 0)?first->lLink:first->rLink;
while (current != first && current->data != x) {
current = (d == 0)?current->lLink:current->rLink;
}
return (current == first)?NULL:current;
}
Insert函数
template <typename T>bool DblList<T>::Insert(int i, const T &x, int d){
DblNode<T> *current = Locate(i, d);
if (current == NULL){
return false;
}
DblNode<T> *newNode = new DblNode<T>(x);
assert(newNode);
if (d == 0){
newNode->lLink = current->lLink;
current->lLink = newNode;
newNode->lLink->rLink = newNode;
newNode->rLink = current;
}
else{
newNode->rLink = current->rLink;
current->rLink = newNode;
newNode->rLink->lLink = newNode;
newNode->lLink = current;
}
return true;
}
Remove函数
template <typename T>
bool DblList<T>::Remove(int i, T &x, int d){
DblNode<T> *current = Locate(i, d);
if (current == NULL)
{
return false;
}
current->rLink->lLink = current->lLink;
current->lLink->rLink = current->rLink;
x = current->data;
delete current;
return true;
}
整一个头文件:
#ifndef DBLLIST_H
#define DBLLIST_H
#include <iostream>
#include <cassert>
using namespace std;
template <typename T>struct DblNode{
T data;
DblNode<T> *rLink, *lLink;
DblNode(DblNode<T> *l = NULL, DblNode<T> *r = NULL){
lLink = l;
rLink = r;
}
DblNode(T value, DblNode<T> *l = NULL, DblNode<T> *r = NULL){
data = value;
lLink = l;
rLink = r;
}
};
template <typename T>class DblList{
public:
DblList(T uniqueVal){
first = new DblNode<T>(uniqueVal);
assert(first);
first->rLink = first->lLink = first;
}
~DblList() {//Îö¹¹º¯Êý²»¿ÉÉÙ
makeEmpty();
delete first;//ÊͷŸ½¼ÓÍ·½áµã
}
void makeEmpty(){//Ìí
DblNode<T> *q;
while (first->rLink != first){//½öÓ฽¼ÓÍ·½áµã
q = first->rLink;//ÏȲ»¹Ü×óÖ¸Õë
first->rLink = q->rLink;
delete q;
}
first->lLink=first;//×îºó´¦Àí
}
DblNode<T> *getFirst()const{
return first;
}
DblNode<T> *Search(const T &x, int d = 1);
DblNode<T> *Locate(int i, int d = 1);
//ÔÚÁ´±íÖж¨Î»ÐòºÅΪi(¡Ý0)µÄ½áµã, d=0°´Ç°Çý·½
//Ïò,d¡Ù0°´ºó¼Ì·½Ïò
bool Insert(int i, const T &x, int d = 1);
//ÔÚµÚi¸ö½áµãºó²åÈëÒ»¸ö°üº¬ÓÐÖµxµÄнáµã,d=0
//°´Ç°Çý·½Ïò,d¡Ù0°´ºó¼Ì·½Ïò
bool Remove(int i, T &x, int d);
bool IsEmpty(){
return first->rlink == first;
}
bool IsFull(){
return false;
}
friend istream& operator >> (istream& in, DblList<T> &dbl){//¸Ä
int i = 0;
T data;
dbl.makeEmpty();
while (!in.eof()){
in >> data;
dbl.Insert(i, data, 1);
i++;
}
return in;
}
friend ostream & operator << (ostream &out, DblList <T> &dbl) {
DblNode <T> *p= dbl.first->rLink;
while ( p!=dbl.first ){
out << p->data <<'\t';
p = p->rLink;
}
cout << endl;
return out;
}
private:
DblNode<T> *first;
};
template <typename T>DblNode<T> *DblList<T>::Locate(int i, int d){//d==1ÏòÓÒ
if (first->rLink == first || i==0){
return first;
}
DblNode<T> *current = (d == 0)?first->lLink:first->rLink;
while (current != first && --i > 0){
current = (d == 0)?current->lLink:current->rLink;
}
return (current == first)?NULL:current;
}
template <typename T>DblNode<T> *DblList<T>::Search(const T &x, int d){//´Ëº¯ÊýÏò×óÏòÓÒÎÞËùν
DblNode<T> *current = (d == 0)?first->lLink:first->rLink;
while (current != first && current->data != x) {
current = (d == 0)?current->lLink:current->rLink;
}
return (current == first)?NULL:current;
}
template <typename T>bool DblList<T>::Insert(int i, const T &x, int d){
//½¨Á¢Ò»¸ö°üº¬ÓÐÖµxµÄнáµã, ²¢½«Æä°´ d Ö¸¶¨µÄ·½Ïò²åÈëµ½µÚi¸ö½áµãÖ®ºó¡£
DblNode<T> *current = Locate(i, d);
if (current == NULL){
return false; //²åÈëʧ°Ü
}
DblNode<T> *newNode = new DblNode<T>(x);
assert(newNode);
if (d == 0){ //Ç°Çý·½Ïò:²åÔÚµÚi¸ö½áµã×ó²à
newNode->lLink = current->lLink;
current->lLink = newNode;
newNode->lLink->rLink = newNode;
newNode->rLink = current;
}
else{ //ºó¼Ì·½Ïò:²åÔÚµÚi¸ö½áµãºóÃæ
newNode->rLink = current->rLink;
current->rLink = newNode;
newNode->rLink->lLink = newNode;
newNode->lLink = current;
}
return true;
}
template <typename T>
bool DblList<T>::Remove(int i, T &x, int d){
//ÔÚË«ÏòÑ»·Á´±íÖа´dËùÖ¸·½Ïòɾ³ýµÚi¸ö½áµã¡£
DblNode<T> *current = Locate(i, d);
if (current == NULL)
{
return false; //ɾ³ýʧ°Ü
}
current->rLink->lLink = current->lLink;
current->lLink->rLink = current->rLink;
x = current->data;
delete current;
return true;
}
#endif