实现一个简单的有序列表,保证插入新数据时,列表依然有序,并且带有查找,删除功能。
查找功能使用了如下不同的方法:
- 顺序查找
- 二分查找(使用了两种不同的二分查找写法)
#ifndef _ORDERLIST_
#define _ORDERLIST_
#include <iostream>
#include <stdexcept>
using namespace std;
template <typename T,int findTag>
class OrderList
{
public:
OrderList(int maxSize=100) : _size(0),_maxSize(maxSize)
{
_values = new T[_maxSize];
}
~OrderList() { delete [] _values; }
OrderList(const OrderList& rhs) : _values(NULL)
{
operator=(rhs);
}
const OrderList& operator=(const OrderList& rhs)
{
if( this != &rhs )
{
delete [] _values;
_size = rhs._size;
_maxSize = rhs._maxSize;
_values = new T[_maxSize];
for(int i=0;i<_size;++i)
_values[i] = rhs._values[i];
}
return *this;
}
int Insert(const T& data)
{
if(IsFull())
throw logic_error("List is full");
for(int i=_size-1;i>=0;--i)
{
if(data < _values[i])
{
_values[i+1] = _values[i];
}
else
{
_values[i+1] = data;
++_size;
return i+1;
}
}
_values[0] = data;
++_size;
return 0;
}
int Find(const T& data)
{
switch(findTag)
{
case 0:
return SequentialFind(_values,_size,data);
case 1:
return BinaryFind1(_values,_size,data);
case 2:
return BinaryFind2(_values,_size,data);
default:
return BinaryFind1(_values,_size,data);
}
}
bool Remove(const T& data)
{
int index = Find(data);
if( -1 == index)
return false;
else
{
for(int i=index; i<_size-1; ++i)
_values[i] = _values[i+1];
--_size;
return true;
}
}
bool IsFull()
{
return _size == _maxSize;
}
bool IsEmpty()
{
return _size == 0;
}
void Print()
{
cout << "Size=" << _size << endl;
for(int i=0;i<_size;++i)
cout << _values[i] << ",";
cout << endl;
}
private:
static int SequentialFind(T* start,int size,const T& key)
{
//cout << "SequentialFind" << endl;
for(int i=0;i<size;++i)
{
if( key == start[i] )
return i;
}
return -1;
}
static int BinaryFind1(T* start,int size,const T& key)
{
//cout << "BinaryFind1" << endl;
int bottom = 0;
int top = size-1;
int mid = 0;
while(bottom < top)
{
mid = (bottom + top) / 2;
if( start[mid] < key )
{
bottom = mid + 1;
}
else
{
top = mid;
}
}
if(bottom > top)
return -1;
else
{
// bottom == top
if(start[bottom] == key)
return bottom;
else
return -1;
}
}
static int BinaryFind2(T* start, int size, const T& key)
{
//cout << "BinaryFind2" << endl;
int bottom = 0;
int top = size-1;
int mid = 0;
while(bottom <= top)
{
mid = (bottom + top) / 2;
if( start[mid] == key )
return mid;
if( start[mid] < key)
bottom = mid + 1;
else
top = mid - 1;
}
return -1;
}
private:
int _size;
int _maxSize;
T* _values;
};
#endif
void OrderListTest1()
{
OrderList<int,1> o;
o.Print();
o.Insert(5);
o.Insert(6);
o.Insert(4);
o.Insert(9);
o.Insert(8);
o.Insert(5);
o.Insert(9);
o.Insert(4);
o.Print();
cout << "Remove 1 is " << o.Remove(1) << endl;
o.Print();
cout << "Remove 8 is " << o.Remove(8) << endl;
o.Print();
cout << "Remove 9 is " << o.Remove(9) << endl;
o.Print();
cout << "Remove 4 is " << o.Remove(4) << endl;
o.Print();
o.Insert(7);
o.Print();
cout << "Remove 9 is " << o.Remove(9) << endl;
o.Print();
cout << "Remove 4 is " << o.Remove(4) << endl;
o.Print();
}
void OrderListTest2()
{
int maxSize = 10;
OrderList<int,0> sequentialFind = OrderList<int,0>(maxSize);
OrderList<int,1> binaryFind1 = OrderList<int,1>(maxSize);
OrderList<int,2> binaryfind2 = OrderList<int,2>(maxSize);
for(int i=0;i<maxSize;++i)
{
sequentialFind.Insert(2*i + 1);
binaryFind1.Insert(2*i + 1);
binaryfind2.Insert(2*i + 1);
}
sequentialFind.Print();
cout << "Find 5 at " << sequentialFind.Find(5) << endl;
cout << "Find 8 at " << sequentialFind.Find(8) << endl;
binaryFind1.Print();
cout << "Find 5 at " << binaryFind1.Find(5) << endl;
cout << "Find 8 at " << binaryFind1.Find(8) << endl;
binaryfind2.Print();
cout << "Find 5 at " << binaryfind2.Find(5) << endl;
cout << "Find 8 at " << binaryfind2.Find(8) << endl;
}