#pragma once #include "SHTable.h" #include "SHQuene.h" template class SHArray { public: SHArray(long size = 0); SHArray(const SHArray& array); SHArray(const SHTable& table); SHArray& operator = (const SHArray& array); virtual ~SHArray(); //space void Realloc(long newLength,bool bCopy = true); //attribute bool IsValidIndex(long index) const; bool IsEmpty() const; long GetLength() const; long GetLastIndex() const; bool operator == (const SHArray&array) const; bool operator != (const SHArray&array) const; //random visit T& operator[](long index); const T& GetAt(long index) const; void SetAt(long index,const T&t); T* GetBuffer() const; //insert/delete void Insert(long index,const T&t); void InsertHead(const T&t); long AddTail(const T&t); void Del(long index); void DelFirst(); void DelTail(); void Clear(); //search long Find(const T&t,long from = 0,long to = -1) const; long Find(const T&t,SHQuene&quene,long from = 0,long to = -1) const; long FindOrAddTail(const T&t); void FindOrInsertHead(const T&t); long FindAndDel(const T&t); //二分查找,适用于升序表 long BFind(const T&t,long from = 0,long to = -1) const; //operate void SetAll(const T&t); //稳定计数排序 void Arrange(bool bIncrease = true); void Arrange(int (*cmp)(const T&,const T&)); //倒序 void Reverse(long from = 0,long to = -1); protected: long length; T * pData; }; template SHArray::~SHArray() { if (pData != NULL) { delete[] pData; } } template bool SHArray::IsValidIndex(long index) const { return index >=0 && index < length; } template bool SHArray::IsEmpty() const { return length == 0; } template long SHArray::GetLength() const { return length; } template long SHArray::GetLastIndex() const { return length - 1; } template bool SHArray::operator != (const SHArray&array) const { return !((*this) == array); } template T& SHArray::operator[](long index) { return pData[index]; } template const T& SHArray::GetAt(long index) const { return pData[index]; } template void SHArray::SetAt(long index,const T&t) { pData[index] = t; } template T* SHArray::GetBuffer() const { return pData; } template void SHArray::InsertHead(const T&t) { Insert(0, t); } template long SHArray::AddTail(const T& t) { Insert(length, t); return GetLastIndex(); } template void SHArray::DelFirst() { Del(0); } template void SHArray::DelTail() { Del(length - 1); } template void SHArray::Clear() { if (pData != NULL) { delete[] pData; pData = NULL; length = 0; } } template long SHArray::BFind(const T& t, long from, long to) const { if (to < 0 || to >= GetLength()) { to = GetLastIndex(); } if (from > to) { return -1; } if (t < GetAt(from)) { return -1; } if (t > GetAt(to)) { return -1; } while(from <= to) { long mid = (from + to) / 2; const T& tCur = GetAt(mid); if (t > tCur) { from = mid + 1; } else if (t < tCur) { to = mid - 1; } else { return mid; } } return -1; } template SHArray::SHArray(long l) { if (l <= 0) { length = 0; pData = NULL; } else { length = l; pData = new T[l]; } } template SHArray::SHArray(const SHArray& array) : pData(NULL), length(0) { Realloc(array.GetLength()); for (long i = 0;i < length; i++) { pData[i] = array.GetAt(i); } } template SHArray& SHArray::operator = (const SHArray& array) { Realloc(array.GetLength()); for (long i = 0; i < length; i++) { pData[i] = array.GetAt(i); } return *this; } template SHArray::SHArray(const SHTable& table) : length(0), pData(NULL) { Realloc(table.GetLength()); long i = 0; for (const T* pCur = table.GetFirst(); pCur != NULL; pCur = table.GetNext(pCur), i++) { pData[i] = *pCur; } } template void SHArray::Realloc(long l,bool bCopy) { if (l != length) { if (l <= 0) { if (pData!=NULL) { delete[] pData; } length = 0; pData = NULL; } else { T* pTemp = pData; pData = new T[l]; if (bCopy) { if (l > length) for (long i = 0;i < length; i++) { pData[i] = pTemp[i]; } else { for (long i = 0; i < l; i++) { pData[i] = pTemp[i]; } } } length = l; if (pTemp != NULL) { delete[] pTemp; } } } } template void SHArray::SetAll(const T&t) { for (long i = 0; i < length; i++) { pData[i] = t; } } template bool SHArray::operator == (const SHArray& array) const { if (length != array.GetLength()) { return false; } for (long i = 0; i < length; i++) { if (pData[i] != array.GetAt(i)) { return false; } } return true; } template void SHArray::Insert(long index,const T& t) { T* pTemp = pData; length++; pData = new T[length]; for (long i = 0; i < length; i++) { if (i < index) { pData[i] = pTemp[i]; } else if ( i > index) { pData[i] = pTemp[i - 1]; } else { pData[i] = t; } } if ( pTemp != NULL) { delete[] pTemp; } } template void SHArray::Del(long index) { T* pTemp = pData; length--; if (length == 0) { pData = NULL; } else { pData = new T[length]; } for (long i = 0; i < length; i++) { if (i < index) { pData[i] = pTemp[i]; } else { pData[i] = pTemp[i + 1]; } } delete[] pTemp; } template long SHArray::FindAndDel(const T&t) { long count = 0; for (long i = 0;i < GetLength(); i++) { if (pData[i] == t) { Del(i); i--; count++; } } return count; } template long SHArray::Find(const T&t,long from,long to) const { if (to < 0 || to >= length) { to = length - 1; } for (long i = from; i <= to; i++) { if (pData[i] == t) { return i; } } return -1; } template long SHArray::Find(const T&t,SHQuene &quene,long from,long to) const { if (to < 0 || to >= length) { to = length-1; } for (long i = from; i <= to; i++) { if (pData[i] == t) { quene.EnQuene(i); } } return quene.GetLength(); } //稳定计数排序 template void SHArray::Arrange(bool bIncrease) { if (GetLength() < 2) { return; } long *count = new long[GetLength()]; long i; for (i = 0;i pData[j]) { count[i]++; count[j]--; } } for (i = 0;i < GetLength();i++) { if (count[i] != i) { long k,j; T temp1 = pData[i],temp2; k = count[i]; while(k != i) { temp2 = pData[k];//save pData[k] = temp1;//transport data temp1 = temp2; j = k; k = count[j];//save count[j] = j;//count ok } pData[i] = temp1; count[i] = i; } } } else { for (i = 0; i < GetLastIndex(); i++) { for (long j = i + 1; j < GetLength();j++) { if (pData[i] < pData[j]) { count[i]++; count[j]--; } } } for (i = 0;i < GetLength();i++) { if (count[i] != i) { long k,j; T temp1 = pData[i],temp2; k = count[i]; while(k != i) { temp2 = pData[k];//save pData[k] = temp1;//transport data temp1 = temp2; j = k; k = count[j];//save count[j] = j;//count ok } pData[i] = temp1; count[i] = i; } } } delete[] count; } //稳定计数排序 template void SHArray::Arrange(int (*cmp)(const T&,const T&)) { if (GetLength() < 2) { return; } long i; long *count = new long[GetLength()]; for (i = 0; i < GetLength(); i++) { count[i] = i; } for (i = 0; i < GetLastIndex(); i++) { for (long j = i + 1; j < GetLength(); j++) { if (cmp(pData[i], pData[j]) > 0) { count[i]++; count[j]--; } } } for (i = 0;i < GetLength(); i++) { if (count[i] != i) { long k,j; T temp1 = pData[i],temp2; k = count[i]; while(k != i) { temp2 = pData[k];//save pData[k] = temp1;//transport data temp1 = temp2; j = k; k = count[j];//save count[j] = j;//count ok } pData[i] = temp1; count[i] = i; } } delete[] count; } template void SHArray::Reverse(long start,long end) { if (end == -1) { end = length - 1; } if (!IsValidIndex(start) || !IsValidIndex(end)) { return; } long halfLength = (end - start + 1) / 2; for (long i = 0; i < halfLength; i++) { T temp = pData[i + start]; long j = end - i; pData[i + start] = pData[j]; pData[j] = temp; } } template long SHArray::FindOrAddTail(const T&t) { long pos = Find(t); return pos != -1 ? pos : AddTail(t); } template void SHArray::FindOrInsertHead(const T&t) { long pos = Find(t); if (pos == -1) { InsertHead(t); } }